xref: /netbsd-src/external/bsd/am-utils/dist/amd/sun_map_parse.y (revision 4da6d876cd9670a0f55b4857d574006fa142db45)
1 /*	$NetBSD: sun_map_parse.y,v 1.4 2015/01/17 17:46:31 christos Exp $	*/
2 
3 %{
4 /*
5  * Copyright (c) 1997-2014 Erez Zadok
6  * Copyright (c) 2005 Daniel P. Ottavio
7  * Copyright (c) 1990 Jan-Simon Pendry
8  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
9  * Copyright (c) 1990 The Regents of the University of California.
10  * All rights reserved.
11  *
12  * This code is derived from software contributed to Berkeley by
13  * Jan-Simon Pendry at Imperial College, London.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  * 3. Neither the name of the University nor the names of its contributors
24  *    may be used to endorse or promote products derived from this software
25  *    without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  *
39  *
40  * File: am-utils/amd/sun_map_parse.y
41  *
42  */
43 
44 #ifdef HAVE_CONFIG_H
45 # include <config.h>
46 #endif /* HAVE_CONFIG_H */
47 #include <am_defs.h>
48 #include <amd.h>
49 #include <sun_map.h>
50 
51 
52 #define SUN_FSTYPE_STR  "fstype="
53 
54 
55 extern int sun_map_lex(void);
56 extern int sun_map_error(const char *);
57 extern void sun_map_tok_setbuff(const char *);
58 extern int sun_map_parse(void);
59 
60 struct sun_entry *sun_map_parse_read(const char *);
61 
62 static struct sun_list *sun_entry_list = NULL;
63 static struct sun_list *sun_opt_list = NULL;
64 static struct sun_list *sun_host_list = NULL;
65 static struct sun_list *sun_location_list = NULL;
66 static struct sun_list *mountpt_list = NULL;
67 static char *tmpFsType = NULL;
68 
69 
70 /*
71  * Each get* function returns a pointer to the corresponding global
72  * list structure.  If the structure is NULL than a new instance is
73  * returned.
74  */
75 static struct sun_list *get_sun_opt_list(void);
76 static struct sun_list *get_sun_host_list(void);
77 static struct sun_list *get_sun_location_list(void);
78 static struct sun_list *get_mountpt_list(void);
79 static struct sun_list *get_sun_entry_list(void);
80 
81 %}
82 
83 %union {
84   char strval[2048];
85 }
86 
87 %token NEWLINE COMMENT WSPACE
88 %token <strval> WORD
89 
90 %%
91 
92 amap : file
93      ;
94 
95 file : new_lines entries
96      | entries
97      ;
98 
99 entries : entry
100         | entry new_lines
101         | entry new_lines entries
102         ;
103 
104 new_lines : NEWLINE
105           | NEWLINE new_lines
106           ;
107 
108 entry : locations {
109 
110   struct sun_list *list;
111   struct sun_entry *entry;
112 
113   /* allocate an entry */
114   entry = CALLOC(struct sun_entry);
115 
116   /*
117    * Assign the global location list to this entry and reset the
118    * global pointer.  Reseting the global pointer will create a new
119    * list instance next time get_sun_location_list() is called.
120    */
121   list = get_sun_location_list();
122   entry->location_list = (struct sun_location *)list->first;
123   sun_location_list = NULL;
124 
125    /* Add this entry to the entry list. */
126   sun_list_add(get_sun_entry_list(), (qelem *)entry);
127 }
128 
129 | '-' options WSPACE locations {
130 
131   struct sun_list *list;
132   struct sun_entry *entry;
133 
134   entry = CALLOC(struct sun_entry);
135 
136   /* An fstype may have been defined in the 'options'. */
137   if (tmpFsType != NULL) {
138     entry->fstype = tmpFsType;
139     tmpFsType = NULL;
140   }
141 
142   /*
143    * Assign the global location list to this entry and reset the
144    * global pointer.  Reseting the global pointer will create a new
145    * list instance next time get_sun_location_list() is called.
146    */
147   list = get_sun_location_list();
148   entry->location_list = (struct sun_location *)list->first;
149   sun_location_list = NULL;
150 
151   /*
152    * Assign the global opt list to this entry and reset the global
153    * pointer.  Reseting the global pointer will create a new list
154    * instance next time get_sun_opt_list() is called.
155    */
156   list = get_sun_opt_list();
157   entry->opt_list = (struct sun_opt *)list->first;
158   sun_opt_list = NULL;
159 
160   /* Add this entry to the entry list. */
161   sun_list_add(get_sun_entry_list(), (qelem *)entry);
162 }
163 
164 | mountpoints {
165 
166   struct sun_list *list;
167   struct sun_entry *entry;
168 
169   /* allocate an entry */
170   entry = CALLOC(struct sun_entry);
171 
172   /*
173    * Assign the global mountpt list to this entry and reset the global
174    * pointer.  Reseting the global pointer will create a new list
175    * instance next time get_mountpt_list() is called.
176    */
177   list = get_mountpt_list();
178   entry->mountpt_list = (struct sun_mountpt *)list->first;
179   mountpt_list = NULL;
180 
181   /* Add this entry to the entry list. */
182   sun_list_add(get_sun_entry_list(), (qelem *)entry);
183 }
184 
185 | '-' options WSPACE mountpoints {
186 
187   struct sun_list *list;
188   struct sun_entry *entry;
189 
190   /* allocate an entry */
191   entry = CALLOC(struct sun_entry);
192 
193   /* An fstype may have been defined in the 'options'. */
194   if (tmpFsType != NULL) {
195     entry->fstype = tmpFsType;
196     tmpFsType = NULL;
197   }
198 
199   /*
200    * Assign the global mountpt list to this entry and reset the global
201    * pointer.  Reseting the global pointer will create a new list
202    * instance next time get_mountpt_list() is called.
203    */
204   list = get_mountpt_list();
205   entry->mountpt_list = (struct sun_mountpt *)list->first;
206   mountpt_list = NULL;
207 
208   /*
209    * Assign the global opt list to this entry and reset the global
210    * pointer.  Reseting the global pointer will create a new list
211    * instance next time get_sun_opt_list() is called.
212    */
213   list = get_sun_opt_list();
214   entry->opt_list = (struct sun_opt *)list->first;
215   sun_opt_list = NULL;
216 
217   /* Add this entry to the entry list. */
218   sun_list_add(get_sun_entry_list(), (qelem *)entry);
219 }
220 ;
221 
222 mountpoints : mountpoint
223             | mountpoint WSPACE mountpoints
224             ;
225 
226 mountpoint : WORD WSPACE location {
227 
228   struct sun_list *list;
229   struct sun_mountpt *mountpt;
230 
231   /* allocate a mountpt */
232   mountpt = CALLOC(struct sun_mountpt);
233 
234   /*
235    * Assign the global loaction list to this entry and reset the
236    * global pointer.  Reseting the global pointer will create a new
237    * list instance next time get_sun_location_list() is called.
238    */
239   list = get_sun_location_list();
240   mountpt->location_list = (struct sun_location *)list->first;
241   sun_location_list = NULL;
242 
243   mountpt->path = xstrdup($1);
244 
245   /* Add this mountpt to the mountpt list. */
246   sun_list_add(get_mountpt_list(), (qelem *)mountpt);
247 }
248 
249 | WORD WSPACE '-' options WSPACE location {
250 
251   struct sun_list *list;
252   struct sun_mountpt *mountpt;
253 
254   /* allocate a mountpt */
255   mountpt = CALLOC(struct sun_mountpt);
256 
257   /* An fstype may have been defined in the 'options'. */
258   if (tmpFsType != NULL) {
259     mountpt->fstype = tmpFsType;
260     tmpFsType = NULL;
261   }
262 
263   /*
264    * Assign the global location list to this entry and reset the
265    * global pointer.  Reseting the global pointer will create a new
266    * list instance next time get_sun_location_list() is called.
267    */
268   list = get_sun_location_list();
269   mountpt->location_list = (struct sun_location *)list->first;
270   sun_location_list = NULL;
271 
272   /*
273    * Assign the global opt list to this entry and reset the global
274    * pointer.  Reseting the global pointer will create a new list
275    * instance next time get_sun_opt_list() is called.
276    */
277   list = get_sun_opt_list();
278   mountpt->opt_list = (struct sun_opt *)list->first;
279   sun_opt_list = NULL;
280 
281   mountpt->path = xstrdup($1);
282 
283   /* Add this mountpt to the mountpt list. */
284   sun_list_add(get_mountpt_list(), (qelem *)mountpt);
285 }
286 ;
287 
288 locations : location
289           | location WSPACE locations
290           ;
291 
292 location : hosts ':' WORD {
293 
294   struct sun_list *list;
295   struct sun_location *location;
296 
297   /* allocate a new location */
298   location = CALLOC(struct sun_location);
299 
300   /*
301    * Assign the global opt list to this entry and reset the global
302    * pointer.  Reseting the global pointer will create a new list
303    * instance next time get_sun_opt_list() is called.
304    */
305   list = get_sun_host_list();
306   location->host_list = (struct sun_host *)list->first;
307   sun_host_list = NULL;
308 
309   location->path = xstrdup($3);
310 
311   /* Add this location to the location list. */
312   sun_list_add(get_sun_location_list(), (qelem *)location);
313 }
314 
315 | ':' WORD {
316 
317   struct sun_location *location;
318 
319   /* allocate a new location */
320   location = CALLOC(struct sun_location);
321 
322   location->path = xstrdup($2);
323 
324   /* Add this location to the location list. */
325   sun_list_add(get_sun_location_list(), (qelem *)location);
326 }
327 ;
328 
329 hosts : host
330       | host ',' hosts
331       ;
332 
333 host : WORD {
334 
335   /* allocate a new host */
336   struct sun_host *host = CALLOC(struct sun_host);
337 
338   host->name = xstrdup($1);
339 
340   /* Add this host to the host list. */
341   sun_list_add(get_sun_host_list(),(qelem *)host);
342 }
343 
344 | WORD weight {
345 
346   /*
347    * It is assumed that the host for this rule was allocated by the
348    * 'weight' rule and assigned to be the last host item on the host
349    * list.
350    */
351   struct sun_host *host = (struct sun_host *)sun_host_list->last;
352 
353   host->name = xstrdup($1);
354 }
355 ;
356 
357 weight : '(' WORD ')' {
358 
359   int val;
360   /* allocate a new host */
361   struct sun_host *host = CALLOC(struct sun_host);
362 
363   val = atoi($2);
364 
365   host->weight = val;
366 
367   /* Add this host to the host list. */
368   sun_list_add(get_sun_host_list(), (qelem *)host);
369 }
370 ;
371 
372 options : option
373         | option ',' options
374         ;
375 
376 option : WORD {
377 
378   char *type;
379 
380   /* check if this is an fstype option */
381   if ((type = strstr($1,SUN_FSTYPE_STR)) != NULL) {
382     /* parse out the fs type from the Sun fstype keyword  */
383     if ((type = type + strlen(SUN_FSTYPE_STR)) != NULL) {
384       /*
385        * This global fstype str will be assigned to the current being
386        * parsed later in the parsing.
387        */
388       tmpFsType = xstrdup(type);
389     }
390   }
391   else {
392     /*
393      * If it is not an fstype option allocate an opt struct and assign
394      * the value.
395      */
396     struct sun_opt *opt = CALLOC(struct sun_opt);
397     opt->str = xstrdup($1);
398     /* Add this opt to the opt list. */
399     sun_list_add(get_sun_opt_list(), (qelem *)opt);
400   }
401 }
402 
403 ;
404 
405 %%
406 
407 /*
408  * Parse 'map_data' which is assumed to be a Sun-syle map.  If
409  * successful a sun_entry is returned.
410  *
411  * The parser is designed to parse map entries with out the keys.  For
412  * example the entry:
413  *
414  * usr -ro pluto:/usr/local
415  *
416  * should be passed to the parser as:
417  *
418  * -ro pluto:/usr/local
419  *
420  * The reason for this is that the Amd info services already strip off
421  * the key when they read map info.
422  */
423 struct sun_entry *
424 sun_map_parse_read(const char *map_data)
425 {
426   struct sun_entry *retval = NULL;
427 
428   /* pass map_data to lex */
429   sun_map_tok_setbuff(map_data);
430 
431   /* call yacc */
432   sun_map_parse();
433 
434   if (sun_entry_list != NULL) {
435     /* return the first Sun entry in the list */
436     retval = (struct sun_entry*)sun_entry_list->first;
437     sun_entry_list = NULL;
438   }
439   else {
440     plog(XLOG_ERROR, "Sun map parser did not produce data structs.");
441   }
442 
443   return retval;
444 }
445 
446 
447 static struct sun_list *
get_sun_entry_list(void)448 get_sun_entry_list(void)
449 {
450   if (sun_entry_list == NULL) {
451     sun_entry_list = CALLOC(struct sun_list);
452   }
453   return sun_entry_list;
454 }
455 
456 
457 static struct sun_list *
get_mountpt_list(void)458 get_mountpt_list(void)
459 {
460   if (mountpt_list == NULL) {
461     mountpt_list = CALLOC(struct sun_list);
462   }
463   return mountpt_list;
464 }
465 
466 
467 static struct sun_list *
get_sun_location_list(void)468 get_sun_location_list(void)
469 {
470   if (sun_location_list == NULL) {
471     sun_location_list = CALLOC(struct sun_list);
472   }
473   return sun_location_list;
474 }
475 
476 
477 static struct sun_list *
get_sun_host_list(void)478 get_sun_host_list(void)
479 {
480   if (sun_host_list == NULL) {
481     sun_host_list = CALLOC(struct sun_list);
482   }
483   return sun_host_list;
484 }
485 
486 
487 static struct sun_list *
get_sun_opt_list(void)488 get_sun_opt_list(void)
489 {
490   if (sun_opt_list == NULL) {
491     sun_opt_list = CALLOC(struct sun_list);
492   }
493   return sun_opt_list;
494 }
495