* $Id: ucgi.c,v 1.3 2003/07/06 20:47:12 ian Exp $
*/
+#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
+#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <cdb.h>
#include "ucgi.h"
+int conf = -1;
+
+static char *lookup(int prefix, const char *label, int len)
+{
+ char *p = 0;
+ unsigned nn;
+ int rc;
+
+ if (conf < 0 || !label) return (0);
+ if (len < 0) len = strlen(label);
+ p = xmalloc(len + 2);
+ p[0] = prefix;
+ memcpy(p + 1, label, len);
+ p[len + 1] = 0;
+ if ((rc = cdb_seek(conf, p, len + 1, &nn)) < 0)
+ error("error seeking in `" CONFIG_CDB "'");
+ free(p);
+ if (!rc) return (0);
+ p = xmalloc(nn + 1);
+ if (read(conf, p, nn) < nn)
+ error("error reading `" CONFIG_CDB "'");
+ p[nn] = 0;
+ return (p);
+}
+
int main(int argc, const char **argv) {
char *defarg, *username;
const char *slash2, *pathi, *ev, *en, *av;
if (argc > MAX_ARGS) error("too many arguments");
+ if ((conf = open(CONFIG_CDB, O_RDONLY)) < 0 && errno != ENOENT)
+ error("failed to open `" CONFIG_CDB "'");
+
pathi= getenv("PATH_INFO");
if (!pathi) error("PATH_INFO not found");
- if (pathi[0] != '/' || pathi[1] != '~') error("PATH_INFO must start with /~");
- slash2= strchr(pathi+2,'/'); 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,usernamelen); username[usernamelen]= 0;
+ if (pathi[0] != '/') error("PATH_INFO must start with /");
+ if ((username = lookup('H', getenv("HTTP_HOST"), -1)) != 0)
+ /* cool! */;
+ else if (pathi[1] == '~') {
+ slash2= strchr(pathi+2,'/'); 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,usernamelen); username[usernamelen]= 0;
+ xsetenv("PATH_INFO",slash2,1);
+ } else {
+ slash2 = strchr(pathi+1,'/');
+ if ((username = lookup('S', pathi + 1,
+ slash2 ? slash2 - pathi - 1 : -1)) == 0)
+ error("unknown CGI service");
+ }
+
if (!isalpha(username[0])) error("username 1st character is not alphabetic");
- xsetenv("PATH_INFO",slash2,1);
-
arguments= xmalloc(sizeof(const char*)*(nenvok+argc+10));
nargs= 0;