diff options
Diffstat (limited to 'amd/sun_map_parse.y')
| -rw-r--r-- | amd/sun_map_parse.y | 492 |
1 files changed, 492 insertions, 0 deletions
diff --git a/amd/sun_map_parse.y b/amd/sun_map_parse.y new file mode 100644 index 000000000000..ccf258e2dcc8 --- /dev/null +++ b/amd/sun_map_parse.y @@ -0,0 +1,492 @@ +%{ +/* + * Copyright (c) 1997-2014 Erez Zadok + * Copyright (c) 2005 Daniel P. Ottavio + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * File: am-utils/amd/sun_map_parse.y + * + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif /* HAVE_CONFIG_H */ +#include <am_defs.h> +#include <amd.h> +#include <sun_map.h> + + +#define SUN_FSTYPE_STR "fstype=" + + +extern int sun_map_lex(void); +extern int sun_map_error(const char *); +extern void sun_map_tok_setbuff(const char *); +extern int sun_map_parse(void); + +struct sun_entry *sun_map_parse_read(const char *); + +static struct sun_list *sun_entry_list = NULL; +static struct sun_list *sun_opt_list = NULL; +static struct sun_list *sun_host_list = NULL; +static struct sun_list *sun_location_list = NULL; +static struct sun_list *mountpt_list = NULL; +static char *tmpFsType = NULL; + + +/* + * Each get* function returns a pointer to the corresponding global + * list structure. If the structure is NULL than a new instance is + * returned. + */ +static struct sun_list *get_sun_opt_list(void); +static struct sun_list *get_sun_host_list(void); +static struct sun_list *get_sun_location_list(void); +static struct sun_list *get_mountpt_list(void); +static struct sun_list *get_sun_entry_list(void); + +%} + +%union { + char strval[2048]; +} + +%token NEWLINE COMMENT WSPACE +%token <strval> WORD + +%% + +amap : file + ; + +file : new_lines entries + | entries + ; + +entries : entry + | entry new_lines + | entry new_lines entries + ; + +new_lines : NEWLINE + | NEWLINE new_lines + ; + +entry : locations { + + struct sun_list *list; + struct sun_entry *entry; + + /* allocate an entry */ + entry = CALLOC(struct sun_entry); + + /* + * Assign the global location list to this entry and reset the + * global pointer. Reseting the global pointer will create a new + * list instance next time get_sun_location_list() is called. + */ + list = get_sun_location_list(); + entry->location_list = (struct sun_location *)list->first; + sun_location_list = NULL; + + /* Add this entry to the entry list. */ + sun_list_add(get_sun_entry_list(), (qelem *)entry); +} + +| '-' options WSPACE locations { + + struct sun_list *list; + struct sun_entry *entry; + + entry = CALLOC(struct sun_entry); + + /* An fstype may have been defined in the 'options'. */ + if (tmpFsType != NULL) { + entry->fstype = tmpFsType; + tmpFsType = NULL; + } + + /* + * Assign the global location list to this entry and reset the + * global pointer. Reseting the global pointer will create a new + * list instance next time get_sun_location_list() is called. + */ + list = get_sun_location_list(); + entry->location_list = (struct sun_location *)list->first; + sun_location_list = NULL; + + /* + * Assign the global opt list to this entry and reset the global + * pointer. Reseting the global pointer will create a new list + * instance next time get_sun_opt_list() is called. + */ + list = get_sun_opt_list(); + entry->opt_list = (struct sun_opt *)list->first; + sun_opt_list = NULL; + + /* Add this entry to the entry list. */ + sun_list_add(get_sun_entry_list(), (qelem *)entry); +} + +| mountpoints { + + struct sun_list *list; + struct sun_entry *entry; + + /* allocate an entry */ + entry = CALLOC(struct sun_entry); + + /* + * Assign the global mountpt list to this entry and reset the global + * pointer. Reseting the global pointer will create a new list + * instance next time get_mountpt_list() is called. + */ + list = get_mountpt_list(); + entry->mountpt_list = (struct sun_mountpt *)list->first; + mountpt_list = NULL; + + /* Add this entry to the entry list. */ + sun_list_add(get_sun_entry_list(), (qelem *)entry); +} + +| '-' options WSPACE mountpoints { + + struct sun_list *list; + struct sun_entry *entry; + + /* allocate an entry */ + entry = CALLOC(struct sun_entry); + + /* An fstype may have been defined in the 'options'. */ + if (tmpFsType != NULL) { + entry->fstype = tmpFsType; + tmpFsType = NULL; + } + + /* + * Assign the global mountpt list to this entry and reset the global + * pointer. Reseting the global pointer will create a new list + * instance next time get_mountpt_list() is called. + */ + list = get_mountpt_list(); + entry->mountpt_list = (struct sun_mountpt *)list->first; + mountpt_list = NULL; + + /* + * Assign the global opt list to this entry and reset the global + * pointer. Reseting the global pointer will create a new list + * instance next time get_sun_opt_list() is called. + */ + list = get_sun_opt_list(); + entry->opt_list = (struct sun_opt *)list->first; + sun_opt_list = NULL; + + /* Add this entry to the entry list. */ + sun_list_add(get_sun_entry_list(), (qelem *)entry); +} +; + +mountpoints : mountpoint + | mountpoint WSPACE mountpoints + ; + +mountpoint : WORD WSPACE location { + + struct sun_list *list; + struct sun_mountpt *mountpt; + + /* allocate a mountpt */ + mountpt = CALLOC(struct sun_mountpt); + + /* + * Assign the global loaction list to this entry and reset the + * global pointer. Reseting the global pointer will create a new + * list instance next time get_sun_location_list() is called. + */ + list = get_sun_location_list(); + mountpt->location_list = (struct sun_location *)list->first; + sun_location_list = NULL; + + mountpt->path = xstrdup($1); + + /* Add this mountpt to the mountpt list. */ + sun_list_add(get_mountpt_list(), (qelem *)mountpt); +} + +| WORD WSPACE '-' options WSPACE location { + + struct sun_list *list; + struct sun_mountpt *mountpt; + + /* allocate a mountpt */ + mountpt = CALLOC(struct sun_mountpt); + + /* An fstype may have been defined in the 'options'. */ + if (tmpFsType != NULL) { + mountpt->fstype = tmpFsType; + tmpFsType = NULL; + } + + /* + * Assign the global location list to this entry and reset the + * global pointer. Reseting the global pointer will create a new + * list instance next time get_sun_location_list() is called. + */ + list = get_sun_location_list(); + mountpt->location_list = (struct sun_location *)list->first; + sun_location_list = NULL; + + /* + * Assign the global opt list to this entry and reset the global + * pointer. Reseting the global pointer will create a new list + * instance next time get_sun_opt_list() is called. + */ + list = get_sun_opt_list(); + mountpt->opt_list = (struct sun_opt *)list->first; + sun_opt_list = NULL; + + mountpt->path = xstrdup($1); + + /* Add this mountpt to the mountpt list. */ + sun_list_add(get_mountpt_list(), (qelem *)mountpt); +} +; + +locations : location + | location WSPACE locations + ; + +location : hosts ':' WORD { + + struct sun_list *list; + struct sun_location *location; + + /* allocate a new location */ + location = CALLOC(struct sun_location); + + /* + * Assign the global opt list to this entry and reset the global + * pointer. Reseting the global pointer will create a new list + * instance next time get_sun_opt_list() is called. + */ + list = get_sun_host_list(); + location->host_list = (struct sun_host *)list->first; + sun_host_list = NULL; + + location->path = xstrdup($3); + + /* Add this location to the location list. */ + sun_list_add(get_sun_location_list(), (qelem *)location); +} + +| ':' WORD { + + struct sun_location *location; + + /* allocate a new location */ + location = CALLOC(struct sun_location); + + location->path = xstrdup($2); + + /* Add this location to the location list. */ + sun_list_add(get_sun_location_list(), (qelem *)location); +} +; + +hosts : host + | host ',' hosts + ; + +host : WORD { + + /* allocate a new host */ + struct sun_host *host = CALLOC(struct sun_host); + + host->name = xstrdup($1); + + /* Add this host to the host list. */ + sun_list_add(get_sun_host_list(),(qelem *)host); +} + +| WORD weight { + + /* + * It is assumed that the host for this rule was allocated by the + * 'weight' rule and assigned to be the last host item on the host + * list. + */ + struct sun_host *host = (struct sun_host *)sun_host_list->last; + + host->name = xstrdup($1); +} +; + +weight : '(' WORD ')' { + + int val; + /* allocate a new host */ + struct sun_host *host = CALLOC(struct sun_host); + + val = atoi($2); + + host->weight = val; + + /* Add this host to the host list. */ + sun_list_add(get_sun_host_list(), (qelem *)host); +} +; + +options : option + | option ',' options + ; + +option : WORD { + + char *type; + + /* check if this is an fstype option */ + if ((type = strstr($1,SUN_FSTYPE_STR)) != NULL) { + /* parse out the fs type from the Sun fstype keyword */ + if ((type = type + strlen(SUN_FSTYPE_STR)) != NULL) { + /* + * This global fstype str will be assigned to the current being + * parsed later in the parsing. + */ + tmpFsType = xstrdup(type); + } + } + else { + /* + * If it is not an fstype option allocate an opt struct and assign + * the value. + */ + struct sun_opt *opt = CALLOC(struct sun_opt); + opt->str = xstrdup($1); + /* Add this opt to the opt list. */ + sun_list_add(get_sun_opt_list(), (qelem *)opt); + } +} + +; + +%% + +/* + * Parse 'map_data' which is assumed to be a Sun-syle map. If + * successful a sun_entry is returned. + * + * The parser is designed to parse map entries with out the keys. For + * example the entry: + * + * usr -ro pluto:/usr/local + * + * should be passed to the parser as: + * + * -ro pluto:/usr/local + * + * The reason for this is that the Amd info services already strip off + * the key when they read map info. + */ +struct sun_entry * +sun_map_parse_read(const char *map_data) +{ + struct sun_entry *retval = NULL; + + /* pass map_data to lex */ + sun_map_tok_setbuff(map_data); + + /* call yacc */ + sun_map_parse(); + + if (sun_entry_list != NULL) { + /* return the first Sun entry in the list */ + retval = (struct sun_entry*)sun_entry_list->first; + sun_entry_list = NULL; + } + else { + plog(XLOG_ERROR, "Sun map parser did not produce data structs."); + } + + return retval; +} + + +static struct sun_list * +get_sun_entry_list(void) +{ + if (sun_entry_list == NULL) { + sun_entry_list = CALLOC(struct sun_list); + } + return sun_entry_list; +} + + +static struct sun_list * +get_mountpt_list(void) +{ + if (mountpt_list == NULL) { + mountpt_list = CALLOC(struct sun_list); + } + return mountpt_list; +} + + +static struct sun_list * +get_sun_location_list(void) +{ + if (sun_location_list == NULL) { + sun_location_list = CALLOC(struct sun_list); + } + return sun_location_list; +} + + +static struct sun_list * +get_sun_host_list(void) +{ + if (sun_host_list == NULL) { + sun_host_list = CALLOC(struct sun_list); + } + return sun_host_list; +} + + +static struct sun_list * +get_sun_opt_list(void) +{ + if (sun_opt_list == NULL) { + sun_opt_list = CALLOC(struct sun_list); + } + return sun_opt_list; +} |
