14 int main(int argc
, const char **argv
) {
15 char *defarg
, *username
;
16 const char *slash2
, *pathi
, *ev
, *en
, *av
;
17 const char *const *ep
;
18 const char **arguments
;
19 size_t usernamelen
, l
;
24 if (l
>6 && !strcmp(argv
[0]+l
-6,"-debug")) debugmode
= 1;
27 if (fputs("Content-Type: text/plain\n\n",stdout
)==EOF
|| fflush(stdout
))
28 syserror("write stdout");
29 if (dup2(1,2)<0) { perror("dup stdout to stderr"); exit(-1); }
32 if (argc
> MAX_ARGS
) error("too many arguments");
34 pathi
= getenv("PATH_INFO");
35 if (!pathi
) error("PATH_INFO not found");
36 if (pathi
[0] != '/' || pathi
[1] != '~') error("PATH_INFO must start with /~");
37 slash2
= strchr(pathi
+2,'/'); if (!slash2
) error("PATH_INFO must have more than one /");
38 usernamelen
= slash2
-(pathi
+2);
39 if (usernamelen
> MAX_USERNAME_LEN
) error("PATH_INFO username too long");
40 username
= xmalloc(usernamelen
+1);
41 memcpy(username
,pathi
+2,usernamelen
); username
[usernamelen
]= 0;
42 if (!isalpha(username
[0])) error("username 1st character is not alphabetic");
43 xsetenv("PATH_INFO",slash2
,1);
45 arguments
= xmalloc(sizeof(const char*)*(nenvok
+argc
+10));
48 arguments
[nargs
++]= "userv";
49 if (debugmode
) arguments
[nargs
++]= "-DDEBUG=1";
51 for (ep
= envok
; (en
= *ep
); ep
++) {
52 ev
= getenv(en
); if (!ev
) continue;
53 l
= strlen(ev
); if (l
> MAX_ENVVAR_VALUE
) error("environment variable too long");
54 defarg
= xmalloc(strlen(en
)+l
+6);
55 sprintf(defarg
,"-DE_%s=%s",en
,ev
);
56 arguments
[nargs
++]= defarg
;
59 arguments
[nargs
++]= username
;
60 arguments
[nargs
++]= "www-cgi";
61 while ((av
= (*++argv
))) arguments
[nargs
++]= av
;
62 arguments
[nargs
++]= 0;
65 child
= fork(); if (child
==-1) syserror("fork");
67 rchild
= waitpid(child
,&status
,0);
68 if (rchild
==-1) syserror("waitpid");
69 printf("\nexit status %d %d\n",(status
>>8)&0x0ff,status
&0x0ff);
74 execvp("userv",(char*const*)arguments
);
75 syserror("exec userv");