www-cgi/: Centralize environment variable filtering.
[userv-utils] / www-cgi / ucgitarget.c
index eb5fdab..a4b5690 100644 (file)
 
 #include "ucgi.h"
 
-static void *xrealloc(void *ptr, size_t sz) {
-  void *r;
-
-  r= realloc(ptr,sz);
-  if (!r) syserror("realloc failed");
-  return r;
+static void setenvar(const char *fulln,
+                    const char *en, const char *ep, void *p) {
+  xsetenv(en, ep, 1);
+  unsetenv(fulln);
 }
 
 int main(int argc, const char **argv) {
-  char *uservarn, *scriptpath, *newvar;
-  const char *nextslash, *lastslash, *pathi, *ev, *ev2, *en, *scriptdir, *av;
-  const char *const *ep;
+  char *scriptpath, *newvar;
+  const char *nextslash, *lastslash, *pathi, *ev, *ev2, *scriptdir, *av;
   const char **arguments;
-  size_t scriptdirlen, scriptpathlen, l, uservarnl;
+  size_t scriptdirlen, scriptpathlen, l;
   struct stat stab;
   int r, nargs;
 
   ev= getenv("USERV_U_DEBUG");
   if (ev && *ev) debugmode= 1;
   
+  D( if (debugmode) printf(";;; UCGITARGET\n"); )
   if (argc > MAX_ARGS) error("too many arguments");
 
   if (!*++argv) error("no script directory argument");
@@ -62,22 +60,17 @@ int main(int argc, const char **argv) {
   scriptdir= newvar;
   scriptdirlen= strlen(scriptdir);
 
-  uservarn= 0;
-  uservarnl= 0;
-  for (ep= envok; (en= *ep); ep++) {
-    l= strlen(en)+11;
-    if (uservarnl<l) { uservarn= xrealloc(uservarn,l); uservarnl= l; }
-    sprintf(uservarn,"USERV_U_E_%s",en);
-    ev= getenv(uservarn); if (!ev) continue;
-    if (strlen(ev) > MAX_ENVVAR_VALUE) error("environment variable too long");
-    if (setenv(en,ev,1)) syserror("setenv");
-    unsetenv(uservarn);
-  }
+  filter_environment(0, "USERV_U_E_", envok, setenvar, 0);
 
   scriptpath= 0;
   pathi= getenv("PATH_INFO");
   if (!pathi) error("PATH_INFO not found");
   lastslash= pathi;
+  D( if (debugmode) {
+       printf(";; find script name...\n"
+             ";;   PATH_INFO = `%s'\n",
+             pathi);
+  } )
   for (;;) {
     if (*lastslash != '/') error("PATH_INFO expected slash not found");
     if (lastslash[1]=='.' || lastslash[1]=='#' || !lastslash[1]) error("bad char begin");
@@ -92,11 +85,13 @@ int main(int argc, const char **argv) {
     memcpy(scriptpath+scriptdirlen,pathi,nextslash-pathi);
     scriptpath[scriptpathlen]= 0;
     if (scriptpath[scriptpathlen-1]=='~') error("bad char end");
+    D( if (debugmode) printf(";;   try `%s'\n", scriptpath); )
     r= stat(scriptpath,&stab); if (r) syserror("stat script");
     if (S_ISREG(stab.st_mode)) break;
-    if (!S_ISDIR(stab.st_mode)) syserror("script not directory or file");
+    if (!S_ISDIR(stab.st_mode)) error("script not directory or file");
     lastslash= nextslash;
   }
+  D( if (debugmode) printf(";;   found script: tail = `%s'\n", nextslash); )
   if (*nextslash) xsetenv("PATH_INFO",nextslash,1);
   else unsetenv("PATH_INFO");
 
@@ -121,6 +116,19 @@ int main(int argc, const char **argv) {
   while ((av= (*++argv))) arguments[nargs++]= av;
   arguments[nargs++]= 0;
 
+  D( if (debugmode) {
+       int i;
+
+       printf(";; final environment...\n");
+       for (i = 0; environ[i]; i++)
+        printf(";;   %s\n", environ[i]);
+
+       printf(";; final command line...\n");
+       for (i = 0; arguments[i]; i++)
+        printf(";;   %s\n", arguments[i]);
+       fflush(stdout);
+  } )
+
   execvp(scriptpath,(char*const*)arguments);
   syserror("exec script");
   return -1;