]> git.cameronkatri.com Git - mandoc.git/blobdiff - cgi.c
Make catman and man.cgi understand the index type-field.
[mandoc.git] / cgi.c
diff --git a/cgi.c b/cgi.c
index a3ec20e944f29c20de46910c08ee6bdc2f722be6..1d88c434207ee572ecb92d144ebc80f255abacc1 100644 (file)
--- a/cgi.c
+++ b/cgi.c
@@ -1,4 +1,4 @@
-/*     $Id: cgi.c,v 1.8 2011/11/27 11:46:44 kristaps Exp $ */
+/*     $Id: cgi.c,v 1.9 2011/12/04 22:52:50 kristaps Exp $ */
 /*
  * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -66,6 +66,7 @@ struct        req {
 };
 
 static int              atou(const char *, unsigned *);
+static void             catman(const char *);
 static void             format(const char *);
 static void             html_print(const char *);
 static int              kval_decode(char *);
@@ -81,6 +82,7 @@ static        void             resp_bad(void);
 static void             resp_baddb(void);
 static void             resp_badexpr(const struct req *);
 static void             resp_badmanual(void);
+static void             resp_badpage(void);
 static void             resp_begin_html(int, const char *);
 static void             resp_begin_http(int, const char *);
 static void             resp_end_html(void);
@@ -320,7 +322,7 @@ resp_searchform(const struct req *req)
        puts("<!-- Begin search form. //-->");
        printf("<FORM ACTION=\"");
        html_print(progname);
-       printf("/search\" METHOD=\"get\">\n");
+       printf("/search.html\" METHOD=\"get\">\n");
        puts(" <FIELDSET>"                                      "\n"
             "  <INPUT TYPE=\"submit\" VALUE=\"Search:\">");
        printf("  Terms: <INPUT TYPE=\"text\" "
@@ -347,6 +349,15 @@ resp_index(const struct req *req)
        resp_end_html();
 }
 
+static void
+resp_badpage(void)
+{
+
+       resp_begin_html(404, "Not Found");
+       puts("<P>Page not found.</P>");
+       resp_end_html();
+}
+
 static void
 resp_badmanual(void)
 {
@@ -434,6 +445,29 @@ pg_index(const struct manpaths *ps, const struct req *req, char *path)
        resp_index(req);
 }
 
+static void
+catman(const char *file)
+{
+       int              fd;
+       char             buf[BUFSIZ];
+       ssize_t          ssz;
+
+       if (-1 == (fd = open(file, O_RDONLY, 0))) {
+               resp_baddb();
+               return;
+       }
+
+       resp_begin_http(200, NULL);
+
+       while ((ssz = read(fd, buf, BUFSIZ)) > 0)
+               write(STDOUT_FILENO, buf, (size_t)ssz);
+
+       if (ssz < 0)
+               perror(file);
+
+       close(fd);
+}
+
 static void
 format(const char *file)
 {
@@ -479,9 +513,10 @@ pg_show(const struct manpaths *ps, const struct req *req, char *path)
 {
        char            *sub;
        char             file[MAXPATHLEN];
+       const char      *fn, *cp;
        int              rc;
        unsigned int     vol, rec;
-       DB              *db;
+       DB              *idx;
        DBT              key, val;
 
        if (NULL == path) {
@@ -506,8 +541,8 @@ pg_show(const struct manpaths *ps, const struct req *req, char *path)
 
        /* Open the index recno(3) database. */
 
-       db = dbopen(file, O_RDONLY, 0, DB_RECNO, NULL);
-       if (NULL == db) {
+       idx = dbopen(file, O_RDONLY, 0, DB_RECNO, NULL);
+       if (NULL == idx) {
                resp_baddb();
                return;
        }
@@ -515,21 +550,30 @@ pg_show(const struct manpaths *ps, const struct req *req, char *path)
        key.data = &rec;
        key.size = 4;
 
-       if (0 != (rc = (*db->get)(db, &key, &val, 0))) {
+       if (0 != (rc = (*idx->get)(idx, &key, &val, 0))) {
                rc < 0 ? resp_baddb() : resp_badmanual();
-               (*db->close)(db);
-               return;
+               goto out;
        } 
 
-       /* Extra filename: the first nil-terminated entry. */
+       cp = (char *)val.data;
 
-       strlcpy(file, ps->paths[vol], MAXPATHLEN);
-       strlcat(file, "/", MAXPATHLEN);
-       strlcat(file, (char *)val.data, MAXPATHLEN);
-
-       (*db->close)(db);
-
-       format(file);
+       if (NULL == (fn = memchr(cp, '\0', val.size)))
+               resp_baddb();
+       else if (++fn - cp >= (int)val.size)
+               resp_baddb();
+       else if (NULL == memchr(fn, '\0', val.size - (fn - cp)))
+               resp_baddb();
+       else {
+               strlcpy(file, ps->paths[vol], MAXPATHLEN);
+               strlcat(file, "/", MAXPATHLEN);
+               strlcat(file, fn, MAXPATHLEN);
+               if (0 == strcmp(cp, "cat"))
+                       catman(file);
+               else
+                       format(file);
+       }
+out:
+       (*idx->close)(idx);
 }
 
 static void
@@ -670,7 +714,7 @@ main(void)
        /* Initialise MANPATH. */
 
        memset(&paths, 0, sizeof(struct manpaths));
-       manpath_manconf("etc/man.conf", &paths);
+       manpath_manconf("etc/catman.conf", &paths);
 
        /* Route pages. */
 
@@ -685,6 +729,7 @@ main(void)
                pg_show(&paths, &req, subpath);
                break;
        default:
+               resp_badpage();
                break;
        }