summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--catman.8111
-rw-r--r--catman.c512
-rw-r--r--index.sgml18
4 files changed, 5 insertions, 638 deletions
diff --git a/Makefile b/Makefile
index 10221e4a..83b9544e 100644
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,7 @@ CFLAGS += -DUSE_WCHAR
# If your system has manpath(1), uncomment this. This is most any
# system that's not OpenBSD or NetBSD. If uncommented, manpage(1) and
# mandocdb(8) will use manpath(1) to get the MANPATH variable.
-#CFLAGS += -DUSE_MANPATH
+CFLAGS += -DUSE_MANPATH
# If your system supports static binaries only, uncomment this. This
# appears only to be BSD UNIX systems (Mac OS X has no support and Linux
diff --git a/catman.8 b/catman.8
deleted file mode 100644
index 241737b8..00000000
--- a/catman.8
+++ /dev/null
@@ -1,111 +0,0 @@
-.\" $Id$
-.\"
-.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate$
-.Dt CATMAN 8
-.Os
-.Sh NAME
-.Nm catman
-.Nd update a man.cgi manpage cache
-.Sh SYNOPSIS
-.Nm catman
-.Op Fl fv
-.Op Fl C Ar file
-.Op Fl M Ar manpath
-.Op Fl m Ar manpath
-.Op Fl o Ar path
-.Sh DESCRIPTION
-The
-.Nm
-utility updates cached manpages for a jailed
-.Xr man.cgi 7 .
-.Pp
-By default,
-.Nm
-searches for
-.Xr mandocdb 8
-databases in the default paths stipulated by
-.Xr man 1
-and updates the cache in
-.Pa /var/www/cache/man.cgi .
-.Pp
-Its arguments are as follows:
-.Bl -tag -width Ds
-.It Fl f
-Force an update to all files.
-.It Fl v
-Print each file being updated.
-.It Fl C Ar file
-Specify an alternative configuration
-.Ar file
-in
-.Xr man.conf 5
-format.
-.It Fl M Ar manpath
-Use the colon-separated path instead of the default list of paths
-searched for
-.Xr mandocdb 8
-databases.
-Invalid paths, or paths without manual databases, are ignored.
-.It Fl m Ar manpath
-Prepend the colon-separated paths to the list of paths searched
-for
-.Xr mandocdb 8
-databases.
-Invalid paths, or paths without manual databases, are ignored.
-.It Fl o Ar path
-Update into the directory tree under
-.Ar path .
-.El
-.Pp
-Cache updates occur when a
-.Xr mandocdb 8
-database is older than the cached copy unless
-.Fl f
-is specified, in which case files are always considered out of date.
-Cached manual pages are only updated if older than the master copy.
-.Sh ENVIRONMENT
-.Bl -tag -width Ds
-.It Ev MANPATH
-Colon-separated paths modifying the default list of paths searched for
-manual databases.
-Invalid paths, or paths without manual databases, are ignored.
-Overridden by
-.Fl M .
-If
-.Ev MANPATH
-begins with a
-.Sq \&: ,
-it is appended to the default list;
-else if it ends with
-.Sq \&: ,
-it is prepended to the default list; else if it contains
-.Sq \&:: ,
-the default list is inserted between the colons.
-If none of these conditions are met, it overrides the default list.
-.El
-.Sh EXIT STATUS
-.Ex -std
-.Sh SEE ALSO
-.Xr mandoc 1 ,
-.Xr man.cgi 7 ,
-.Xr mandocdb 8
-.Sh AUTHORS
-The
-.Nm
-utility was written by
-.An Kristaps Dzonsons ,
-.Mt kristaps@bsd.lv .
diff --git a/catman.c b/catman.c
deleted file mode 100644
index bde01c10..00000000
--- a/catman.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#ifdef __linux__
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#include "manpath.h"
-#include "mandocdb.h"
-
-#define xstrlcpy(_dst, _src, _sz) \
- do if (strlcpy((_dst), (_src), (_sz)) >= (_sz)) { \
- fprintf(stderr, "%s: Path too long", (_dst)); \
- exit(EXIT_FAILURE); \
- } while (/* CONSTCOND */0)
-
-#define xstrlcat(_dst, _src, _sz) \
- do if (strlcat((_dst), (_src), (_sz)) >= (_sz)) { \
- fprintf(stderr, "%s: Path too long", (_dst)); \
- exit(EXIT_FAILURE); \
- } while (/* CONSTCOND */0)
-
-static int indexhtml(char *, size_t, char *, size_t);
-static int manup(const struct manpaths *, char *);
-static int mkpath(char *, mode_t, mode_t);
-static int treecpy(char *, char *);
-static int update(char *, char *);
-static void usage(void);
-
-static const char *progname;
-static int verbose;
-static int force;
-
-int
-main(int argc, char *argv[])
-{
- int ch;
- char *aux, *base, *conf_file;
- struct manpaths dirs;
- char buf[MAXPATHLEN];
- extern char *optarg;
- extern int optind;
-
- progname = strrchr(argv[0], '/');
- if (progname == NULL)
- progname = argv[0];
- else
- ++progname;
-
- aux = base = conf_file = NULL;
- xstrlcpy(buf, "/var/www/cache/man.cgi", MAXPATHLEN);
-
- while (-1 != (ch = getopt(argc, argv, "C:fm:M:o:v")))
- switch (ch) {
- case ('C'):
- conf_file = optarg;
- break;
- case ('f'):
- force = 1;
- break;
- case ('m'):
- aux = optarg;
- break;
- case ('M'):
- base = optarg;
- break;
- case ('o'):
- xstrlcpy(buf, optarg, MAXPATHLEN);
- break;
- case ('v'):
- verbose++;
- break;
- default:
- usage();
- return(EXIT_FAILURE);
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc > 0) {
- usage();
- return(EXIT_FAILURE);
- }
-
- memset(&dirs, 0, sizeof(struct manpaths));
- manpath_parse(&dirs, conf_file, base, aux);
- ch = manup(&dirs, buf);
- manpath_free(&dirs);
- return(ch ? EXIT_SUCCESS : EXIT_FAILURE);
-}
-
-static void
-usage(void)
-{
-
- fprintf(stderr, "usage: %s "
- "[-fv] "
- "[-C file] "
- "[-o path] "
- "[-m manpath] "
- "[-M manpath]\n",
- progname);
-}
-
-/*
- * If "src" file doesn't exist (errors out), return -1. Otherwise,
- * return 1 if "src" is newer (which also happens "dst" doesn't exist)
- * and 0 otherwise.
- */
-static int
-isnewer(const char *dst, const char *src)
-{
- struct stat s1, s2;
-
- if (-1 == stat(src, &s1))
- return(-1);
- if (force)
- return(1);
-
- return(-1 == stat(dst, &s2) ? 1 : s1.st_mtime > s2.st_mtime);
-}
-
-/*
- * Copy the contents of one file into another.
- * Returns 0 on failure, 1 on success.
- */
-static int
-filecpy(const char *dst, const char *src)
-{
- char buf[BUFSIZ];
- int sfd, dfd, rc;
- ssize_t rsz, wsz;
-
- sfd = dfd = -1;
- rc = 0;
-
- if (-1 == (dfd = open(dst, O_CREAT|O_TRUNC|O_WRONLY, 0644))) {
- perror(dst);
- goto out;
- } else if (-1 == (sfd = open(src, O_RDONLY, 0))) {
- perror(src);
- goto out;
- }
-
- while ((rsz = read(sfd, buf, BUFSIZ)) > 0)
- if (-1 == (wsz = write(dfd, buf, (size_t)rsz))) {
- perror(dst);
- goto out;
- } else if (wsz < rsz) {
- fprintf(stderr, "%s: Short write\n", dst);
- goto out;
- }
-
- if (rsz < 0)
- perror(src);
- else
- rc = 1;
-out:
- if (-1 != sfd)
- close(sfd);
- if (-1 != dfd)
- close(dfd);
-
- return(rc);
-}
-
-/*
- * Pass over the recno database and re-create HTML pages if they're
- * found to be out of date.
- * Returns -1 on fatal error, 1 on success.
- */
-static int
-indexhtml(char *src, size_t ssz, char *dst, size_t dsz)
-{
- DB *idx;
- DBT key, val;
- int c, rc;
- unsigned int fl;
- const char *f;
- char *d;
- char fname[MAXPATHLEN];
- pid_t pid;
-
- pid = -1;
-
- xstrlcpy(fname, dst, MAXPATHLEN);
- xstrlcat(fname, "/", MAXPATHLEN);
- xstrlcat(fname, MANDOC_IDX, MAXPATHLEN);
-
- idx = dbopen(fname, O_RDONLY, 0, DB_RECNO, NULL);
- if (NULL == idx) {
- perror(fname);
- return(-1);
- }
-
- fl = R_FIRST;
- while (0 == (c = (*idx->seq)(idx, &key, &val, fl))) {
- fl = R_NEXT;
- /*
- * If the record is zero-length, then it's unassigned.
- * Skip past these.
- */
- if (0 == val.size)
- continue;
-
- f = (const char *)val.data + 1;
- if (NULL == memchr(f, '\0', val.size - 1))
- break;
-
- src[(int)ssz] = dst[(int)dsz] = '\0';
-
- xstrlcat(dst, "/", MAXPATHLEN);
- xstrlcat(dst, f, MAXPATHLEN);
-
- xstrlcat(src, "/", MAXPATHLEN);
- xstrlcat(src, f, MAXPATHLEN);
-
- if (-1 == (rc = isnewer(dst, src))) {
- fprintf(stderr, "%s: File missing\n", f);
- break;
- } else if (0 == rc)
- continue;
-
- d = strrchr(dst, '/');
- assert(NULL != d);
- *d = '\0';
-
- if (-1 == mkpath(dst, 0755, 0755)) {
- perror(dst);
- break;
- }
-
- *d = '/';
-
- if ( ! filecpy(dst, src))
- break;
- if (verbose)
- printf("%s\n", dst);
- }
-
- (*idx->close)(idx);
-
- if (c < 0)
- perror(fname);
- else if (0 == c)
- fprintf(stderr, "%s: Corrupt index\n", fname);
-
- return(1 == c ? 1 : -1);
-}
-
-/*
- * Copy both recno and btree databases into the destination.
- * Call in to begin recreating HTML files.
- * Return -1 on fatal error and 1 if the update went well.
- */
-static int
-update(char *dst, char *src)
-{
- size_t dsz, ssz;
-
- dsz = strlen(dst);
- ssz = strlen(src);
-
- xstrlcat(src, "/", MAXPATHLEN);
- xstrlcat(dst, "/", MAXPATHLEN);
-
- xstrlcat(src, MANDOC_DB, MAXPATHLEN);
- xstrlcat(dst, MANDOC_DB, MAXPATHLEN);
-
- if ( ! filecpy(dst, src))
- return(-1);
- if (verbose)
- printf("%s\n", dst);
-
- dst[(int)dsz] = src[(int)ssz] = '\0';
-
- xstrlcat(src, "/", MAXPATHLEN);
- xstrlcat(dst, "/", MAXPATHLEN);
-
- xstrlcat(src, MANDOC_IDX, MAXPATHLEN);
- xstrlcat(dst, MANDOC_IDX, MAXPATHLEN);
-
- if ( ! filecpy(dst, src))
- return(-1);
- if (verbose)
- printf("%s\n", dst);
-
- dst[(int)dsz] = src[(int)ssz] = '\0';
-
- return(indexhtml(src, ssz, dst, dsz));
-}
-
-/*
- * See if btree or recno databases in the destination are out of date
- * with respect to a single manpath component.
- * Return -1 on fatal error, 0 if the source is no longer valid (and
- * shouldn't be listed), and 1 if the update went well.
- */
-static int
-treecpy(char *dst, char *src)
-{
- size_t dsz, ssz;
- int rc;
-
- dsz = strlen(dst);
- ssz = strlen(src);
-
- xstrlcat(src, "/", MAXPATHLEN);
- xstrlcat(dst, "/", MAXPATHLEN);
-
- xstrlcat(src, MANDOC_IDX, MAXPATHLEN);
- xstrlcat(dst, MANDOC_IDX, MAXPATHLEN);
-
- if (-1 == (rc = isnewer(dst, src)))
- return(0);
-
- dst[(int)dsz] = src[(int)ssz] = '\0';
-
- if (1 == rc)
- return(update(dst, src));
-
- xstrlcat(src, "/", MAXPATHLEN);
- xstrlcat(dst, "/", MAXPATHLEN);
-
- xstrlcat(src, MANDOC_DB, MAXPATHLEN);
- xstrlcat(dst, MANDOC_DB, MAXPATHLEN);
-
- if (-1 == (rc = isnewer(dst, src)))
- return(0);
- else if (rc == 0)
- return(1);
-
- dst[(int)dsz] = src[(int)ssz] = '\0';
-
- return(update(dst, src));
-}
-
-/*
- * Update the destination's file-tree with respect to changes in the
- * source manpath components.
- * "Change" is defined by an updated index or btree database.
- * Returns 1 on success, 0 on failure.
- */
-static int
-manup(const struct manpaths *dirs, char *base)
-{
- char dst[MAXPATHLEN],
- src[MAXPATHLEN];
- const char *path;
- size_t i;
- int c;
- size_t sz;
- FILE *f;
-
- /* Create the path and file for the catman.conf file. */
-
- sz = strlen(base);
- xstrlcpy(dst, base, MAXPATHLEN);
- xstrlcat(dst, "/etc", MAXPATHLEN);
- if (-1 == mkpath(dst, 0755, 0755)) {
- perror(dst);
- return(0);
- }
-
- xstrlcat(dst, "/catman.conf", MAXPATHLEN);
- if (NULL == (f = fopen(dst, "w"))) {
- perror(dst);
- return(0);
- } else if (verbose)
- printf("%s\n", dst);
-
- for (i = 0; i < dirs->sz; i++) {
- path = dirs->paths[i];
- dst[(int)sz] = '\0';
- xstrlcat(dst, path, MAXPATHLEN);
- if (-1 == mkpath(dst, 0755, 0755)) {
- perror(dst);
- break;
- }
-
- xstrlcpy(src, path, MAXPATHLEN);
- if (-1 == (c = treecpy(dst, src)))
- break;
- else if (0 == c)
- continue;
-
- /*
- * We want to use a relative path here because manpath.h
- * will realpath() when invoked with man.cgi, and we'll
- * make sure to chdir() into the cache directory before.
- *
- * This allows the cache directory to be in an arbitrary
- * place, working in both chroot() and non-chroot()
- * "safe" modes.
- */
- assert('/' == path[0]);
- fprintf(f, "_whatdb %s/whatis.db\n", path + 1);
- }
-
- fclose(f);
- return(i == dirs->sz);
-}
-
-/*
- * Copyright (c) 1983, 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-static int
-mkpath(char *path, mode_t mode, mode_t dir_mode)
-{
- struct stat sb;
- char *slash;
- int done, exists;
-
- slash = path;
-
- for (;;) {
- /* LINTED */
- slash += strspn(slash, "/");
- /* LINTED */
- slash += strcspn(slash, "/");
-
- done = (*slash == '\0');
- *slash = '\0';
-
- /* skip existing path components */
- exists = !stat(path, &sb);
- if (!done && exists && S_ISDIR(sb.st_mode)) {
- *slash = '/';
- continue;
- }
-
- if (mkdir(path, done ? mode : dir_mode) == 0) {
- if (mode > 0777 && chmod(path, mode) < 0)
- return (-1);
- } else {
- if (!exists) {
- /* Not there */
- return (-1);
- }
- if (!S_ISDIR(sb.st_mode)) {
- /* Is there, but isn't a directory */
- errno = ENOTDIR;
- return (-1);
- }
- }
-
- if (done)
- break;
-
- *slash = '/';
- }
-
- return (0);
-}
diff --git a/index.sgml b/index.sgml
index e4e53dc4..706027ff 100644
--- a/index.sgml
+++ b/index.sgml
@@ -37,7 +37,7 @@
<A HREF="demandoc.1.html">demandoc</A>, for emitting only text parts of manuals;
<A HREF="mandocdb.8.html">mandocdb</A>, for indexing manuals; and
<A HREF="apropos.1.html">apropos</A>, <A HREF="whatis.1.html">whatis</A>, and
- <A HREF="man.cgi.7.html">man.cgi</A> (via <A HREF="catman.8.html">catman</A>) for semantic search of manual content.
+ <A HREF="man.cgi.7.html">man.cgi</A> for semantic search of manual content.
It is a <A CLASS="external" HREF="http://bsd.lv/">BSD.lv</A> project.
</P>
<P>
@@ -49,8 +49,8 @@
<P>
<SPAN CLASS="nm">mdocml</SPAN> is in plain-old ANSI C and should build and run on any modern system; however, you'll
need <A HREF="http://www.oracle.com/technetwork/database/berkeleydb/overview/index.html">libdb</A> to build <A
- HREF="apropos.1.html">apropos</A>, <A HREF="whatis.1.html">whatis</A>, <A HREF="man.cgi.7.html">man.cgi</A>, <A
- HREF="catman.8.html">catman</A>, and <A HREF="mandocdb.8.html">mandocdb</A> (this is installed by default on BSD UNIX
+ HREF="apropos.1.html">apropos</A>, <A HREF="whatis.1.html">whatis</A>, <A HREF="man.cgi.7.html">man.cgi</A>,
+ and <A HREF="mandocdb.8.html">mandocdb</A> (this is installed by default on BSD UNIX
systems &mdash; see the <I>Makefile</I> if you're running Linux). To build and install into <I>/usr/local/</I>, just
run <CODE>make install</CODE>. Be careful: the <B>preconv</B>, <B>apropos</B>, and <B>whatis</B> binary names are
usually taken by existing utilities.
@@ -249,16 +249,6 @@
</TD>
</TR>
<TR>
- <TD VALIGN="top"><A HREF="catman.8.html">catman(8)</A></TD>
- <TD VALIGN="top">
- update a man.cgi manpage cache
- (<A HREF="catman.8.txt">text</A> |
- <A HREF="catman.8.xhtml">xhtml</A> |
- <A HREF="catman.8.pdf">pdf</A> |
- <A HREF="catman.8.ps">ps</A>)
- </TD>
- </TR>
- <TR>
<TD VALIGN="top"><A HREF="mandocdb.8.html">mandocdb(8)</A></TD>
<TD VALIGN="top">
index UNIX manuals
@@ -328,7 +318,7 @@
</P>
<P>
The <A HREF="man.cgi.7.html">man.cgi</A> script is also now available for wider testing. It interfaces with <A
- HREF="mandocdb.8.html">mandocdb</A> manuals cached by <A HREF="catman.8.html">catman</A>. HTML output is generated
+ HREF="mandocdb.8.html">mandocdb</A> manuals cached by <DEL><A HREF="catman.8.html">catman</A></DEL>. HTML output is generated
on-the-fly by <A HREF="mandoc.3.html">libmandoc</A> or internal methods to convert pre-formatted pages.
</P>
<P>