summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2011-12-04 22:52:50 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2011-12-04 22:52:50 +0000
commit29ac73dafe481c332afcf1adc7c74cdad72433c9 (patch)
tree03391768196bba8fbd595f5df115e088730cf574
parentd894c471306c4cb24738dcc1d17fcaaccaec3df9 (diff)
downloadmandoc-29ac73dafe481c332afcf1adc7c74cdad72433c9.tar.gz
Make catman and man.cgi understand the index type-field.
Also make catman's man.conf be generated as catman.conf to avoid clobbering a real man.conf file. Finally, add a placeholder catman() function to man.cgi for preformatted manuals in the cache.
-rw-r--r--catman.84
-rw-r--r--catman.c42
-rw-r--r--cgi.c77
-rw-r--r--man.cgi.77
4 files changed, 94 insertions, 36 deletions
diff --git a/catman.8 b/catman.8
index 1be5659e..c211ce77 100644
--- a/catman.8
+++ b/catman.8
@@ -29,7 +29,8 @@
.Sh DESCRIPTION
The
.Nm
-utility updates cached manpages for a jailed man.cgi.
+utility updates cached manpages for a jailed
+.Xr man.cgi 7 .
Its arguments are as follows:
.Bl -tag -width Ds
.It Fl f
@@ -73,6 +74,7 @@ is specified, all files are updated.
.Ex -std
.Sh SEE ALSO
.Xr mandoc 1 ,
+.Xr man.cgi 7 ,
.Xr mandocdb 8
.Sh AUTHORS
The
diff --git a/catman.c b/catman.c
index 529d9055..7f19acec 100644
--- a/catman.c
+++ b/catman.c
@@ -265,12 +265,12 @@ jobstart(const char *dst, const char *src, pid_t *pid)
static int
indexhtml(char *dst)
{
- DB *db;
+ DB *idx;
DBT key, val;
size_t sz;
int c, rc;
unsigned int fl;
- const char *f;
+ const char *f, *cp;
char *d;
char fname[MAXPATHLEN];
pid_t pid;
@@ -281,25 +281,32 @@ indexhtml(char *dst)
xstrlcpy(fname, dst, MAXPATHLEN);
xstrlcat(fname, "/mandoc.index", MAXPATHLEN);
- db = dbopen(fname, O_RDONLY, 0, DB_RECNO, NULL);
- if (NULL == db) {
+ idx = dbopen(fname, O_RDONLY, 0, DB_RECNO, NULL);
+ if (NULL == idx) {
perror(fname);
return(-1);
}
fl = R_FIRST;
- while (0 == (c = (*db->seq)(db, &key, &val, fl))) {
+ while (0 == (c = (*idx->seq)(idx, &key, &val, fl))) {
fl = R_NEXT;
- f = (const char *)val.data;
+ cp = (const char *)val.data;
+ if (0 == val.size)
+ continue;
+ if (NULL == (f = memchr(cp, '\0', val.size)))
+ break;
+ if (++f - cp >= (int)val.size)
+ break;
+ if (NULL == memchr(f, '\0', val.size - (f - cp)))
+ break;
dst[(int)sz] = '\0';
xstrlcat(dst, "/", MAXPATHLEN);
xstrlcat(dst, f, MAXPATHLEN);
- /*xstrlcat(dst, ".html", MAXPATHLEN);*/
if (-1 == (rc = isnewer(dst, f))) {
- fprintf(stderr, "%s: Manpage missing\n", f);
+ fprintf(stderr, "%s: File missing\n", f);
break;
} else if (0 == rc)
continue;
@@ -317,19 +324,24 @@ indexhtml(char *dst)
if ( ! filecpy(dst, f))
break;
-
- /*if ( ! jobstart(dst, f, &pid))
- break;*/
+#if 0
+ if ( ! jobstart(dst, f, &pid))
+ break;
+#endif
if (verbose)
printf("%s\n", dst);
}
- (*db->close)(db);
+ (*idx->close)(idx);
if (c < 0)
perror(fname);
- /*if ( ! jobwait(pid))
- c = -1;*/
+ else if (0 == c)
+ fprintf(stderr, "%s: Corrupt index\n", fname);
+#if 0
+ if ( ! jobwait(pid))
+ c = -1;
+#endif
return(1 == c ? 1 : -1);
}
@@ -433,7 +445,7 @@ manup(const struct manpaths *dirs, const char *dir)
return(0);
}
- xstrlcat(dst, "/man.conf", MAXPATHLEN);
+ xstrlcat(dst, "/catman.conf", MAXPATHLEN);
if (verbose)
printf("%s\n", dst);
diff --git a/cgi.c b/cgi.c
index e395baf2..1637d0c2 100644
--- a/cgi.c
+++ b/cgi.c
@@ -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\" "
@@ -348,6 +350,15 @@ resp_index(const struct req *req)
}
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)
{
@@ -435,6 +446,29 @@ pg_index(const struct manpaths *ps, const struct req *req, char *path)
}
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)
{
struct mparse *mp;
@@ -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;
}
diff --git a/man.cgi.7 b/man.cgi.7
index 67be8101..630c7422 100644
--- a/man.cgi.7
+++ b/man.cgi.7
@@ -13,7 +13,7 @@ script queries and displays manual pages.
It interfaces with
.Xr mandocdb 8
databases for query and with
-.Xr mandoc 1
+.Xr mandoc 3
for display.
It operates over a cache of manuals generated by
.Xr catman 8 .
@@ -40,13 +40,12 @@ cache directory.
.El
.Sh FILES
The configuration file
-.Pa etc/man.conf
+.Pa etc/catman.conf
must exist within the cache directory.
This is built by
.Xr catman 8 .
.Sh SEE ALSO
-.Xr apropos 1 ,
-.Xr mandoc 1 ,
+.Xr mandoc 3 ,
.Xr catman 8 ,
.Xr mandocdb 8
.Sh AUTHORS