chiark / gitweb /
Incorporate markups on all paper copies to date.
[userv.git] / parser.c
index 0f8e1956a12a73f6c99e21caa02c5fb46fc4c743..4b55743c1791d99a2ffab60f8bda6e43e662b5d1 100644 (file)
--- a/parser.c
+++ b/parser.c
  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-static directive_fnt *lr_dir=0;
-static parmcondition_fnt *lr_parmcond=0;
-static parameter_fnt *lr_parameter=0;
-static int lr_loglevel, lr_logfacility, lr_min, lr_max, *lr_flag;
-static int lr_flagval, lr_controlend;
-static int lr_fdwant_readwrite;
-
 static void useless(void) { (void)yyunput; (void)useless; /* to shut up GCC ! */ }
 
 static void closeerrorfile(void) {
@@ -303,30 +296,39 @@ static int paa_1path(const char **rv) {
   *rv= string2path(cp); return 0;
 }
 
-static int pa_parameter(char ***rvalues) {
+static int pa_parameter(char ***rvalues, char **rname) {
   /* Scans a single parameter token and calls the appropriate parameter
    * function, returning tokv_error or 0 just like the parameter function.
+   * If rname is non-null then the name of the parameter (malloc'd) will
+   * be stored in it.
    */
   int token, r, i;
+  char *name;
 
   token= yylex(); if (token == tokv_error) return token;
+  name= xstrsave(yytext);
   if ((token & tokm_repres) != tokr_nonstring &&
       !memcmp(yytext,"u-",2) && strlen(yytext)>=3) {
     for (i=0;
-        i<request_mbuf.nvars && strcmp(yytext+2,defvararray[i][0]);
+        i<request_mbuf.nvars && strcmp(yytext+2,defvararray[i].key);
         i++);
     if (i>=request_mbuf.nvars) {
       *rvalues= xmalloc(sizeof(char*));
       **rvalues= 0;
     } else {
-      parm_1string(rvalues,defvararray[i][1]);
+      parm_1string(rvalues,defvararray[i].value);
     }
   } else {
-    if (!(token & tokt_parameter)) return unexpected(token,-1,"parameter name");
+    if (!(token & tokt_parameter)) {
+      free(name);
+      return unexpected(token,-1,"parameter name");
+    }
     r= (lr_parameter)(token,rvalues);
-    if (r) return r;
+    if (r) { free(name); return r; }
   }
-  debug_dumpparameter(yytext,*rvalues);
+  debug_dumpparameter(name,*rvalues);
+  if (rname) *rname= name;
+  else free(name);
   return 0;
 }
 
@@ -372,7 +374,7 @@ static int pa_condition(int *rtrue) {
     *rtrue= actrue; return 0;
   } else if (token & tokt_parmcondition) {
     r= pa_mwsp(); if (r) return r;
-    r= pa_parameter(&parmvalues); if (r) return r;
+    r= pa_parameter(&parmvalues,0); if (r) return r;
     r= (lr_parmcond)(token,parmvalues,rtrue); freecharparray(parmvalues);
     return r;
   }
@@ -684,26 +686,6 @@ int pf_serviceusershell(int ptoken, char ***rvalues) {
 
 /* Directive functions and associated `common code' functions */
 
-int df_reject(int dtoken) {
-  int r;
-  
-  r= pa_mnl(); if (r) return r;
-  execute= tokv_word_reject;
-  free(execpath); execpath= 0;
-  freecharparray(execargs); execargs= 0;
-  return 0;
-}
-
-int df_executefrompath(int dtoken) {
-  int r;
-  
-  r= pa_mnl(); if (r) return r;
-  execute= tokv_word_executefrompath;
-  free(execpath); execpath= 0;
-  freecharparray(execargs); execargs= 0;
-  return 0;
-}
-
 static int paa_pathargs(const char **rv, char ***newargs_r) {
   /* Repeated calls do _not_ overwrite newargs_r; caller must free.
    * Repeated calls _do_ overwrite string returned in rv.
@@ -742,15 +724,41 @@ error:
   return r;
 }
 
+static void execreset(void) {
+  execute= 0;
+  execbuiltin= 0;
+  free(execpath); execpath= 0;
+  freecharparray(execargs); execargs= 0;
+}
+
+int df_reject(int dtoken) {
+  int r;
+  
+  r= pa_mnl(); if (r) return r;
+  execreset();
+  execute= tokv_word_reject;
+  return 0;
+}
+
+int df_executefrompath(int dtoken) {
+  int r;
+  
+  r= pa_mnl(); if (r) return r;
+  execreset();
+  execute= tokv_word_executefrompath;
+  return 0;
+}
+
 int df_execute(int dtoken) {
   const char *rv;
   char **newargs;
   int r;
 
   r= paa_pathargs(&rv,&newargs); if (r) return r;
+  execreset();
   execute= tokv_word_execute;
-  freecharparray(execargs); execargs= newargs;
-  free(execpath); execpath= xstrsave(rv);
+  execargs= newargs;
+  execpath= xstrsave(rv);
   return 0;
 }
 
@@ -792,9 +800,51 @@ int df_executefromdirectory(int dtoken) {
                  " or link to one (mode=0%o)",fn,stab.st_mode);
     free(fn); freecharparray(newargs); return tokv_error;
   }
+  execreset();
   execute= tokv_word_executefromdirectory;
-  freecharparray(execargs); execargs= newargs;
-  free(execpath); execpath= fn;
+  execargs= newargs;
+  execpath= fn;
+  return 0;
+}
+
+static int bispa_none(char ***rnewargs) {
+  return pa_mnl();
+}
+
+static int bispa_parameter(char ***rnewargs) {
+  int r, i;
+  char **parmvalues, *name, **newargs;
+  
+  r= pa_mwsp(); if (r) return r;
+  r= pa_parameter(&parmvalues,&name); if (r) return r;
+  for (i=0; parmvalues[i]; i++);
+  newargs= xmalloc(sizeof(char*)*(i+2));
+  newargs[0]= name;
+  memcpy(newargs+1,parmvalues,sizeof(char*)*(i+1));
+  free(parmvalues);
+  r= pa_mnl(); if (r) { free(newargs); return r; }
+  *rnewargs= newargs;
+  return 0;
+}
+
+int df_executebuiltin(int dtoken) {
+  int r;
+  builtinserviceexec_fnt *bisexec;
+  char *newpath, **newargs;
+
+  r= pa_mwsp(); if (r) return r;
+  r= yylex(); if (r == tokv_error) return r;
+  if (!(r & tokt_builtinservice)) return unexpected(r,-1,"builtin service name");
+  bisexec= lr_bisexec;
+  newpath= xstrsave(yytext);
+  newargs= 0;
+  r= lr_bispa(&newargs); if (r) { free(newpath); return r; }
+
+  execreset();
+  execute= tokv_word_executebuiltin;
+  execbuiltin= bisexec;
+  execpath= newpath;
+  execargs= newargs;
   return 0;
 }
 
@@ -1009,7 +1059,7 @@ int df_includelookup(int dtoken) {
   int r, done, thisdone, cpl, c;
 
   r= pa_mwsp(); if (r) return r;
-  r= pa_parameter(&parmvalues); if (r) return r;
+  r= pa_parameter(&parmvalues,0); if (r) return r;
   r= paa_1path(&cp); if (r) { freecharparray(parmvalues); return r; }
   if (stat(cp,&stab)) {
     parseerrprint("unable to access directory `%s': %s",cp,strerror(errno));