chiark / gitweb /
Regenerated formatted documentation (spec.ps, spec.html).
[userv.git] / parser.c
index 0965f41..5f6ebad 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -6,7 +6,7 @@
  * about m4 quoting &c., but we have to #include it so that the C
  * objects from the lexer are available.
  *
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-1999 Ian Jackson
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
@@ -139,7 +139,7 @@ static void freecharparray(char **array) {
 static int dequote(char *inplace) {
   char *p, *q, buf[4], *bep;
   int v;
-  
+
   p=q=inplace;
   assert(*p++ = '"');
   while (*p && *p != '"') {
@@ -149,26 +149,37 @@ static int dequote(char *inplace) {
     case 'r': *q++= '\r'; continue;
     case 't': *q++= '\t'; continue;
     case 'x':
-      assert(buf[0]= *++p); assert(buf[1]= *++p); buf[2]= 0;
-      v= strtoul(buf,&bep,16); assert(bep == buf+2);
-      assert(!(v & ~0xff)); *q++= v; p++; continue;
+      p++;
+      if (!((buf[0]= *p++) && (buf[1]= *p++))) {
+       parseerrprint("quoted string ends inside \\x<hex> sequence");
+       return tokv_error;
+      }
+      buf[2]= 0;
+      v= strtoul(buf,&bep,16);
+      if (bep != buf+2) {
+       parseerrprint("invalid \\<hex> sequence \\x%s in quoted string",buf);
+       return tokv_error;
+      }
+      assert(!(v & ~0xff));
+      *q++= v;
+      continue;
     default:
       if (isalpha(*p)) {
         parseerrprint("unknown \\<letter> sequence \\%c in quoted string",*p);
         return tokv_error;
       } else if (isdigit(*p)) {
-        assert(buf[0]= *++p); assert(buf[1]= *++p); assert(buf[2]= *++p);
+        if (!((buf[0]= *p++) && (buf[1]= *p++) && (buf[2]= *p++))) abort();
         buf[3]= 0; v= strtoul(buf,&bep,8);
-        if (bep != buf+3 || (v & ~0xff)); {
+        if (bep != buf+3 || (v & ~0xff)) {
           parseerrprint("invalid \\<octal> sequence \\%s in quoted string",buf);
           return tokv_error;
         }
-        *q++= v; p++; continue;
+        *q++= v; continue;
       } else if (ispunct(*p)) {
         *q++= *p++; continue;
       } else {
        while (*p==' ' || *p=='\t') p++;
-       assert(*p=='\n');
+       v= *p++; assert(v=='\n');
       }
     }
   }
@@ -488,7 +499,7 @@ static int pf_service(int ptoken, char ***rvalues) {
 }
 
 static int pf_callinguser(int ptoken, char ***rvalues) {
-  return parm_usernameuid(rvalues,logname,request_mbuf.callinguid);
+  return parm_usernameuid(rvalues,loginname,request_mbuf.callinguid);
 }
 
 static int pf_serviceuser(int ptoken, char ***rvalues) {
@@ -839,8 +850,7 @@ int df_reset(int dtoken) {
 
   r= pa_mnl(); if (r) return r;
   r= parse_string(RESET_CONFIGURATION,"<builtin reset configuration>",1);
-  assert(!r);
-  return 0;  
+  return r;
 }
 
 int dfg_fdwant(int dtoken) {
@@ -987,14 +997,16 @@ int df_includedirectory(int dtoken) {
   int r, cpl, tel, c, found;
   DIR *d;
   struct dirent *de;
-  const char *p, *cp;
+  const char *p, *cpget;
+  char *cp;
   
-  r= paa_1path(&cp); if (r) return r;
-  d= opendir(cp);
+  r= paa_1path(&cpget); if (r) return r;
+  d= opendir(cpget);
   if (!d) {
-    parseerrprint("unable to open directory `%s': %s",cp,strerror(errno));
+    parseerrprint("unable to open directory `%s': %s",cpget,strerror(errno));
     return tokv_error;
   }
+  cp= xstrsave(cpget);
   cpl= strlen(cp);
   while ((de= readdir(d))) {
     tel= strlen(de->d_name);
@@ -1003,60 +1015,72 @@ int df_includedirectory(int dtoken) {
     if (!*p || !isalnum(*p)) continue;
     while ((c= *++p)) if (!(isalnum(c) || c=='-')) break;
     if (c) continue;
-    if (makeroom(&buildbuf,&buildbuflen,cpl+1+tel+1))
-      return stringoverflow("pathname in directory");
+    if (makeroom(&buildbuf,&buildbuflen,cpl+1+tel+1)) {
+      stringoverflow("pathname in directory");
+      r= tokv_error; goto x_err;
+    }
     snyprintf(buildbuf,buildbuflen,"%s/%s",cp,de->d_name);
-    r= parse_file(buildbuf,&found); if (r) { closedir(d); return r; }
+    r= parse_file(buildbuf,&found); if (r) goto x_err;
     if (!found) {
       parseerrprint("unable to open file `%s' in included directory `%s': %s",
                    de->d_name,cp,strerror(errno));
-      closedir(d);
-      return tokv_error;
+      r= tokv_error; goto x_err;
     }
   }
   if (closedir(d)) {
     parseerrprint("error closing directory `%s': %s",cp,strerror(errno));
+    free(cp);
     return tokv_error;
   }
+  free(cp);
   return 0;
+
+x_err:
+  closedir(d);
+  free(cp);
+  return r;
 }
 
 int df_includelookup(int dtoken) {
   static char *buildbuf=0;
   int buildbuflen=0;
   
-  char **parmvalues, **pp, *p, *q;
-  const char *cp;
+  char **parmvalues, **pp, *p, *q, *cp;
+  const char *cpget;
   struct stat stab;
   int r, done, thisdone, cpl, c;
 
   r= pa_mwsp(); 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));
+  r= paa_1path(&cpget); if (r) { freecharparray(parmvalues); return r; }
+  if (stat(cpget,&stab)) {
+    parseerrprint("unable to access directory `%s': %s",cpget,strerror(errno));
     freecharparray(parmvalues); return tokv_error;
   }
   if (!S_ISDIR(stab.st_mode)) {
-    parseerrprint("object `%s' is not a directory or link to one",cp);
+    parseerrprint("object `%s' is not a directory or link to one",cpget);
     freecharparray(parmvalues); return tokv_error;
   }
   done= 0;
+  cp= xstrsave(cpget);
   cpl= strlen(cp);
   if (!parmvalues[0]) {
-    if (makeroom(&buildbuf,&buildbuflen,cpl+1+sizeof(NONEINCLUDELOOKUP)))
-      return stringoverflow("pathname in directory for lookup of undefined parameter");
+    if (makeroom(&buildbuf,&buildbuflen,cpl+1+sizeof(NONEINCLUDELOOKUP))) {
+      stringoverflow("pathname in directory for lookup of undefined parameter");
+      r= tokv_error; goto x_err;
+    }
     snyprintf(buildbuf,buildbuflen,"%s/" NONEINCLUDELOOKUP,cp);
-    r= parse_file(buildbuf,&thisdone);
-    if (r) { freecharparray(parmvalues); return r; }
+    r= parse_file(buildbuf,&thisdone); if (r) goto x_err;
     if (thisdone) done= 1;
   } else {
     for (pp=parmvalues;
         *pp && (!done || dtoken == tokv_word_includelookupall);
         pp++) {
       if (makeroom(&buildbuf,&buildbuflen,
-                  cpl+1+strlen(*pp)*2+3+sizeof(EMPTYINCLUDELOOKUP)+1))
-       return stringoverflow("pathname in directory for lookup");
+                  cpl+1+strlen(*pp)*2+3+sizeof(EMPTYINCLUDELOOKUP)+1)) {
+       stringoverflow("pathname in directory for lookup");
+       r= tokv_error; goto x_err;
+      }
       strcpy(buildbuf,cp);
       p= *pp; q= buildbuf+cpl;
       *q++= '/';
@@ -1072,19 +1096,25 @@ int df_includelookup(int dtoken) {
        *q++= 0;
       }
       r= parse_file(buildbuf,&thisdone);
-      if (r) { freecharparray(parmvalues); return r; }
+      if (r) goto x_err;
       if (thisdone) done= 1;
     }
   }
-  freecharparray(parmvalues);
   if (!done) {
     if (makeroom(&buildbuf,&buildbuflen,
-                cpl+1+sizeof(DEFAULTINCLUDELOOKUP)))
-      return stringoverflow("pathname in directory for lookup of default");
+                cpl+1+sizeof(DEFAULTINCLUDELOOKUP))) {
+      stringoverflow("pathname in directory for lookup of default");
+      r= tokv_error; goto x_err;
+    }
     snyprintf(buildbuf,buildbuflen,"%s/" DEFAULTINCLUDELOOKUP,cp);
-    r= parse_file(buildbuf,0); if (r) return r;
+    r= parse_file(buildbuf,0); if (r) goto x_err;
   }
-  return 0;
+  r= 0;
+  
+x_err:
+  freecharparray(parmvalues);
+  free(cp);
+  return r;
 }
 
 /* Control constructs */