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