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 53extern int sun_map_lex(void); 54extern int sun_map_error(const char *); 55extern void sun_map_tok_setbuff(const char *); 56extern int sun_map_parse(void); 57 58struct sun_entry *sun_map_parse_read(const char *); 59 60static struct sun_list *sun_entry_list = NULL; 61static struct sun_list *sun_opt_list = NULL; 62static struct sun_list *sun_host_list = NULL; 63static struct sun_list *sun_location_list = NULL; 64static struct sun_list *mountpt_list = NULL; 65static 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 */ 73static struct sun_list *get_sun_opt_list(void); 74static struct sun_list *get_sun_host_list(void); 75static struct sun_list *get_sun_location_list(void); 76static struct sun_list *get_mountpt_list(void); 77static 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 90amap : file 91 ; 92 93file : new_lines entries 94 | entries 95 ; 96 97entries : entry 98 | entry new_lines 99 | entry new_lines entries 100 ; 101 102new_lines : NEWLINE 103 | NEWLINE new_lines 104 ; 105 106entry : 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 220mountpoints : mountpoint 221 | mountpoint WSPACE mountpoints 222 ; 223 224mountpoint : 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 286locations : location 287 | location WSPACE locations 288 ; 289 290location : 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 327hosts : host 328 | host ',' hosts 329 ; 330 331host : 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 355weight : '(' 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 370options : option 371 | option ',' options 372 ; 373 374option : 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 */ 421struct sun_entry * 422sun_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 445static struct sun_list * 446get_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 455static struct sun_list * 456get_mountpt_list(void) 457{ 458 if (mountpt_list == NULL) { 459 mountpt_list = CALLOC(struct sun_list); 460 } 461 return mountpt_list; 462} 463 464 465static struct sun_list * 466get_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 475static struct sun_list * 476get_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 485static struct sun_list * 486get_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