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