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_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(); }