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