17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier #include "httpd.h"
580ee5cbfSDavid du Colombier #include "httpsrv.h"
67dd7cddfSDavid du Colombier
77dd7cddfSDavid du Colombier static Hio *hout;
8223a736eSDavid du Colombier static Hio houtb;
980ee5cbfSDavid du Colombier static HConnect *connect;
107dd7cddfSDavid du Colombier
11223a736eSDavid du Colombier void doconvert(char*, int);
127dd7cddfSDavid du Colombier
137dd7cddfSDavid du Colombier void
error(char * title,char * fmt,...)147dd7cddfSDavid du Colombier error(char *title, char *fmt, ...)
157dd7cddfSDavid du Colombier {
167dd7cddfSDavid du Colombier va_list arg;
177dd7cddfSDavid du Colombier char buf[1024], *out;
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier va_start(arg, fmt);
209a747e4fSDavid du Colombier out = vseprint(buf, buf+sizeof(buf), fmt, arg);
217dd7cddfSDavid du Colombier va_end(arg);
227dd7cddfSDavid du Colombier *out = 0;
237dd7cddfSDavid du Colombier
2480ee5cbfSDavid du Colombier hprint(hout, "%s 404 %s\n", hversion, title);
257dd7cddfSDavid du Colombier hprint(hout, "Date: %D\n", time(nil));
267dd7cddfSDavid du Colombier hprint(hout, "Server: Plan9\n");
277dd7cddfSDavid du Colombier hprint(hout, "Content-type: text/html\n");
287dd7cddfSDavid du Colombier hprint(hout, "\n");
297dd7cddfSDavid du Colombier hprint(hout, "<head><title>%s</title></head>\n", title);
307dd7cddfSDavid du Colombier hprint(hout, "<body><h1>%s</h1></body>\n", title);
317dd7cddfSDavid du Colombier hprint(hout, "%s\n", buf);
3214414594SDavid du Colombier hflush(hout);
3314414594SDavid du Colombier writelog(connect, "Reply: 404\nReason: %s\n", title);
347dd7cddfSDavid du Colombier exits(nil);
357dd7cddfSDavid du Colombier }
367dd7cddfSDavid du Colombier
377dd7cddfSDavid du Colombier typedef struct Hit Hit;
387dd7cddfSDavid du Colombier struct Hit
397dd7cddfSDavid du Colombier {
407dd7cddfSDavid du Colombier Hit *next;
417dd7cddfSDavid du Colombier char *file;
427dd7cddfSDavid du Colombier };
437dd7cddfSDavid du Colombier
447dd7cddfSDavid du Colombier void
lookup(char * object,int section,Hit ** list)457dd7cddfSDavid du Colombier lookup(char *object, int section, Hit **list)
467dd7cddfSDavid du Colombier {
477dd7cddfSDavid du Colombier int fd;
487dd7cddfSDavid du Colombier char *p, *f;
497dd7cddfSDavid du Colombier Biobuf b;
509a747e4fSDavid du Colombier char file[256];
517dd7cddfSDavid du Colombier Hit *h;
527dd7cddfSDavid du Colombier
537dd7cddfSDavid du Colombier while(*list != nil)
547dd7cddfSDavid du Colombier list = &(*list)->next;
557dd7cddfSDavid du Colombier
567dd7cddfSDavid du Colombier snprint(file, sizeof(file), "/sys/man/%d/INDEX", section);
577dd7cddfSDavid du Colombier fd = open(file, OREAD);
587dd7cddfSDavid du Colombier if(fd > 0){
597dd7cddfSDavid du Colombier Binit(&b, fd, OREAD);
607dd7cddfSDavid du Colombier for(;;){
617dd7cddfSDavid du Colombier p = Brdline(&b, '\n');
627dd7cddfSDavid du Colombier if(p == nil)
637dd7cddfSDavid du Colombier break;
647dd7cddfSDavid du Colombier p[Blinelen(&b)-1] = 0;
657dd7cddfSDavid du Colombier f = strchr(p, ' ');
667dd7cddfSDavid du Colombier if(f == nil)
677dd7cddfSDavid du Colombier continue;
687dd7cddfSDavid du Colombier *f++ = 0;
697dd7cddfSDavid du Colombier if(strcmp(p, object) == 0){
707dd7cddfSDavid du Colombier h = ezalloc(sizeof *h);
717dd7cddfSDavid du Colombier *list = h;
727dd7cddfSDavid du Colombier h->next = nil;
737dd7cddfSDavid du Colombier snprint(file, sizeof(file), "/%d/%s", section, f);
747dd7cddfSDavid du Colombier h->file = estrdup(file);
757dd7cddfSDavid du Colombier close(fd);
767dd7cddfSDavid du Colombier return;
777dd7cddfSDavid du Colombier }
787dd7cddfSDavid du Colombier }
797dd7cddfSDavid du Colombier close(fd);
807dd7cddfSDavid du Colombier }
817dd7cddfSDavid du Colombier snprint(file, sizeof(file), "/sys/man/%d/%s", section, object);
827dd7cddfSDavid du Colombier if(access(file, 0) == 0){
837dd7cddfSDavid du Colombier h = ezalloc(sizeof *h);
847dd7cddfSDavid du Colombier *list = h;
857dd7cddfSDavid du Colombier h->next = nil;
867dd7cddfSDavid du Colombier h->file = estrdup(file+8);
877dd7cddfSDavid du Colombier }
887dd7cddfSDavid du Colombier }
897dd7cddfSDavid du Colombier
907dd7cddfSDavid du Colombier void
manindex(int sect,int vermaj)917dd7cddfSDavid du Colombier manindex(int sect, int vermaj)
927dd7cddfSDavid du Colombier {
937dd7cddfSDavid du Colombier int i;
947dd7cddfSDavid du Colombier
957dd7cddfSDavid du Colombier if(vermaj){
9680ee5cbfSDavid du Colombier hokheaders(connect);
977dd7cddfSDavid du Colombier hprint(hout, "Content-type: text/html\r\n");
987dd7cddfSDavid du Colombier hprint(hout, "\r\n");
997dd7cddfSDavid du Colombier }
1007dd7cddfSDavid du Colombier
1017dd7cddfSDavid du Colombier hprint(hout, "<head><title>plan 9 section index");
1027dd7cddfSDavid du Colombier if(sect)
1037dd7cddfSDavid du Colombier hprint(hout, "(%d)\n", sect);
1047dd7cddfSDavid du Colombier hprint(hout, "</title></head><body>\n");
1057dd7cddfSDavid du Colombier hprint(hout, "<H6>Section Index");
1067dd7cddfSDavid du Colombier if(sect)
1077dd7cddfSDavid du Colombier hprint(hout, "(%d)\n", sect);
1087dd7cddfSDavid du Colombier hprint(hout, "</H6>\n");
1097dd7cddfSDavid du Colombier
1107dd7cddfSDavid du Colombier if(sect)
1117dd7cddfSDavid du Colombier hprint(hout, "<p><a href=\"/plan9/man%d.html\">/plan9/man%d.html</a>\n",
1127dd7cddfSDavid du Colombier sect, sect);
1137dd7cddfSDavid du Colombier else for(i = 1; i < 10; i++)
1147dd7cddfSDavid du Colombier hprint(hout, "<p><a href=\"/plan9/man%d.html\">/plan9/man%d.html</a>\n",
1157dd7cddfSDavid du Colombier i, i);
1167dd7cddfSDavid du Colombier hprint(hout, "</body>\n");
1177dd7cddfSDavid du Colombier }
1187dd7cddfSDavid du Colombier
1197dd7cddfSDavid du Colombier void
man(char * o,int sect,int vermaj)1207dd7cddfSDavid du Colombier man(char *o, int sect, int vermaj)
1217dd7cddfSDavid du Colombier {
1227dd7cddfSDavid du Colombier int i;
1237dd7cddfSDavid du Colombier Hit *list;
1247dd7cddfSDavid du Colombier
1257dd7cddfSDavid du Colombier list = nil;
1267dd7cddfSDavid du Colombier
1277dd7cddfSDavid du Colombier if(*o == 0){
1287dd7cddfSDavid du Colombier manindex(sect, vermaj);
1297dd7cddfSDavid du Colombier return;
1307dd7cddfSDavid du Colombier }
1317dd7cddfSDavid du Colombier
1327dd7cddfSDavid du Colombier if(sect > 0 && sect < 10)
1337dd7cddfSDavid du Colombier lookup(o, sect, &list);
1347dd7cddfSDavid du Colombier else
1357dd7cddfSDavid du Colombier for(i = 1; i < 9; i++)
1367dd7cddfSDavid du Colombier lookup(o, i, &list);
1377dd7cddfSDavid du Colombier
1387dd7cddfSDavid du Colombier if(list != nil && list->next == nil){
139223a736eSDavid du Colombier doconvert(list->file, vermaj);
1407dd7cddfSDavid du Colombier return;
1417dd7cddfSDavid du Colombier }
1427dd7cddfSDavid du Colombier
1437dd7cddfSDavid du Colombier if(vermaj){
14480ee5cbfSDavid du Colombier hokheaders(connect);
1457dd7cddfSDavid du Colombier hprint(hout, "Content-type: text/html\r\n");
1467dd7cddfSDavid du Colombier hprint(hout, "\r\n");
1477dd7cddfSDavid du Colombier }
1487dd7cddfSDavid du Colombier
1497dd7cddfSDavid du Colombier hprint(hout, "<head><title>plan 9 man %H", o);
1507dd7cddfSDavid du Colombier if(sect)
1517dd7cddfSDavid du Colombier hprint(hout, "(%d)\n", sect);
1527dd7cddfSDavid du Colombier hprint(hout, "</title></head><body>\n");
1537dd7cddfSDavid du Colombier hprint(hout, "<H6>Search for %H", o);
1547dd7cddfSDavid du Colombier if(sect)
1557dd7cddfSDavid du Colombier hprint(hout, "(%d)\n", sect);
1567dd7cddfSDavid du Colombier hprint(hout, "</H6>\n");
1577dd7cddfSDavid du Colombier
1587dd7cddfSDavid du Colombier for(; list; list = list->next)
1597dd7cddfSDavid du Colombier hprint(hout, "<p><a href=\"/magic/man2html%U\">/magic/man2html%H</a>\n",
1607dd7cddfSDavid du Colombier list->file, list->file);
1617dd7cddfSDavid du Colombier hprint(hout, "</body>\n");
1627dd7cddfSDavid du Colombier }
1637dd7cddfSDavid du Colombier
1647dd7cddfSDavid du Colombier void
strlwr(char * p)165*0b9a5132SDavid du Colombier strlwr(char *p)
166*0b9a5132SDavid du Colombier {
167*0b9a5132SDavid du Colombier for(; *p; p++)
168*0b9a5132SDavid du Colombier if('A' <= *p && *p <= 'Z')
169*0b9a5132SDavid du Colombier *p += 'a'-'A';
170*0b9a5132SDavid du Colombier }
171*0b9a5132SDavid du Colombier
172*0b9a5132SDavid du Colombier void
redirectto(char * uri)1737dd7cddfSDavid du Colombier redirectto(char *uri)
1747dd7cddfSDavid du Colombier {
17580ee5cbfSDavid du Colombier if(connect){
17680ee5cbfSDavid du Colombier hmoved(connect, uri);
17780ee5cbfSDavid du Colombier exits(0);
17880ee5cbfSDavid du Colombier }else
1797dd7cddfSDavid du Colombier hprint(hout, "Your selection moved to <a href=\"%U\"> here</a>.<p></body>\r\n", uri);
1807dd7cddfSDavid du Colombier }
1817dd7cddfSDavid du Colombier
1827dd7cddfSDavid du Colombier void
searchfor(char * search)1837dd7cddfSDavid du Colombier searchfor(char *search)
1847dd7cddfSDavid du Colombier {
1857dd7cddfSDavid du Colombier int i, j, n, fd;
1867dd7cddfSDavid du Colombier char *p, *sp;
1877dd7cddfSDavid du Colombier Biobufhdr *b;
1887dd7cddfSDavid du Colombier char *arg[32];
1897dd7cddfSDavid du Colombier
1907dd7cddfSDavid du Colombier hprint(hout, "<head><title>plan 9 search for %H</title></head>\n", search);
1917dd7cddfSDavid du Colombier hprint(hout, "<body>\n");
1927dd7cddfSDavid du Colombier
1937dd7cddfSDavid du Colombier hprint(hout, "<p>This is a keyword search through Plan 9 man pages.\n");
1947dd7cddfSDavid du Colombier hprint(hout, "The search is case insensitive; blanks denote \"boolean and\".\n");
1957dd7cddfSDavid du Colombier hprint(hout, "<FORM METHOD=\"GET\" ACTION=\"/magic/man2html\">\n");
1967dd7cddfSDavid du Colombier hprint(hout, "<INPUT NAME=\"pat\" TYPE=\"text\" SIZE=\"60\">\n");
1977dd7cddfSDavid du Colombier hprint(hout, "<INPUT TYPE=\"submit\" VALUE=\"Submit\">\n");
1987dd7cddfSDavid du Colombier hprint(hout, "</FORM>\n");
1997dd7cddfSDavid du Colombier
2007dd7cddfSDavid du Colombier hprint(hout, "<hr><H6>Search for %H</H6>\n", search);
2017dd7cddfSDavid du Colombier n = getfields(search, arg, 32, 1, "+");
2027dd7cddfSDavid du Colombier for(i = 0; i < n; i++){
2037dd7cddfSDavid du Colombier for(j = i+1; j < n; j++){
2047dd7cddfSDavid du Colombier if(strcmp(arg[i], arg[j]) > 0){
2057dd7cddfSDavid du Colombier sp = arg[j];
2067dd7cddfSDavid du Colombier arg[j] = arg[i];
2077dd7cddfSDavid du Colombier arg[i] = sp;
2087dd7cddfSDavid du Colombier }
2097dd7cddfSDavid du Colombier }
2107dd7cddfSDavid du Colombier sp = malloc(strlen(arg[i]) + 2);
2117dd7cddfSDavid du Colombier if(sp != nil){
2127dd7cddfSDavid du Colombier strcpy(sp+1, arg[i]);
2137dd7cddfSDavid du Colombier sp[0] = ' ';
2147dd7cddfSDavid du Colombier arg[i] = sp;
2157dd7cddfSDavid du Colombier }
2167dd7cddfSDavid du Colombier }
2177dd7cddfSDavid du Colombier
2187dd7cddfSDavid du Colombier /*
2197dd7cddfSDavid du Colombier * search index till line starts alphabetically < first token
2207dd7cddfSDavid du Colombier */
2217dd7cddfSDavid du Colombier fd = open("/sys/man/searchindex", OREAD);
2227dd7cddfSDavid du Colombier if(fd < 0){
2237dd7cddfSDavid du Colombier hprint(hout, "<body>error: No Plan 9 search index\n");
2247dd7cddfSDavid du Colombier hprint(hout, "</body>");
2257dd7cddfSDavid du Colombier return;
2267dd7cddfSDavid du Colombier }
2277dd7cddfSDavid du Colombier p = malloc(32*1024);
2287dd7cddfSDavid du Colombier if(p == nil){
2297dd7cddfSDavid du Colombier close(fd);
2307dd7cddfSDavid du Colombier return;
2317dd7cddfSDavid du Colombier }
2327dd7cddfSDavid du Colombier b = ezalloc(sizeof *b);
2337dd7cddfSDavid du Colombier Binits(b, fd, OREAD, (uchar*)p, 32*1024);
2347dd7cddfSDavid du Colombier for(;;){
2357dd7cddfSDavid du Colombier p = Brdline(b, '\n');
2367dd7cddfSDavid du Colombier if(p == nil)
2377dd7cddfSDavid du Colombier break;
2387dd7cddfSDavid du Colombier p[Blinelen(b)-1] = 0;
2397dd7cddfSDavid du Colombier for(i = 0; i < n; i++){
2407dd7cddfSDavid du Colombier sp = strstr(p, arg[i]);
2417dd7cddfSDavid du Colombier if(sp == nil)
2427dd7cddfSDavid du Colombier break;
2437dd7cddfSDavid du Colombier p = sp;
2447dd7cddfSDavid du Colombier }
2457dd7cddfSDavid du Colombier if(i < n)
2467dd7cddfSDavid du Colombier continue;
2477dd7cddfSDavid du Colombier sp = strrchr(p, '\t');
2487dd7cddfSDavid du Colombier if(sp == nil)
2497dd7cddfSDavid du Colombier continue;
2507dd7cddfSDavid du Colombier sp++;
2517dd7cddfSDavid du Colombier hprint(hout, "<p><a href=\"/magic/man2html/%U\">/magic/man2html/%H</a>\n",
2527dd7cddfSDavid du Colombier sp, sp);
2537dd7cddfSDavid du Colombier }
2547dd7cddfSDavid du Colombier hprint(hout, "</body>");
2557dd7cddfSDavid du Colombier
2567dd7cddfSDavid du Colombier Bterm(b);
2577dd7cddfSDavid du Colombier free(b);
2587dd7cddfSDavid du Colombier free(p);
2597dd7cddfSDavid du Colombier close(fd);
2607dd7cddfSDavid du Colombier }
2617dd7cddfSDavid du Colombier
2627dd7cddfSDavid du Colombier /*
2637dd7cddfSDavid du Colombier * find man pages mentioning the search string
2647dd7cddfSDavid du Colombier */
2657dd7cddfSDavid du Colombier void
dosearch(int vermaj,char * search)2667dd7cddfSDavid du Colombier dosearch(int vermaj, char *search)
2677dd7cddfSDavid du Colombier {
2687dd7cddfSDavid du Colombier int sect;
2697dd7cddfSDavid du Colombier char *p;
2707dd7cddfSDavid du Colombier
2717dd7cddfSDavid du Colombier if(strncmp(search, "man=", 4) == 0){
2727dd7cddfSDavid du Colombier sect = 0;
27380ee5cbfSDavid du Colombier search = hurlunesc(connect, search+4);
2747dd7cddfSDavid du Colombier p = strchr(search, '&');
2757dd7cddfSDavid du Colombier if(p != nil){
2767dd7cddfSDavid du Colombier *p++ = 0;
2777dd7cddfSDavid du Colombier if(strncmp(p, "sect=", 5) == 0)
2787dd7cddfSDavid du Colombier sect = atoi(p+5);
2797dd7cddfSDavid du Colombier }
2807dd7cddfSDavid du Colombier man(search, sect, vermaj);
2817dd7cddfSDavid du Colombier return;
2827dd7cddfSDavid du Colombier }
2837dd7cddfSDavid du Colombier
2847dd7cddfSDavid du Colombier if(vermaj){
28580ee5cbfSDavid du Colombier hokheaders(connect);
2867dd7cddfSDavid du Colombier hprint(hout, "Content-type: text/html\r\n");
2877dd7cddfSDavid du Colombier hprint(hout, "\r\n");
2887dd7cddfSDavid du Colombier }
2897dd7cddfSDavid du Colombier
2907dd7cddfSDavid du Colombier if(strncmp(search, "pat=", 4) == 0){
29180ee5cbfSDavid du Colombier search = hurlunesc(connect, search+4);
29280ee5cbfSDavid du Colombier search = hlower(search);
2937dd7cddfSDavid du Colombier searchfor(search);
2947dd7cddfSDavid du Colombier return;
2957dd7cddfSDavid du Colombier }
2967dd7cddfSDavid du Colombier
2977dd7cddfSDavid du Colombier hprint(hout, "<head><title>illegal search</title></head>\n");
2987dd7cddfSDavid du Colombier hprint(hout, "<body><p>Illegally formatted Plan 9 man page search</p>\n");
29980ee5cbfSDavid du Colombier search = hurlunesc(connect, search);
3007dd7cddfSDavid du Colombier hprint(hout, "<body><p>%H</p>\n", search);
3017dd7cddfSDavid du Colombier hprint(hout, "</body>");
3027dd7cddfSDavid du Colombier }
3037dd7cddfSDavid du Colombier
3047dd7cddfSDavid du Colombier /*
3057dd7cddfSDavid du Colombier * convert a man page to html and output
3067dd7cddfSDavid du Colombier */
3077dd7cddfSDavid du Colombier void
doconvert(char * uri,int vermaj)308223a736eSDavid du Colombier doconvert(char *uri, int vermaj)
3097dd7cddfSDavid du Colombier {
310223a736eSDavid du Colombier char *p;
3117dd7cddfSDavid du Colombier char file[256];
312223a736eSDavid du Colombier char title[256];
3139a747e4fSDavid du Colombier char err[ERRMAX];
314223a736eSDavid du Colombier int pfd[2];
3159a747e4fSDavid du Colombier Dir *d;
3169a747e4fSDavid du Colombier Waitmsg *w;
317223a736eSDavid du Colombier int x;
3187dd7cddfSDavid du Colombier
3197dd7cddfSDavid du Colombier if(strstr(uri, ".."))
3207dd7cddfSDavid du Colombier error("bad URI", "man page URI cannot contain ..");
3217dd7cddfSDavid du Colombier p = strstr(uri, "/intro");
322223a736eSDavid du Colombier
3237dd7cddfSDavid du Colombier if(p == nil){
324*0b9a5132SDavid du Colombier while(*uri == '/')
325*0b9a5132SDavid du Colombier uri++;
326223a736eSDavid du Colombier /* redirect section requests */
3277dd7cddfSDavid du Colombier snprint(file, sizeof(file), "/sys/man/%s", uri);
3289a747e4fSDavid du Colombier d = dirstat(file);
329*0b9a5132SDavid du Colombier if(d == nil){
330*0b9a5132SDavid du Colombier strlwr(file);
331*0b9a5132SDavid du Colombier if(dirstat(file) != nil){
332*0b9a5132SDavid du Colombier snprint(file, sizeof(file), "/magic/man2html/%s", uri);
333*0b9a5132SDavid du Colombier strlwr(file);
334*0b9a5132SDavid du Colombier redirectto(file);
335*0b9a5132SDavid du Colombier }
336223a736eSDavid du Colombier error(uri, "man page not found");
337*0b9a5132SDavid du Colombier }
3389a747e4fSDavid du Colombier x = d->qid.type;
3399a747e4fSDavid du Colombier free(d);
3409a747e4fSDavid du Colombier if(x & QTDIR){
3417dd7cddfSDavid du Colombier if(*uri == 0 || strcmp(uri, "/") == 0)
342223a736eSDavid du Colombier redirectto("/sys/man/index.html");
3437dd7cddfSDavid du Colombier else {
344223a736eSDavid du Colombier snprint(file, sizeof(file), "/sys/man/%s/INDEX.html",
3457dd7cddfSDavid du Colombier uri+1);
3467dd7cddfSDavid du Colombier redirectto(file);
3477dd7cddfSDavid du Colombier }
3487dd7cddfSDavid du Colombier return;
3497dd7cddfSDavid du Colombier }
3507dd7cddfSDavid du Colombier } else {
351223a736eSDavid du Colombier /* rewrite the name intro */
3527dd7cddfSDavid du Colombier *p = 0;
3537dd7cddfSDavid du Colombier snprint(file, sizeof(file), "/sys/man/%s/0intro", uri);
3549a747e4fSDavid du Colombier d = dirstat(file);
3559a747e4fSDavid du Colombier free(d);
3569a747e4fSDavid du Colombier if(d == nil)
357223a736eSDavid du Colombier error(uri, "man page not found");
3587dd7cddfSDavid du Colombier }
3597dd7cddfSDavid du Colombier
3607dd7cddfSDavid du Colombier if(vermaj){
36180ee5cbfSDavid du Colombier hokheaders(connect);
3627dd7cddfSDavid du Colombier hprint(hout, "Content-type: text/html\r\n");
3637dd7cddfSDavid du Colombier hprint(hout, "\r\n");
3647dd7cddfSDavid du Colombier }
365223a736eSDavid du Colombier hflush(hout);
3667dd7cddfSDavid du Colombier
367223a736eSDavid du Colombier if(pipe(pfd) < 0)
368223a736eSDavid du Colombier error("out of resources", "pipe failed");
369223a736eSDavid du Colombier
370223a736eSDavid du Colombier /* troff -manhtml <file> | troff2html -t '' */
371223a736eSDavid du Colombier switch(fork()){
372223a736eSDavid du Colombier case -1:
373223a736eSDavid du Colombier error("out of resources", "fork failed");
374223a736eSDavid du Colombier case 0:
375223a736eSDavid du Colombier snprint(title, sizeof(title), "Plan 9 %s", file);
376223a736eSDavid du Colombier close(0);
377223a736eSDavid du Colombier dup(pfd[0], 0);
378223a736eSDavid du Colombier close(pfd[0]);
379223a736eSDavid du Colombier close(pfd[1]);
380f19e7b74SDavid du Colombier execl("/bin/troff2html", "troff2html", "-t", title, nil);
3819a747e4fSDavid du Colombier errstr(err, sizeof err);
382223a736eSDavid du Colombier exits(err);
3837dd7cddfSDavid du Colombier }
384223a736eSDavid du Colombier switch(fork()){
385223a736eSDavid du Colombier case -1:
386223a736eSDavid du Colombier error("out of resources", "fork failed");
387223a736eSDavid du Colombier case 0:
388223a736eSDavid du Colombier snprint(title, sizeof(title), "Plan 9 %s", file);
389223a736eSDavid du Colombier close(0);
390223a736eSDavid du Colombier close(1);
391223a736eSDavid du Colombier dup(pfd[1], 1);
392223a736eSDavid du Colombier close(pfd[0]);
393223a736eSDavid du Colombier close(pfd[1]);
394f19e7b74SDavid du Colombier execl("/bin/troff", "troff", "-manhtml", file, nil);
3959a747e4fSDavid du Colombier errstr(err, sizeof err);
396223a736eSDavid du Colombier exits(err);
397223a736eSDavid du Colombier }
398223a736eSDavid du Colombier close(pfd[0]);
399223a736eSDavid du Colombier close(pfd[1]);
4007dd7cddfSDavid du Colombier
401223a736eSDavid du Colombier /* wait for completion */
4027dd7cddfSDavid du Colombier for(;;){
4039a747e4fSDavid du Colombier w = wait();
4049a747e4fSDavid du Colombier if(w == nil)
4057dd7cddfSDavid du Colombier break;
4069a747e4fSDavid du Colombier if(w->msg[0] != 0)
4079a747e4fSDavid du Colombier print("whoops %s\n", w->msg);
4089a747e4fSDavid du Colombier free(w);
4097dd7cddfSDavid du Colombier }
4107dd7cddfSDavid du Colombier }
4117dd7cddfSDavid du Colombier
4127dd7cddfSDavid du Colombier void
main(int argc,char ** argv)4137dd7cddfSDavid du Colombier main(int argc, char **argv)
4147dd7cddfSDavid du Colombier {
4159a747e4fSDavid du Colombier fmtinstall('H', httpfmt);
4169a747e4fSDavid du Colombier fmtinstall('U', hurlfmt);
417223a736eSDavid du Colombier
418223a736eSDavid du Colombier if(argc == 2){
4197dd7cddfSDavid du Colombier hinit(&houtb, 1, Hwrite);
4207dd7cddfSDavid du Colombier hout = &houtb;
421223a736eSDavid du Colombier doconvert(argv[1], 0);
4227dd7cddfSDavid du Colombier exits(nil);
4237dd7cddfSDavid du Colombier }
4247dd7cddfSDavid du Colombier close(2);
4257dd7cddfSDavid du Colombier
4267dd7cddfSDavid du Colombier connect = init(argc, argv);
4277dd7cddfSDavid du Colombier hout = &connect->hout;
42880ee5cbfSDavid du Colombier if(hparseheaders(connect, HSTIMEOUT) < 0)
42980ee5cbfSDavid du Colombier exits("failed");
4307dd7cddfSDavid du Colombier
43180ee5cbfSDavid du Colombier if(strcmp(connect->req.meth, "GET") != 0 && strcmp(connect->req.meth, "HEAD") != 0){
43280ee5cbfSDavid du Colombier hunallowed(connect, "GET, HEAD");
43380ee5cbfSDavid du Colombier exits("not allowed");
43480ee5cbfSDavid du Colombier }
43580ee5cbfSDavid du Colombier if(connect->head.expectother || connect->head.expectcont){
43680ee5cbfSDavid du Colombier hfail(connect, HExpectFail, nil);
43780ee5cbfSDavid du Colombier exits("failed");
43880ee5cbfSDavid du Colombier }
4397dd7cddfSDavid du Colombier
44080ee5cbfSDavid du Colombier bind("/usr/web/sys/man", "/sys/man", MREPL);
4417dd7cddfSDavid du Colombier
4427dd7cddfSDavid du Colombier if(connect->req.search != nil)
4437dd7cddfSDavid du Colombier dosearch(connect->req.vermaj, connect->req.search);
4447dd7cddfSDavid du Colombier else
445223a736eSDavid du Colombier doconvert(connect->req.uri, connect->req.vermaj);
44614414594SDavid du Colombier hflush(hout);
44714414594SDavid du Colombier writelog(connect, "200 man2html %ld %ld\n", hout->seek, hout->seek);
4487dd7cddfSDavid du Colombier exits(nil);
4497dd7cddfSDavid du Colombier }
450