From: ian Date: Wed, 2 Jul 2003 18:53:26 +0000 (+0000) Subject: found in davenant:/usr/local/src/misc X-Git-Tag: debian_version_0_3~16 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?p=userv-utils.git;a=commitdiff_plain;h=6c8e44a54c692f6e62d376aa6e3c3e16c7db57bb;hp=23246c5e550b105042fc511953d7450c5fb29d3d found in davenant:/usr/local/src/misc --- diff --git a/www-cgi/ucgi b/www-cgi/ucgi new file mode 100755 index 0000000..4f42c86 Binary files /dev/null and b/www-cgi/ucgi differ diff --git a/www-cgi/ucgi.c~ b/www-cgi/ucgi.c~ new file mode 100644 index 0000000..b336f96 --- /dev/null +++ b/www-cgi/ucgi.c~ @@ -0,0 +1,37 @@ +/* + * Usage: as CGI script + */ + +#include "ucgi.h" + +int main(int argc, const char **argv) { + char *defarg; + const char *slash2, *pathi, *ev, *en, *av; + const char *const *ep; + const char **arguments; + size_t usernamelen; + + pathi= getenv("PATH_INFO"); + if (pathi[0] != '/' || pathi[1] != '~') error("PATH_INFO must start with /~"); + slash2= strchr(pathi,'/'); if (!slash2) error("PATH_INFO must have more than one /"); + usernamelen= slash2-(pathi+2); + if (usernamelen > MAX_USERNAME_LEN) error("PATH_INFO username too long"); + username= xmalloc(usernamelen+1); memcpy(username,pathi+2); username[usernamelen]= 0; + if (!isalpha(username[0])) error("username 1st character is not alphabetic"); + if (setenv("PATH_INFO",slash2,1)) syserror("setenv PATH_INFO"); + + arguments= xmalloc(sizeof(const char*)*(nenvok+argc+10)); + nargs= 0; + arguments[0]= "userv"; + for (ep= envok; (en= *ep); ep++) { + ev= getenv(en); if (!ev) continue; + l= strlen(ev); if (l > MAX_ENVVAR_VALUE) error("environment variable too long"); + defarg= xmalloc(strlen(en)+l+5); + sprintf(defarg,"-D%s=%s",en,ev); + arguments[nargs++]= defarg; + } + arguments[nargs++]= username; + arguments[nargs++]= "www-cgi"; + while ((av= (*++argv))) arguments[nargs++]= av; + arguments[nargs++]= 0; +} diff --git a/www-cgi/ucgi.h~ b/www-cgi/ucgi.h~ new file mode 100644 index 0000000..f5bda11 --- /dev/null +++ b/www-cgi/ucgi.h~ @@ -0,0 +1,15 @@ +/**/ + +#ifndef UCGI_H +#define UCGI_H + +#include "ucgicommon.h" + +void syserror(const char *m); +void error(const char *m); +void *xmalloc(size_t sz); + +extern const char *const envok[]; +extern const int nenvok; + +#endif diff --git a/www-cgi/ucgicommon.c~ b/www-cgi/ucgicommon.c~ new file mode 100644 index 0000000..327beae --- /dev/null +++ b/www-cgi/ucgicommon.c~ @@ -0,0 +1,61 @@ +/**/ + +#include "ucgicommon.h" + +const char *const envok[]= { + "CONTENT_LENGTH", + "CONTENT_TYPE", + "DOCUMENT_ROOT", + "GATEWAY_INTERFACE", + "HTTP_ACCEPT", + "HTTP_ACCEPT_ENCODING", + "HTTP_ACCEPT_LANGUAGE", + "HTTP_CACHE_CONTROL", + "HTTP_HOST", + "HTTP_NEGOTIATE", + "HTTP_PRAGMA", + "HTTP_USER_AGENT", + "PATH_INFO", + "PATH_TRANSLATED", + "QUERY_STRING", + "REMOTE_ADDR", + "REMOTE_HOST", + "REMOTE_USER", + "REMOTE_IDENT", + "REQUEST_METHOD", + "SCRIPT_FILENAME", + "SCRIPT_NAME", + "SCRIPT_URI", + "SCRIPT_URL", + "SERVER_ADMIN", + "SERVER_NAME", + "SERVER_PORT", + "SERVER_PROTOCOL", + "SERVER_SOFTWARE", + 0 +}; +const int nenvok= sizeof(envok)/sizeof(envok[0]); + +void syserror(const char *m) { + if (printf("Content-Type: text/plain\n\n" + "ucgi: system call error:\n" + "%s: %s\n", + m,strerror(errno))==EOF || fflush(stdout)) outerror(); + exit(0); +} + +void error(const char *m) { + if (printf("Content-Type: text/plain\n\n" + "ucgi: error:\n" + "%s\n", + m)==EOF || fflush(stdout)) outerror(); + exit(0); +} + +void *xmalloc(size_t sz) { + void *r; + + r= malloc(sz); + if (!r) syserror("malloc failed"); + return r; +} diff --git a/www-cgi/ucgitarget b/www-cgi/ucgitarget new file mode 100755 index 0000000..8ce16f4 Binary files /dev/null and b/www-cgi/ucgitarget differ diff --git a/www-cgi/ucgitarget.c~ b/www-cgi/ucgitarget.c~ new file mode 100644 index 0000000..5299b6a --- /dev/null +++ b/www-cgi/ucgitarget.c~ @@ -0,0 +1,81 @@ +/* + * Usage: as CGI script, but called by userv + * environment variables are USERV_U_E_... + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "ucgi.h" + +void *xrealloc(void *ptr, size_t sz) { + void *r; + + r= realloc(ptr,sz); + if (!r) syserror("realloc failed"); + return r; +} + +int main(int argc, const char **argv) { + char *uservar, *scriptpath; + const char *nextslash, *lastslash, *pathi, *ev, *en, *scriptdir; + const char *const *ep; + const char **arguments; + size_t scriptdirlen, scriptpathlen, l, uservarnl; + struct stat stab; + + ev= getenv("USERV_U_DEBUG"); + if (ev && *ev) debugmode= 1; + + if (argc > MAX_ARGS) error("too many arguments"); + + scriptdir= *++argv; + if (!scriptdir) error("no argv[1] (script directory)"); + scriptdirlen= strlen(scriptdir); + + for (ep= envok; (en= *ep); ep++) { + l= strlen(en)+11; + if (uservarnl MAX_ENVVAR_VALUE) error("environment variable too long"); + if (setenv(en,ev,1)) syserror("setenv"); + if (unsetenv(uservarn)) syserror("unsetenv"); + } + + pathi= getenv("PATH_INFO"); + if (!pathi) error("PATH_INFO not found"); + if (pathi[0] != '/') error("PATH_INFO must start with /"); + lastslash= pathi; + for (;;) { + nextslash= strchr(lastslash+1,'/'); + if (!nextslash) error("insufficient slashes in PATH_INFO beyond directory"); + if (nextslash[1]=='.' || nextslash[1]=='#' || !nextslash[1]) error("bad char begin"); + if (nextslash-pathi > MAX_SCRIPTPATH_LEN) error("PATH_INFO script dir too long"); + scriptpathlen= scriptdirlen+(nextslash-pathi); + scriptpath= xrealloc(scriptpath,scriptpathlen); + memcpy(scriptpath,pathi,scriptpathlen); scriptpath[scriptpathlen]= 0; + if (scriptpath[scriptpathlen-1]=='~') error("bad char end"); + 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"); + lastlash= nextslash; + } + if (setenv("PATH_INFO",nextslash,1)) syserror("setenv PATH_INFO"); + + arguments= xmalloc(sizeof(const char*)*(argc+5)); + nargs= 0; + + arguments[nargs++]= scriptpath; + while ((av= (*++argv))) arguments[nargs++]= av; + arguments[nargs++]= 0; + + execvp(scriptpath,(char*const*)arguments); + syserror("exec script"); + return -1; +}