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 55extern int sun_map_lex(void); 56extern int sun_map_error(const char *); 57extern void sun_map_tok_setbuff(const char *); 58extern int sun_map_parse(void); 59 60struct sun_entry *sun_map_parse_read(const char *); 61 62static struct sun_list *sun_entry_list = NULL; 63static struct sun_list *sun_opt_list = NULL; 64static struct sun_list *sun_host_list = NULL; 65static struct sun_list *sun_location_list = NULL; 66static struct sun_list *mountpt_list = NULL; 67static 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 */ 75static struct sun_list *get_sun_opt_list(void); 76static struct sun_list *get_sun_host_list(void); 77static struct sun_list *get_sun_location_list(void); 78static struct sun_list *get_mountpt_list(void); 79static 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 92amap : file 93 ; 94 95file : new_lines entries 96 | entries 97 ; 98 99entries : entry 100 | entry new_lines 101 | entry new_lines entries 102 ; 103 104new_lines : NEWLINE 105 | NEWLINE new_lines 106 ; 107 108entry : 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 222mountpoints : mountpoint 223 | mountpoint WSPACE mountpoints 224 ; 225 226mountpoint : 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 288locations : location 289 | location WSPACE locations 290 ; 291 292location : 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 329hosts : host 330 | host ',' hosts 331 ; 332 333host : 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 357weight : '(' 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 372options : option 373 | option ',' options 374 ; 375 376option : 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 */ 423struct sun_entry * 424sun_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 447static struct sun_list * 448get_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 457static struct sun_list * 458get_mountpt_list(void) 459{ 460 if (mountpt_list == NULL) { 461 mountpt_list = CALLOC(struct sun_list); 462 } 463 return mountpt_list; 464} 465 466 467static struct sun_list * 468get_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 477static struct sun_list * 478get_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 487static struct sun_list * 488get_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