diff options
author | 2016-03-17 21:22:43 +0000 | |
---|---|---|
committer | 2016-03-17 21:22:43 +0000 | |
commit | 02b1b49469a48b04fe88940ac5425938ef29edfb (patch) | |
tree | 246463be1e98fdc08bb979e11bcf420c2c1f1249 /usr.bin/mandoc/cgi.c | |
parent | Remove #ifdef __vax__ bits (diff) | |
download | wireguard-openbsd-02b1b49469a48b04fe88940ac5425938ef29edfb.tar.xz wireguard-openbsd-02b1b49469a48b04fe88940ac5425938ef29edfb.zip |
support short URIs for man.openbsd.org
Diffstat (limited to 'usr.bin/mandoc/cgi.c')
-rw-r--r-- | usr.bin/mandoc/cgi.c | 78 |
1 files changed, 69 insertions, 9 deletions
diff --git a/usr.bin/mandoc/cgi.c b/usr.bin/mandoc/cgi.c index 6fd5a208187..b64a243a0d0 100644 --- a/usr.bin/mandoc/cgi.c +++ b/usr.bin/mandoc/cgi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cgi.c,v 1.55 2015/12/25 20:16:19 bentley Exp $ */ +/* $OpenBSD: cgi.c,v 1.56 2016/03/17 21:22:43 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@usta.de> @@ -62,6 +62,7 @@ static void html_putchar(char); static int http_decode(char *); static void http_parse(struct req *, const char *); static void pathgen(struct req *); +static void path_parse(struct req *req, const char *path); static void pg_error_badrequest(const char *); static void pg_error_internal(void); static void pg_index(const struct req *); @@ -1031,11 +1032,21 @@ main(void) memset(&req, 0, sizeof(struct req)); pathgen(&req); - /* Next parse out the query string. */ + /* Parse the path info and the query string. */ - if (NULL != (querystring = getenv("QUERY_STRING"))) + if ((path = getenv("PATH_INFO")) == NULL) + path = ""; + else if (*path == '/') + path++; + + if (*path != '\0' && access(path, F_OK) == -1) { + path_parse(&req, path); + path = ""; + } else if ((querystring = getenv("QUERY_STRING")) != NULL) http_parse(&req, querystring); + /* Validate parsed data and add defaults. */ + if (req.q.manpath == NULL) req.q.manpath = mandoc_strdup(req.p[0]); else if ( ! validate_manpath(&req, req.q.manpath)) { @@ -1052,12 +1063,6 @@ main(void) /* Dispatch to the three different pages. */ - path = getenv("PATH_INFO"); - if (NULL == path) - path = ""; - else if ('/' == *path) - path++; - if ('\0' != *path) pg_show(&req, path); else if (NULL != req.q.query) @@ -1076,6 +1081,61 @@ main(void) } /* + * If PATH_INFO is not a file name, translate it to a query. + */ +static void +path_parse(struct req *req, const char *path) +{ + int dir_done; + + req->q.equal = 1; + req->q.manpath = mandoc_strdup(path); + + /* Mandatory manual page name. */ + if ((req->q.query = strrchr(req->q.manpath, '/')) == NULL) { + req->q.query = req->q.manpath; + req->q.manpath = NULL; + } else + *req->q.query++ = '\0'; + + /* Optional trailing section. */ + if ((req->q.sec = strrchr(req->q.query, '.')) != NULL) { + if(isdigit((unsigned char)req->q.sec[1])) { + *req->q.sec++ = '\0'; + req->q.sec = mandoc_strdup(req->q.sec); + } else + req->q.sec = NULL; + } + + /* Handle the case of name[.section] only. */ + if (req->q.manpath == NULL) { + req->q.arch = NULL; + return; + } + req->q.query = mandoc_strdup(req->q.query); + + /* Optional architecture. */ + dir_done = 0; + for (;;) { + if ((req->q.arch = strrchr(req->q.manpath, '/')) == NULL) + break; + *req->q.arch++ = '\0'; + if (dir_done || strncmp(req->q.arch, "man", 3)) { + req->q.arch = mandoc_strdup(req->q.arch); + break; + } + + /* Optional directory name. */ + req->q.arch += 3; + if (*req->q.arch != '\0') { + free(req->q.sec); + req->q.sec = mandoc_strdup(req->q.arch); + } + dir_done = 1; + } +} + +/* * Scan for indexable paths. */ static void |