aboutsummaryrefslogtreecommitdiffstats
path: root/amd/sun_map_parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'amd/sun_map_parse.y')
-rw-r--r--amd/sun_map_parse.y492
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;
+}