From: kristaps@mdocml.bsd.lv
To: source@mdocml.bsd.lv
Subject: mdocml: When routing to a "result" page in the cgi, remember our input
Date: Fri, 16 Dec 2011 13:37:12 -0500 (EST) [thread overview]
Message-ID: <201112161837.pBGIbCsj018380@krisdoz.my.domain> (raw)
Log Message:
-----------
When routing to a "result" page in the cgi, remember our input parameters
and repeat them in the search bar. This is handy. While here, make the
QUERY_STRING parser a bit simpler.
Modified Files:
--------------
mdocml:
cgi.c
Revision Data
-------------
Index: cgi.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/cgi.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -Lcgi.c -Lcgi.c -u -p -r1.35 -r1.36
--- cgi.c
+++ cgi.c
@@ -84,9 +84,13 @@ static void catman(const struct req *,
static int cmp(const void *, const void *);
static void format(const struct req *, const char *);
static void html_print(const char *);
+static void html_printquery(const struct req *);
static void html_putchar(char);
static int http_decode(char *);
static void http_parse(struct req *, char *);
+static void http_print(const char *);
+static void http_putchar(char);
+static void http_printquery(const struct req *);
static int pathstop(DIR *);
static void pathgen(DIR *, char *, struct req *);
static void pg_index(const struct req *, char *);
@@ -163,6 +167,40 @@ html_putchar(char c)
break;
}
}
+static void
+http_printquery(const struct req *req)
+{
+
+ printf("&expr=");
+ http_print(req->q.expr ? req->q.expr : "");
+ printf("&sec=");
+ http_print(req->q.sec ? req->q.sec : "");
+ printf("&arch=");
+ http_print(req->q.arch ? req->q.arch : "");
+}
+
+
+static void
+html_printquery(const struct req *req)
+{
+
+ printf("&expr=");
+ html_print(req->q.expr ? req->q.expr : "");
+ printf("&sec=");
+ html_print(req->q.sec ? req->q.sec : "");
+ printf("&arch=");
+ html_print(req->q.arch ? req->q.arch : "");
+}
+
+static void
+http_print(const char *p)
+{
+
+ if (NULL == p)
+ return;
+ while ('\0' != *p)
+ http_putchar(*p++);
+}
/*
* Call through to html_putchar().
@@ -187,7 +225,6 @@ static void
http_parse(struct req *req, char *p)
{
char *key, *val, *manroot;
- size_t sz;
int i, legacy;
memset(&req->q, 0, sizeof(struct query));
@@ -196,42 +233,24 @@ http_parse(struct req *req, char *p)
legacy = -1;
manroot = NULL;
- while (p && '\0' != *p) {
- while (' ' == *p)
- p++;
-
+ while ('\0' != *p) {
key = p;
val = NULL;
- if (NULL != (p = strchr(p, '='))) {
+ p += (int)strcspn(p, ";&");
+ if ('\0' != *p)
*p++ = '\0';
- val = p;
+ if (NULL != (val = strchr(key, '=')))
+ *val++ = '\0';
- sz = strcspn(p, ";&");
- /* LINTED */
- p += sz;
-
- if ('\0' != *p)
- *p++ = '\0';
- } else {
- p = key;
- sz = strcspn(p, ";&");
- /* LINTED */
- p += sz;
-
- if ('\0' != *p)
- p++;
- continue;
- }
-
- if ('\0' == *key || '\0' == *val)
+ if ('\0' == *key || NULL == val || '\0' == *val)
continue;
/* Just abort handling. */
if ( ! http_decode(key))
break;
- if ( ! http_decode(val))
+ if (NULL != val && ! http_decode(val))
break;
if (0 == strcmp(key, "expr"))
@@ -284,6 +303,20 @@ http_parse(struct req *req, char *p)
}
}
+static void
+http_putchar(char c)
+{
+
+ if (isalnum((unsigned char)c)) {
+ putchar((unsigned char)c);
+ return;
+ } else if (' ' == c) {
+ putchar('+');
+ return;
+ }
+ printf("%%%.2x", c);
+}
+
/*
* HTTP-decode a string. The standard explanation is that this turns
* "%4e+foo" into "n foo" in the regular way. This is done in-place
@@ -478,17 +511,19 @@ resp_search(struct res *r, size_t sz, vo
req = (const struct req *)arg;
assert(req->q.manroot >= 0);
-
+
if (1 == sz) {
/*
* 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\n",
+ printf("Location: http://%s%s/show/%d/%u/%u.html?",
host, progname, req->q.manroot,
r[0].volume, r[0].rec);
- puts("Content-Type: text/html; charset=utf-8\n");
+ http_printquery(req);
+ puts("\n"
+ "Content-Type: text/html; charset=utf-8\n");
return;
}
@@ -504,13 +539,10 @@ resp_search(struct res *r, size_t sz, vo
"No %s results found.\n",
req->q.whatis ? "whatis" : "apropos");
if (req->q.whatis) {
- printf("(Try <A HREF=\"%s/search.html?"
- "op=apropos&expr=", progname);
- html_print(req->q.expr ? req->q.expr : "");
- printf("&sec=");
- html_print(req->q.sec ? req->q.sec : "");
- printf("&arch=");
- html_print(req->q.arch ? req->q.arch : "");
+ printf("(Try "
+ "<A HREF=\"%s/search.html?op=apropos",
+ progname);
+ html_printquery(req);
puts("\">apropos</A>?)");
}
puts("</P>");
@@ -524,9 +556,11 @@ resp_search(struct res *r, size_t sz, vo
for (i = 0; i < (int)sz; i++) {
printf("<TR>\n"
"<TD CLASS=\"title\">\n"
- "<A HREF=\"%s/show/%d/%u/%u.html\">",
+ "<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);
--
To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv
reply other threads:[~2011-12-16 18:37 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201112161837.pBGIbCsj018380@krisdoz.my.domain \
--to=kristaps@mdocml.bsd.lv \
--cc=source@mdocml.bsd.lv \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).