=================================================================== RCS file: /cvs/mandoc/cgi.c,v retrieving revision 1.117 retrieving revision 1.125 diff -u -p -r1.117 -r1.125 --- mandoc/cgi.c 2016/03/17 21:22:59 1.117 +++ mandoc/cgi.c 2016/04/15 00:51:59 1.125 @@ -1,7 +1,7 @@ -/* $Id: cgi.c,v 1.117 2016/03/17 21:22:59 schwarze Exp $ */ +/* $Id: cgi.c,v 1.125 2016/04/15 00:51:59 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons - * Copyright (c) 2014, 2015 Ingo Schwarze + * Copyright (c) 2014, 2015, 2016 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -55,6 +55,7 @@ struct req { struct query q; char **p; /* array of available manpaths */ size_t psz; /* number of available manpaths */ + int isquery; /* QUERY_STRING used, not PATH_INFO */ }; static void catman(const struct req *, const char *); @@ -84,7 +85,7 @@ static int validate_filename(const char *); static int validate_manpath(const struct req *, const char *); static int validate_urifrag(const char *); -static const char *scriptname; /* CGI script name */ +static const char *scriptname = SCRIPT_NAME; static const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9}; static const char *const sec_numbers[] = { @@ -107,16 +108,16 @@ static const int sec_MAX = sizeof(sec_names) / sizeof( static const char *const arch_names[] = { "amd64", "alpha", "armish", "armv7", - "aviion", "hppa", "hppa64", "i386", - "ia64", "landisk", "loongson", "luna88k", - "macppc", "mips64", "octeon", "sgi", - "socppc", "solbourne", "sparc", "sparc64", - "vax", "zaurus", + "hppa", "hppa64", "i386", "landisk", + "loongson", "luna88k", "macppc", "mips64", + "octeon", "sgi", "socppc", "sparc", + "sparc64", "zaurus", "amiga", "arc", "arm32", "atari", - "beagle", "cats", "hp300", "mac68k", - "mvme68k", "mvme88k", "mvmeppc", "palm", - "pc532", "pegasos", "pmax", "powerpc", - "sun3", "wgrisc", "x68k" + "aviion", "beagle", "cats", "hp300", + "ia64", "mac68k", "mvme68k", "mvme88k", + "mvmeppc", "palm", "pc532", "pegasos", + "pmax", "powerpc", "solbourne", "sun3", + "vax", "wgrisc", "x68k" }; static const int arch_MAX = sizeof(arch_names) / sizeof(char *); @@ -188,6 +189,7 @@ http_parse(struct req *req, const char *qs) char *key, *val; size_t keysz, valsz; + req->isquery = 1; req->q.manpath = NULL; req->q.arch = NULL; req->q.sec = NULL; @@ -370,7 +372,7 @@ resp_searchform(const struct req *req) puts(""); printf("
\n" - "
\n" + "\n" "
\n" "Manual Page Search Parameters\n", scriptname); @@ -507,12 +509,13 @@ pg_index(const struct req *req) resp_searchform(req); printf("

\n" "This web interface is documented in the\n" - "man.cgi\n" + "man.cgi\n" "manual, and the\n" - "apropos\n" + "apropos\n" "manual explains the query syntax.\n" "

\n", - scriptname, scriptname); + scriptname, *scriptname == '\0' ? "" : "/", + scriptname, *scriptname == '\0' ? "" : "/"); resp_end_html(); } @@ -536,7 +539,7 @@ pg_error_badrequest(const char *msg) "

\n"); puts(msg); printf("Try again from the\n" - "main page.\n" + "main page.\n" "

", scriptname); resp_end_html(); } @@ -553,10 +556,10 @@ static void pg_searchres(const struct req *req, struct manpage *r, size_t sz) { char *arch, *archend; - size_t i, iuse, isec; + const char *sec; + size_t i, iuse; int archprio, archpriouse; int prio, priouse; - char sec; for (i = 0; i < sz; i++) { if (validate_filename(r[i].file)) @@ -567,14 +570,16 @@ pg_searchres(const struct req *req, struct manpage *r, return; } - if (1 == sz) { + 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", - HTTP_HOST, scriptname, req->q.manpath, r[0].file); + 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"); @@ -583,49 +588,55 @@ pg_searchres(const struct req *req, struct manpage *r, resp_begin_html(200, NULL); resp_searchform(req); - puts("
"); - puts(""); - for (i = 0; i < sz; i++) { - printf("\n" - "\n" - "\n" - ""); - } + if (sz > 1) { + puts("
"); + puts("
\n" - "q.manpath, r[i].file); - printf("\">"); - html_print(r[i].names); - printf("\n" - ""); - html_print(r[i].output); - puts("
"); - puts("
\n" - "
"); + for (i = 0; i < sz; i++) { + printf("\n" + "\n" + "q.manpath, r[i].file); + printf("\">"); + html_print(r[i].names); + printf("\n" + "\n" + ""); + html_print(r[i].output); + puts("\n" + ""); + } + puts("\n" + "
"); + } + /* * In man(1) mode, show one of the pages * even if more than one is found. */ - if (req->q.equal) { + if (req->q.equal || sz == 1) { puts("
"); iuse = 0; - priouse = 10; + priouse = 20; archpriouse = 3; for (i = 0; i < sz; i++) { - isec = strcspn(r[i].file, "123456789"); - sec = r[i].file[isec]; - if ('\0' == sec) + sec = r[i].file; + sec += strcspn(sec, "123456789"); + if (sec[0] == '\0') continue; - prio = sec_prios[sec - '1']; - if (NULL == req->q.arch) { + prio = sec_prios[sec[0] - '1']; + if (sec[1] != '/') + prio += 10; + if (req->q.arch == NULL) { archprio = - (NULL == (arch = strchr( - r[i].file + isec, '/'))) ? 3 : - (NULL == (archend = strchr( - arch + 1, '/'))) ? 0 : + ((arch = strchr(sec + 1, '/')) + == NULL) ? 3 : + ((archend = strchr(arch + 1, '/')) + == NULL) ? 0 : strncmp(arch, "amd64/", archend - arch) ? 2 : 1; if (archprio < archpriouse) { @@ -808,12 +819,8 @@ format(const struct req *req, const char *file) memset(&conf, 0, sizeof(conf)); conf.fragment = 1; usepath = strcmp(req->q.manpath, req->p[0]); - mandoc_asprintf(&conf.man, "%s?query=%%N&sec=%%S%s%s%s%s", - scriptname, - req->q.arch ? "&arch=" : "", - req->q.arch ? req->q.arch : "", - usepath ? "&manpath=" : "", - usepath ? req->q.manpath : ""); + mandoc_asprintf(&conf.man, "/%s%s%%N.%%S", + usepath ? req->q.manpath : "", usepath ? "/" : ""); mparse_result(mp, &man, NULL); if (man == NULL) { @@ -1006,18 +1013,6 @@ main(void) return EXIT_FAILURE; } - /* Scan our run-time environment. */ - - if (NULL == (scriptname = getenv("SCRIPT_NAME"))) - scriptname = ""; - - if ( ! validate_urifrag(scriptname)) { - fprintf(stderr, "unsafe SCRIPT_NAME \"%s\"\n", - scriptname); - pg_error_internal(); - return EXIT_FAILURE; - } - /* * First we change directory into the MAN_DIR so that * subsequent scanning for manpath directories is rooted @@ -1032,6 +1027,7 @@ main(void) } memset(&req, 0, sizeof(struct req)); + req.q.equal = 1; pathgen(&req); /* Parse the path info and the query string. */ @@ -1041,9 +1037,10 @@ main(void) else if (*path == '/') path++; - if (*path != '\0' && access(path, F_OK) == -1) { + if (*path != '\0') { path_parse(&req, path); - path = ""; + if (access(path, F_OK) == -1) + path = ""; } else if ((querystring = getenv("QUERY_STRING")) != NULL) http_parse(&req, querystring); @@ -1090,6 +1087,7 @@ path_parse(struct req *req, const char *path) { int dir_done; + req->isquery = 0; req->q.equal = 1; req->q.manpath = mandoc_strdup(path);