From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from localhost (fantadrom.bsd.lv [local]) by fantadrom.bsd.lv (OpenSMTPD) with ESMTPA id 89d25432 for ; Thu, 17 Mar 2016 16:23:29 -0500 (EST) Date: Thu, 17 Mar 2016 16:23:29 -0500 (EST) Message-Id: <12211422492965720749.enqueue@fantadrom.bsd.lv> X-Mailinglist: mdocml-source Reply-To: source@mdocml.bsd.lv MIME-Version: 1.0 From: schwarze@mdocml.bsd.lv To: source@mdocml.bsd.lv Subject: mdocml: support short URIs for man.openbsd.org X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Log Message: ----------- support short URIs for man.openbsd.org Modified Files: -------------- mdocml: cgi.c Revision Data ------------- Index: cgi.c =================================================================== RCS file: /home/cvs/mdocml/mdocml/cgi.c,v retrieving revision 1.116 retrieving revision 1.117 diff -Lcgi.c -Lcgi.c -u -p -r1.116 -r1.117 --- cgi.c +++ cgi.c @@ -64,6 +64,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 *); @@ -1033,11 +1034,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)) { @@ -1054,12 +1065,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) @@ -1075,6 +1080,61 @@ main(void) free(req.p[i]); free(req.p); return EXIT_SUCCESS; +} + +/* + * 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; + } } /* -- To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv