#include /plan9/man%d.html\n",
sect, sect);
else for(i = 1; i < 10; i++)
hprint(hout, " /plan9/man%d.html\n",
i, i);
hprint(hout, "\n");
}
void
man(char *o, int sect, int vermaj)
{
int i;
Hit *list;
list = nil;
if(*o == 0){
manindex(sect, vermaj);
return;
}
if(sect > 0 && sect < 10)
lookup(o, sect, &list);
else
for(i = 1; i < 9; i++)
lookup(o, i, &list);
if(list != nil && list->next == nil){
doconvert(list->file, vermaj);
return;
}
if(vermaj){
hokheaders(connect);
hprint(hout, "Content-type: text/html\r\n");
hprint(hout, "\r\n");
}
hprint(hout, " /magic/man2html%H\n",
list->file, list->file);
hprint(hout, "\n");
}
void
strlwr(char *p)
{
for(; *p; p++)
if('A' <= *p && *p <= 'Z')
*p += 'a'-'A';
}
void
redirectto(char *uri)
{
if(connect){
hmoved(connect, uri);
exits(0);
}else
hprint(hout, "Your selection moved to here.%s
\n", title);
hprint(hout, "%s\n", buf);
hflush(hout);
writelog(connect, "Reply: 404\nReason: %s\n", title);
exits(nil);
}
typedef struct Hit Hit;
struct Hit
{
Hit *next;
char *file;
};
void
lookup(char *object, int section, Hit **list)
{
int fd;
char *p, *f;
Biobuf b;
char file[256];
Hit *h;
while(*list != nil)
list = &(*list)->next;
snprint(file, sizeof(file), "/sys/man/%d/INDEX", section);
fd = open(file, OREAD);
if(fd > 0){
Binit(&b, fd, OREAD);
for(;;){
p = Brdline(&b, '\n');
if(p == nil)
break;
p[Blinelen(&b)-1] = 0;
f = strchr(p, ' ');
if(f == nil)
continue;
*f++ = 0;
if(strcmp(p, object) == 0){
h = ezalloc(sizeof *h);
*list = h;
h->next = nil;
snprint(file, sizeof(file), "/%d/%s", section, f);
h->file = estrdup(file);
close(fd);
return;
}
}
close(fd);
}
snprint(file, sizeof(file), "/sys/man/%d/%s", section, object);
if(access(file, 0) == 0){
h = ezalloc(sizeof *h);
*list = h;
h->next = nil;
h->file = estrdup(file+8);
}
}
void
manindex(int sect, int vermaj)
{
int i;
if(vermaj){
hokheaders(connect);
hprint(hout, "Content-type: text/html\r\n");
hprint(hout, "\r\n");
}
hprint(hout, "Section Index");
if(sect)
hprint(hout, "(%d)\n", sect);
hprint(hout, "
\n");
if(sect)
hprint(hout, "Search for %H", o);
if(sect)
hprint(hout, "(%d)\n", sect);
hprint(hout, "
\n");
for(; list; list = list->next)
hprint(hout, "
This is a keyword search through Plan 9 man pages.\n"); hprint(hout, "The search is case insensitive; blanks denote \"boolean and\".\n"); hprint(hout, "
\n"); hprint(hout, "%H(%H)\n", sp, page, sect); } hprint(hout, "
Illegally formatted Plan 9 man page search
\n"); search = hurlunesc(connect, search); hprint(hout, "%H
\n", search); hprint(hout, ""); } /* * convert a man page to html and output */ void doconvert(char *uri, int vermaj) { char *p; char file[256]; char title[256]; char err[ERRMAX]; int pfd[2]; Dir *d; Waitmsg *w; int x; if(strstr(uri, "..")) error("bad URI", "man page URI cannot contain .."); p = strstr(uri, "/intro"); if(p == nil){ while(*uri == '/') uri++; /* redirect section requests */ snprint(file, sizeof(file), "/sys/man/%s", uri); d = dirstat(file); if(d == nil){ strlwr(file); if(dirstat(file) != nil){ snprint(file, sizeof(file), "/magic/man2html/%s", uri); strlwr(file); redirectto(file); } error(uri, "man page not found"); } x = d->qid.type; free(d); if(x & QTDIR){ if(*uri == 0 || strcmp(uri, "/") == 0) redirectto("/sys/man/index.html"); else { snprint(file, sizeof(file), "/sys/man/%s/INDEX.html", uri+1); redirectto(file); } return; } } else { /* rewrite the name intro */ *p = 0; snprint(file, sizeof(file), "/sys/man/%s/0intro", uri); d = dirstat(file); free(d); if(d == nil) error(uri, "man page not found"); } if(vermaj){ hokheaders(connect); hprint(hout, "Content-type: text/html\r\n"); hprint(hout, "\r\n"); } hflush(hout); if(pipe(pfd) < 0) error("out of resources", "pipe failed"); /* troff -manhtml\r\n", uri); } int crackpath(char *s, char *page, int npage, char *sect, int nsect) { char *p; *page = 0; *sect = 0; p = strchr(s, '/'); if(p == nil) return -1; snprint(page, npage, "%s", p+1); snprint(sect, nsect, "%.*s", (int)(p-s), s); return 0; } void searchfor(char *search) { int i, j, n, fd; char *p, *sp; Biobufhdr *b; char *arg[32], page[32], sect[32]; hprint(hout, "\n"); hprint(hout, "\n"); hprint(hout, "\n"); hprint(hout, "
\n", search); hprint(hout, ""); hprint(hout, "\n"); hprint(hout, "
"); Bterm(b); free(b); free(p); close(fd); } /* * find man pages mentioning the search string */ void dosearch(int vermaj, char *search) { int sect; char *p; if(strncmp(search, "man=", 4) == 0){ sect = 0; search = hurlunesc(connect, search+4); p = strchr(search, '&'); if(p != nil){ *p++ = 0; if(strncmp(p, "sect=", 5) == 0) sect = atoi(p+5); } man(search, sect, vermaj); return; } if(vermaj){ hokheaders(connect); hprint(hout, "Content-type: text/html\r\n"); hprint(hout, "\r\n"); } if(strncmp(search, "pat=", 4) == 0){ search = hurlunesc(connect, search+4); search = hlower(search); searchfor(search); return; } hprint(hout, "
\n"); hprint(hout, "