5 * Copyright 1996-2013 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright 1998 David Damerell <damerell@chiark.greenend.org.uk>
8 * Chancellor Masters and Scholars of the University of Cambridge
9 * Copyright 2010 Tony Finch <fanf@dotat.at>
11 * This is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with userv-utils; if not, see http://www.gnu.org/licenses/.
29 #include <sys/types.h>
34 int main(int argc
, const char **argv
) {
35 char *defarg
, *username
;
36 const char *slash2
, *pathi
, *ev
, *en
, *av
;
37 const char *const *ep
;
38 const char **arguments
;
39 size_t usernamelen
, l
;
44 if (l
>6 && !strcmp(argv
[0]+l
-6,"-debug")) debugmode
= 1;
47 if (fputs("Content-Type: text/plain\n\n",stdout
)==EOF
|| fflush(stdout
))
48 syserror("write stdout");
49 if (dup2(1,2)<0) { perror("dup stdout to stderr"); exit(-1); }
52 if (argc
> MAX_ARGS
) error("too many arguments");
54 pathi
= getenv("PATH_INFO");
55 if (!pathi
) error("PATH_INFO not found");
56 if (pathi
[0] != '/' || pathi
[1] != '~') error("PATH_INFO must start with /~");
57 slash2
= strchr(pathi
+2,'/'); if (!slash2
) error("PATH_INFO must have more than one /");
58 usernamelen
= slash2
-(pathi
+2);
59 if (usernamelen
> MAX_USERNAME_LEN
) error("PATH_INFO username too long");
60 username
= xmalloc(usernamelen
+1);
61 memcpy(username
,pathi
+2,usernamelen
); username
[usernamelen
]= 0;
62 if (!isalpha(username
[0])) error("username 1st character is not alphabetic");
63 xsetenv("PATH_INFO",slash2
,1);
65 arguments
= xmalloc(sizeof(const char*)*(nenvok
+argc
+10));
68 arguments
[nargs
++]= "userv";
69 if (debugmode
) arguments
[nargs
++]= "-DDEBUG=1";
71 for (ep
= envok
; (en
= *ep
); ep
++) {
72 ev
= getenv(en
); if (!ev
) continue;
73 l
= strlen(ev
); if (l
> MAX_ENVVAR_VALUE
) error("environment variable too long");
74 defarg
= xmalloc(strlen(en
)+l
+6);
75 sprintf(defarg
,"-DE_%s=%s",en
,ev
);
76 arguments
[nargs
++]= defarg
;
79 arguments
[nargs
++]= username
;
80 arguments
[nargs
++]= "www-cgi";
81 while ((av
= (*++argv
))) arguments
[nargs
++]= av
;
82 arguments
[nargs
++]= 0;
85 child
= fork(); if (child
==-1) syserror("fork");
87 rchild
= waitpid(child
,&status
,0);
88 if (rchild
==-1) syserror("waitpid");
89 printf("\nexit status %d %d\n",(status
>>8)&0x0ff,status
&0x0ff);
94 execvp("userv",(char*const*)arguments
);
95 syserror("exec userv");