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