version 1.26, 2011/12/10 22:45:47 |
version 1.32, 2011/12/15 12:05:19 |
|
|
}; |
}; |
|
|
static int atou(const char *, unsigned *); |
static int atou(const char *, unsigned *); |
static void catman(const char *); |
static void catman(const struct req *, const char *); |
static int cmp(const void *, const void *); |
static int cmp(const void *, const void *); |
static void format(const char *); |
static void format(const struct req *, const char *); |
static void html_print(const char *); |
static void html_print(const char *); |
static void html_putchar(char); |
static void html_putchar(char); |
static int http_decode(char *); |
static int http_decode(char *); |
Line 103 static void resp_index(const struct req *); |
|
Line 103 static void resp_index(const struct req *); |
|
static void resp_search(struct res *, size_t, void *); |
static void resp_search(struct res *, size_t, void *); |
static void resp_searchform(const struct req *); |
static void resp_searchform(const struct req *); |
|
|
static const char *progname; |
static const char *progname; /* cgi script name */ |
static const char *cache; |
static const char *cache; /* cache directory */ |
static const char *host; |
static const char *css; /* css directory */ |
|
static const char *host; /* hostname */ |
|
|
static const char * const pages[PAGE__MAX] = { |
static const char * const pages[PAGE__MAX] = { |
"index", /* PAGE_INDEX */ |
"index", /* PAGE_INDEX */ |
Line 338 resp_begin_html(int code, const char *msg) |
|
Line 339 resp_begin_html(int code, const char *msg) |
|
|
|
resp_begin_http(code, msg); |
resp_begin_http(code, msg); |
|
|
puts("<!DOCTYPE HTML PUBLIC " |
printf("<!DOCTYPE HTML PUBLIC " |
" \"-//W3C//DTD HTML 4.01//EN\"" |
" \"-//W3C//DTD HTML 4.01//EN\"" |
" \"http://www.w3.org/TR/html4/strict.dtd\">\n" |
" \"http://www.w3.org/TR/html4/strict.dtd\">\n" |
"<HTML>\n" |
"<HTML>\n" |
"<HEAD>\n" |
"<HEAD>\n" |
"<META HTTP-EQUIV=\"Content-Type\"" |
"<META HTTP-EQUIV=\"Content-Type\"" |
" CONTENT=\"text/html; charset=utf-8\">\n" |
" CONTENT=\"text/html; charset=utf-8\">\n" |
"<LINK REL=\"stylesheet\" HREF=\"/man.cgi.css\"" |
"<LINK REL=\"stylesheet\" HREF=\"%s/man-cgi.css\"" |
" TYPE=\"text/css\" media=\"all\">\n" |
" TYPE=\"text/css\" media=\"all\">\n" |
"<TITLE>System Manpage Reference</TITLE>\n" |
"<LINK REL=\"stylesheet\" HREF=\"%s/man.css\"" |
"</HEAD>\n" |
" TYPE=\"text/css\" media=\"all\">\n" |
"<BODY>\n" |
"<TITLE>System Manpage Reference</TITLE>\n" |
"<!-- Begin page content. //-->"); |
"</HEAD>\n" |
|
"<BODY>\n" |
|
"<!-- Begin page content. //-->\n", css, css); |
} |
} |
|
|
static void |
static void |
Line 364 resp_end_html(void) |
|
Line 367 resp_end_html(void) |
|
static void |
static void |
resp_searchform(const struct req *req) |
resp_searchform(const struct req *req) |
{ |
{ |
|
int i; |
|
|
puts("<!-- Begin search form. //-->"); |
puts("<!-- Begin search form. //-->"); |
printf("<FORM ACTION=\""); |
printf("<DIV ID=\"mancgi\">\n" |
html_print(progname); |
"<FORM ACTION=\"%s/search.html\" METHOD=\"get\">\n" |
printf("/search.html\" METHOD=\"get\">\n"); |
"<FIELDSET>\n" |
printf("<FIELDSET>\n" |
|
"<LEGEND>Search Parameters</LEGEND>\n" |
"<LEGEND>Search Parameters</LEGEND>\n" |
"<INPUT TYPE=\"submit\" NAME=\"op\"" |
"<INPUT TYPE=\"submit\" NAME=\"op\"" |
" VALUE=\"Whatis\"> or \n" |
" VALUE=\"Whatis\"> or \n" |
"<INPUT TYPE=\"submit\" NAME=\"op\"" |
"<INPUT TYPE=\"submit\" NAME=\"op\"" |
" VALUE=\"apropos\"> for manuals satisfying \n" |
" VALUE=\"apropos\"> for manuals satisfying \n" |
"<INPUT TYPE=\"text\" NAME=\"expr\" VALUE=\""); |
"<INPUT TYPE=\"text\" NAME=\"expr\" VALUE=\"", |
|
progname); |
html_print(req->q.expr ? req->q.expr : ""); |
html_print(req->q.expr ? req->q.expr : ""); |
printf("\">, section " |
printf("\">, section " |
"<INPUT TYPE=\"text\"" |
"<INPUT TYPE=\"text\"" |
Line 385 resp_searchform(const struct req *req) |
|
Line 389 resp_searchform(const struct req *req) |
|
"<INPUT TYPE=\"text\"" |
"<INPUT TYPE=\"text\"" |
" SIZE=\"8\" NAME=\"arch\" VALUE=\""); |
" SIZE=\"8\" NAME=\"arch\" VALUE=\""); |
html_print(req->q.arch ? req->q.arch : ""); |
html_print(req->q.arch ? req->q.arch : ""); |
puts("\">.\n" |
printf("\">"); |
|
if (req->psz > 1) { |
|
puts(", <SELECT NAME=\"manpath\">"); |
|
for (i = 0; i < (int)req->psz; i++) { |
|
printf("<OPTION %s VALUE=\"", |
|
(i == req->q.manroot) || |
|
(0 == i && -1 == req->q.manroot) ? |
|
"SELECTED=\"selected\"" : ""); |
|
html_print(req->p[i].name); |
|
printf("\">"); |
|
html_print(req->p[i].name); |
|
puts("</OPTION>"); |
|
} |
|
puts("</SELECT>"); |
|
} |
|
puts(".\n" |
"<INPUT TYPE=\"reset\" VALUE=\"Reset\">\n" |
"<INPUT TYPE=\"reset\" VALUE=\"Reset\">\n" |
"</FIELDSET>\n" |
"</FIELDSET>\n" |
"</FORM>"); |
"</FORM>\n" |
|
"</DIV>"); |
puts("<!-- End search form. //-->"); |
puts("<!-- End search form. //-->"); |
} |
} |
|
|
Line 456 resp_search(struct res *r, size_t sz, void *arg) |
|
Line 476 resp_search(struct res *r, size_t sz, void *arg) |
|
int i; |
int i; |
const struct req *req; |
const struct req *req; |
|
|
|
req = (const struct req *)arg; |
|
assert(req->q.manroot >= 0); |
|
|
if (1 == sz) { |
if (1 == sz) { |
/* |
/* |
* If we have just one result, then jump there now |
* If we have just one result, then jump there now |
* without any delay. |
* without any delay. |
*/ |
*/ |
puts("Status: 303 See Other"); |
puts("Status: 303 See Other"); |
printf("Location: http://%s%s/show/%u/%u.html\n", |
printf("Location: http://%s%s/show/%d/%u/%u.html\n", |
host, progname, |
host, progname, req->q.manroot, |
r[0].volume, r[0].rec); |
r[0].volume, r[0].rec); |
puts("Content-Type: text/html; charset=utf-8\n"); |
puts("Content-Type: text/html; charset=utf-8\n"); |
return; |
return; |
Line 472 resp_search(struct res *r, size_t sz, void *arg) |
|
Line 495 resp_search(struct res *r, size_t sz, void *arg) |
|
qsort(r, sz, sizeof(struct res), cmp); |
qsort(r, sz, sizeof(struct res), cmp); |
|
|
resp_begin_html(200, NULL); |
resp_begin_html(200, NULL); |
|
|
req = (const struct req *)arg; |
|
resp_searchform(req); |
resp_searchform(req); |
|
|
if (0 == sz) { |
if (0 == sz) { |
Line 481 resp_search(struct res *r, size_t sz, void *arg) |
|
Line 502 resp_search(struct res *r, size_t sz, void *arg) |
|
"No %s results found.\n", |
"No %s results found.\n", |
req->q.whatis ? "whatis" : "apropos"); |
req->q.whatis ? "whatis" : "apropos"); |
if (req->q.whatis) { |
if (req->q.whatis) { |
printf("(Try <A HREF=\""); |
printf("(Try <A HREF=\"%s/search.html?" |
html_print(progname); |
"op=apropos&expr=", progname); |
printf("/search.html?op=apropos&expr="); |
|
html_print(req->q.expr ? req->q.expr : ""); |
html_print(req->q.expr ? req->q.expr : ""); |
printf("&sec="); |
printf("&sec="); |
html_print(req->q.sec ? req->q.sec : ""); |
html_print(req->q.sec ? req->q.sec : ""); |
Line 499 resp_search(struct res *r, size_t sz, void *arg) |
|
Line 519 resp_search(struct res *r, size_t sz, void *arg) |
|
puts("<P></P>\n" |
puts("<P></P>\n" |
"<TABLE>"); |
"<TABLE>"); |
|
|
assert(req->q.manroot >= 0); |
|
for (i = 0; i < (int)sz; i++) { |
for (i = 0; i < (int)sz; i++) { |
printf("<TR>\n" |
printf("<TR>\n" |
"<TD CLASS=\"title\">\n" |
"<TD CLASS=\"title\">\n" |
"<A HREF=\""); |
"<A HREF=\"%s/show/%d/%u/%u.html\">", |
html_print(progname); |
progname, req->q.manroot, |
printf("/show/%d/%u/%u.html\">", |
|
req->q.manroot, |
|
r[i].volume, r[i].rec); |
r[i].volume, r[i].rec); |
html_print(r[i].title); |
html_print(r[i].title); |
putchar('('); |
putchar('('); |
Line 536 pg_index(const struct req *req, char *path) |
|
Line 553 pg_index(const struct req *req, char *path) |
|
} |
} |
|
|
static void |
static void |
catman(const char *file) |
catman(const struct req *req, const char *file) |
{ |
{ |
FILE *f; |
FILE *f; |
size_t len; |
size_t len; |
Line 549 catman(const char *file) |
|
Line 566 catman(const char *file) |
|
return; |
return; |
} |
} |
|
|
resp_begin_http(200, NULL); |
resp_begin_html(200, NULL); |
puts("<!DOCTYPE HTML PUBLIC " |
resp_searchform(req); |
" \"-//W3C//DTD HTML 4.01//EN\"" |
puts("<DIV CLASS=\"catman\">\n" |
" \"http://www.w3.org/TR/html4/strict.dtd\">\n" |
|
"<HTML>\n" |
|
"<HEAD>\n" |
|
"<META HTTP-EQUIV=\"Content-Type\"" |
|
" CONTENT=\"text/html; charset=utf-8\">\n" |
|
"<LINK REL=\"stylesheet\" HREF=\"/catman.css\"" |
|
" TYPE=\"text/css\" media=\"all\">\n" |
|
"<TITLE>System Manpage Reference</TITLE>\n" |
|
"</HEAD>\n" |
|
"<BODY>\n" |
|
"<!-- Begin page content. //-->\n" |
|
"<PRE>"); |
"<PRE>"); |
|
|
while (NULL != (p = fgetln(f, &len))) { |
while (NULL != (p = fgetln(f, &len))) { |
Line 675 catman(const char *file) |
|
Line 681 catman(const char *file) |
|
} |
} |
|
|
puts("</PRE>\n" |
puts("</PRE>\n" |
|
"</DIV>\n" |
"</BODY>\n" |
"</BODY>\n" |
"</HTML>"); |
"</HTML>"); |
|
|
Line 682 catman(const char *file) |
|
Line 689 catman(const char *file) |
|
} |
} |
|
|
static void |
static void |
format(const char *file) |
format(const struct req *req, const char *file) |
{ |
{ |
struct mparse *mp; |
struct mparse *mp; |
int fd; |
int fd; |
Line 706 format(const char *file) |
|
Line 713 format(const char *file) |
|
return; |
return; |
} |
} |
|
|
snprintf(opts, sizeof(opts), "style=/man.css," |
snprintf(opts, sizeof(opts), "fragment," |
"man=%s/search.html?sec=%%S&expr=%%N," |
"man=%s/search.html?sec=%%S&expr=%%N," |
/*"includes=/cgi-bin/man.cgi/usr/include/%%I"*/, |
/*"includes=/cgi-bin/man.cgi/usr/include/%%I"*/, |
progname); |
progname); |
|
|
mparse_result(mp, &mdoc, &man); |
mparse_result(mp, &mdoc, &man); |
|
if (NULL == man && NULL == mdoc) { |
|
resp_baddb(); |
|
mparse_free(mp); |
|
return; |
|
} |
|
|
|
resp_begin_html(200, NULL); |
|
resp_searchform(req); |
|
|
vp = html_alloc(opts); |
vp = html_alloc(opts); |
|
|
if (NULL != mdoc) { |
if (NULL != mdoc) |
resp_begin_http(200, NULL); |
|
html_mdoc(vp, mdoc); |
html_mdoc(vp, mdoc); |
} else if (NULL != man) { |
else |
resp_begin_http(200, NULL); |
|
html_man(vp, man); |
html_man(vp, man); |
} else |
|
resp_baddb(); |
|
|
|
|
puts("</BODY>\n" |
|
"</HTML>"); |
|
|
html_free(vp); |
html_free(vp); |
mparse_free(mp); |
mparse_free(mp); |
} |
} |
Line 779 pg_show(const struct req *req, char *path) |
|
Line 794 pg_show(const struct req *req, char *path) |
|
} |
} |
|
|
memset(&ps, 0, sizeof(struct manpaths)); |
memset(&ps, 0, sizeof(struct manpaths)); |
manpath_manconf("etc/catman.conf", &ps); |
manpath_manconf(&ps, "etc/catman.conf"); |
|
|
if (vol >= (unsigned int)ps.sz) { |
if (vol >= (unsigned int)ps.sz) { |
resp_error400(); |
resp_error400(); |
Line 816 pg_show(const struct req *req, char *path) |
|
Line 831 pg_show(const struct req *req, char *path) |
|
resp_baddb(); |
resp_baddb(); |
else { |
else { |
if (0 == strcmp(cp, "cat")) |
if (0 == strcmp(cp, "cat")) |
catman(fn + 1); |
catman(req, fn + 1); |
else |
else |
format(fn + 1); |
format(req, fn + 1); |
} |
} |
out: |
out: |
if (idx) |
if (idx) |
Line 837 pg_search(const struct req *req, char *path) |
|
Line 852 pg_search(const struct req *req, char *path) |
|
struct opts opt; |
struct opts opt; |
struct expr *expr; |
struct expr *expr; |
|
|
if (req->q.manroot < 0) { |
if (req->q.manroot < 0 || 0 == req->psz) { |
resp_search(NULL, 0, (void *)req); |
resp_search(NULL, 0, (void *)req); |
return; |
return; |
} |
} |
Line 865 pg_search(const struct req *req, char *path) |
|
Line 880 pg_search(const struct req *req, char *path) |
|
} |
} |
|
|
memset(&ps, 0, sizeof(struct manpaths)); |
memset(&ps, 0, sizeof(struct manpaths)); |
manpath_manconf("etc/catman.conf", &ps); |
manpath_manconf(&ps, "etc/catman.conf"); |
|
|
/* |
/* |
* Poor man's tokenisation: just break apart by spaces. |
* Poor man's tokenisation: just break apart by spaces. |
|
|
|
|
/* Scan our run-time environment. */ |
/* Scan our run-time environment. */ |
|
|
progname = getenv("SCRIPT_NAME"); |
if (NULL == (cache = getenv("CACHE_DIR"))) |
if (NULL == progname) |
cache = "/cache/man.cgi"; |
|
|
|
if (NULL == (progname = getenv("SCRIPT_NAME"))) |
progname = ""; |
progname = ""; |
|
|
cache = getenv("CACHE_DIR"); |
if (NULL == (css = getenv("CSS_DIR"))) |
if (NULL == cache) |
css = ""; |
cache = "/cache/man.cgi"; |
|
|
|
host = getenv("HTTP_HOST"); |
if (NULL == (host = getenv("HTTP_HOST"))) |
if (NULL == host) |
|
host = "localhost"; |
host = "localhost"; |
|
|
/* |
/* |
Line 1100 pathgen(DIR *dir, char *path, struct req *req) |
|
Line 1115 pathgen(DIR *dir, char *path, struct req *req) |
|
|
|
if (rc > 0) { |
if (rc > 0) { |
/* This also strips the trailing slash. */ |
/* This also strips the trailing slash. */ |
path[(int)sz - 1] = '\0'; |
path[(int)--sz] = '\0'; |
req->p = mandoc_realloc |
req->p = mandoc_realloc |
(req->p, |
(req->p, |
(req->psz + 1) * sizeof(struct paths)); |
(req->psz + 1) * sizeof(struct paths)); |
|
/* |
|
* Strip out the leading "./" unless we're just a ".", |
|
* in which case use an empty string as our name. |
|
*/ |
req->p[(int)req->psz].path = mandoc_strdup(path); |
req->p[(int)req->psz].path = mandoc_strdup(path); |
/* And this strips out the leading "./". */ |
|
req->p[(int)req->psz].name = |
req->p[(int)req->psz].name = |
cp = mandoc_strdup(path + 2); |
cp = mandoc_strdup(path + (1 == sz ? 1 : 2)); |
req->psz++; |
req->psz++; |
/* |
/* |
* The name is just the path with all the slashes taken |
* The name is just the path with all the slashes taken |