static void resp_index(const struct req *req) { resp_begin_html(200, NULL); resp_searchform(req); resp_end_html(); }
static void pg_noresult(const struct req *req, const char *msg) { resp_begin_html(200, NULL); resp_searchform(req); puts("<P>"); puts(msg); puts("</P>"); resp_end_html(); }
static void format(const struct req *req, const char *file) { struct mparse *mp; int fd; struct mdoc *mdoc; struct man *man; void *vp; enum mandoclevel rc; char opts[PATH_MAX + 128]; if (-1 == (fd = open(file, O_RDONLY, 0))) { resp_baddb(); return; } mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL, NULL); rc = mparse_readfd(mp, fd, file); close(fd); if (rc >= MANDOCLEVEL_FATAL) { resp_baddb(); return; } snprintf(opts, sizeof(opts), "fragment," "man=%s/search.html?sec=%%S&expr=Nm~^%%N$," /*"includes=/cgi-bin/man.cgi/usr/include/%%I"*/, progname); 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); if (NULL != mdoc) html_mdoc(vp, mdoc); else html_man(vp, man); puts("</BODY>\n" "</HTML>"); html_free(vp); mparse_free(mp); }
static void pg_show(struct req *req, const char *fullpath) { char *manpath; const char *file; if ((file = strchr(fullpath, '/')) == NULL) { pg_error_badrequest( "You did not specify a page to show."); return; } manpath = mandoc_strndup(fullpath, file - fullpath); file++; if ( ! validate_manpath(req, manpath)) { pg_error_badrequest( "You specified an invalid manpath."); free(manpath); return; } /* * Begin by chdir()ing into the manpath. * This way we can pick up the database files, which are * relative to the manpath root. */ if (chdir(manpath) == -1) { fprintf(stderr, "chdir %s: %s\n", manpath, strerror(errno)); pg_error_internal(); free(manpath); return; } if (strcmp(manpath, "mandoc")) { free(req->q.manpath); req->q.manpath = manpath; } else free(manpath); if ( ! validate_filename(file)) { pg_error_badrequest( "You specified an invalid manual file."); return; } resp_begin_html(200, NULL); resp_searchform(req); resp_show(req, file); resp_end_html(); }
static void pg_index(const struct req *req) { resp_begin_html(200, NULL); resp_searchform(req); printf("<P>\n" "This web interface is documented in the\n" "<A HREF=\"%s/mandoc/man8/man.cgi.8\">man.cgi</A>\n" "manual, and the\n" "<A HREF=\"%s/mandoc/man1/apropos.1\">apropos</A>\n" "manual explains the query syntax.\n" "</P>\n", scriptname, scriptname); resp_end_html(); }
static void pg_index(const struct req *req) { resp_begin_html(200, NULL); resp_searchform(req, FOCUS_QUERY); printf("<p>\n" "This web interface is documented in the\n" "<a href=\"/%s%sman.cgi.8\">man.cgi(8)</a>\n" "manual, and the\n" "<a href=\"/%s%sapropos.1\">apropos(1)</a>\n" "manual explains the query syntax.\n" "</p>\n", scriptname, *scriptname == '\0' ? "" : "/", scriptname, *scriptname == '\0' ? "" : "/"); resp_end_html(); }
static void pg_searchres(const struct req *req, struct manpage *r, size_t sz) { char *arch, *archend; size_t i, iuse, isec; int archprio, archpriouse; int prio, priouse; char sec; for (i = 0; i < sz; i++) { if (validate_filename(r[i].file)) continue; fprintf(stderr, "invalid filename %s in %s database\n", r[i].file, req->q.manpath); pg_error_internal(); return; } if (1 == sz) { /* * If we have just one result, then jump there now * without any delay. */ printf("Status: 303 See Other\r\n"); printf("Location: http://%s%s/%s/%s?", HTTP_HOST, scriptname, req->q.manpath, r[0].file); http_printquery(req, "&"); printf("\r\n" "Content-Type: text/html; charset=utf-8\r\n" "\r\n"); return; } resp_begin_html(200, NULL); resp_searchform(req); puts("<DIV CLASS=\"results\">"); puts("<TABLE>"); for (i = 0; i < sz; i++) { printf("<TR>\n" "<TD CLASS=\"title\">\n" "<A HREF=\"%s/%s/%s?", scriptname, req->q.manpath, r[i].file); http_printquery(req, "&"); printf("\">"); html_print(r[i].names); printf("</A>\n" "</TD>\n" "<TD CLASS=\"desc\">"); html_print(r[i].output); puts("</TD>\n" "</TR>"); } puts("</TABLE>\n" "</DIV>"); /* * In man(1) mode, show one of the pages * even if more than one is found. */ if (req->q.equal) { puts("<HR>"); iuse = 0; priouse = 10; archpriouse = 3; for (i = 0; i < sz; i++) { isec = strcspn(r[i].file, "123456789"); sec = r[i].file[isec]; if ('\0' == sec) continue; prio = sec_prios[sec - '1']; if (NULL == req->q.arch) { archprio = (NULL == (arch = strchr( r[i].file + isec, '/'))) ? 3 : (NULL == (archend = strchr( arch + 1, '/'))) ? 0 : strncmp(arch, "amd64/", archend - arch) ? 2 : 1; if (archprio < archpriouse) { archpriouse = archprio; priouse = prio; iuse = i; continue; } if (archprio > archpriouse) continue; } if (prio >= priouse) continue; priouse = prio; iuse = i; } resp_show(req, r[iuse].file); } resp_end_html(); }
static void pg_searchres(const struct req *req, struct manpage *r, size_t sz) { char *arch, *archend; const char *sec; size_t i, iuse; int archprio, archpriouse; int prio, priouse; for (i = 0; i < sz; i++) { if (validate_filename(r[i].file)) continue; warnx("invalid filename %s in %s database", r[i].file, req->q.manpath); pg_error_internal(); return; } if (req->isquery && sz == 1) { /* * If we have just one result, then jump there now * without any delay. */ printf("Status: 303 See Other\r\n"); printf("Location: http://%s/%s%s%s/%s", HTTP_HOST, scriptname, *scriptname == '\0' ? "" : "/", req->q.manpath, r[0].file); printf("\r\n" "Content-Type: text/html; charset=utf-8\r\n" "\r\n"); return; } resp_begin_html(200, NULL); resp_searchform(req, req->q.equal || sz == 1 ? FOCUS_NONE : FOCUS_QUERY); if (sz > 1) { puts("<div class=\"results\">"); puts("<table>"); for (i = 0; i < sz; i++) { printf("<tr>\n" "<td class=\"title\">\n" "<a href=\"/%s%s%s/%s", scriptname, *scriptname == '\0' ? "" : "/", req->q.manpath, r[i].file); printf("\">"); html_print(r[i].names); printf("</a>\n" "</td>\n" "<td class=\"desc\">"); html_print(r[i].output); puts("</td>\n" "</tr>"); } puts("</table>\n" "</div>"); } /* * In man(1) mode, show one of the pages * even if more than one is found. */ if (req->q.equal || sz == 1) { puts("<hr>"); iuse = 0; priouse = 20; archpriouse = 3; for (i = 0; i < sz; i++) { sec = r[i].file; sec += strcspn(sec, "123456789"); if (sec[0] == '\0') continue; prio = sec_prios[sec[0] - '1']; if (sec[1] != '/') prio += 10; if (req->q.arch == NULL) { archprio = ((arch = strchr(sec + 1, '/')) == NULL) ? 3 : ((archend = strchr(arch + 1, '/')) == NULL) ? 0 : strncmp(arch, "amd64/", archend - arch) ? 2 : 1; if (archprio < archpriouse) { archpriouse = archprio; priouse = prio; iuse = i; continue; } if (archprio > archpriouse) continue; } if (prio >= priouse) continue; priouse = prio; iuse = i; } resp_show(req, r[iuse].file); } resp_end_html(); }
static void catman(const struct req *req, const char *file) { FILE *f; size_t len; int i; char *p; int italic, bold; if (NULL == (f = fopen(file, "r"))) { resp_baddb(); return; } resp_begin_html(200, NULL); resp_searchform(req); puts("<DIV CLASS=\"catman\">\n" "<PRE>"); while (NULL != (p = fgetln(f, &len))) { bold = italic = 0; for (i = 0; i < (int)len - 1; i++) { /* * This means that the catpage is out of state. * Ignore it and keep going (although the * catpage is bogus). */ if ('\b' == p[i] || '\n' == p[i]) continue; /* * Print a regular character. * Close out any bold/italic scopes. * If we're in back-space mode, make sure we'll * have something to enter when we backspace. */ if ('\b' != p[i + 1]) { if (italic) printf("</I>"); if (bold) printf("</B>"); italic = bold = 0; html_putchar(p[i]); continue; } else if (i + 2 >= (int)len) continue; /* Italic mode. */ if ('_' == p[i]) { if (bold) printf("</B>"); if ( ! italic) printf("<I>"); bold = 0; italic = 1; i += 2; html_putchar(p[i]); continue; } /* * Handle funny behaviour troff-isms. * These grok'd from the original man2html.c. */ if (('+' == p[i] && 'o' == p[i + 2]) || ('o' == p[i] && '+' == p[i + 2]) || ('|' == p[i] && '=' == p[i + 2]) || ('=' == p[i] && '|' == p[i + 2]) || ('*' == p[i] && '=' == p[i + 2]) || ('=' == p[i] && '*' == p[i + 2]) || ('*' == p[i] && '|' == p[i + 2]) || ('|' == p[i] && '*' == p[i + 2])) { if (italic) printf("</I>"); if (bold) printf("</B>"); italic = bold = 0; putchar('*'); i += 2; continue; } else if (('|' == p[i] && '-' == p[i + 2]) || ('-' == p[i] && '|' == p[i + 1]) || ('+' == p[i] && '-' == p[i + 1]) || ('-' == p[i] && '+' == p[i + 1]) || ('+' == p[i] && '|' == p[i + 1]) || ('|' == p[i] && '+' == p[i + 1])) { if (italic) printf("</I>"); if (bold) printf("</B>"); italic = bold = 0; putchar('+'); i += 2; continue; } /* Bold mode. */ if (italic) printf("</I>"); if ( ! bold) printf("<B>"); bold = 1; italic = 0; i += 2; html_putchar(p[i]); } /* * Clean up the last character. * We can get to a newline; don't print that. */ if (italic) printf("</I>"); if (bold) printf("</B>"); if (i == (int)len - 1 && '\n' != p[i]) html_putchar(p[i]); putchar('\n'); } puts("</PRE>\n" "</DIV>\n" "</BODY>\n" "</HTML>"); fclose(f); }
static void resp_search(struct res *r, size_t sz, void *arg) { size_t i, matched; const struct req *req; req = (const struct req *)arg; if (sz > 0) assert(req->q.manroot >= 0); for (matched = i = 0; i < sz; i++) if (r[i].matched) matched++; if (1 == matched) { for (i = 0; i < sz; i++) if (r[i].matched) break; /* * If we have just one result, then jump there now * without any delay. */ puts("Status: 303 See Other"); printf("Location: http://%s%s/show/%d/%u/%u.html?", host, progname, req->q.manroot, r[i].volume, r[i].rec); http_printquery(req); puts("\n" "Content-Type: text/html; charset=utf-8\n"); return; } resp_begin_html(200, NULL); resp_searchform(req); puts("<DIV CLASS=\"results\">"); if (0 == matched) { puts("<P>\n" "No results found.\n" "</P>\n" "</DIV>"); resp_end_html(); return; } qsort(r, sz, sizeof(struct res), cmp); puts("<TABLE>"); for (i = 0; i < sz; i++) { if ( ! r[i].matched) continue; printf("<TR>\n" "<TD CLASS=\"title\">\n" "<A HREF=\"%s/show/%d/%u/%u.html?", progname, req->q.manroot, r[i].volume, r[i].rec); html_printquery(req); printf("\">"); html_print(r[i].title); putchar('('); html_print(r[i].cat); if (r[i].arch && '\0' != *r[i].arch) { putchar('/'); html_print(r[i].arch); } printf(")</A>\n" "</TD>\n" "<TD CLASS=\"desc\">"); html_print(r[i].desc); puts("</TD>\n" "</TR>"); } puts("</TABLE>\n" "</DIV>"); resp_end_html(); }