]> git.cameronkatri.com Git - mandoc.git/blobdiff - catman.c
Do not cast void pointers to pointers requiring alignment.
[mandoc.git] / catman.c
index 59dd50aed33e8801060ea591f4d273d45d9d4f73..aa185eb3b121f287296785252dccff270fbde11a 100644 (file)
--- a/catman.c
+++ b/catman.c
@@ -1,4 +1,4 @@
-/*     $Id: catman.c,v 1.1 2011/11/26 19:54:13 kristaps Exp $ */
+/*     $Id: catman.c,v 1.8 2011/12/18 18:51:01 kristaps Exp $ */
 /*
  * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  *
                exit(EXIT_FAILURE); \
        } while (/* CONSTCOND */0)
 
-static int              indexhtml(char *);
-static int              jobstart(const char *, const char *, pid_t *);
-static int              jobwait(pid_t);
-static int              manup(const struct manpaths *, const char *);
+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 *);
@@ -68,9 +66,9 @@ int
 main(int argc, char *argv[])
 {
        int              ch;
-       char            *aux, *base;
-       const char      *dir;
+       char            *aux, *base, *conf_file;
        struct manpaths  dirs;
+       char             buf[MAXPATHLEN];
        extern char     *optarg;
        extern int       optind;
 
@@ -81,10 +79,13 @@ main(int argc, char *argv[])
                ++progname;
 
        aux = base = NULL;
-       dir = "/var/www/cache/man.cgi";
+       xstrlcpy(buf, "/var/www/cache/man.cgi", MAXPATHLEN);
 
-       while (-1 != (ch = getopt(argc, argv, "fm:M:o:v")))
+       while (-1 != (ch = getopt(argc, argv, "C:fm:M:o:v")))
                switch (ch) {
+               case ('C'):
+                       conf_file = optarg;
+                       break;
                case ('f'):
                        force = 1;
                        break;
@@ -95,7 +96,7 @@ main(int argc, char *argv[])
                        base = optarg;
                        break;
                case ('o'):
-                       dir = optarg;
+                       xstrlcpy(buf, optarg, MAXPATHLEN);
                        break;
                case ('v'):
                        verbose++;
@@ -114,8 +115,8 @@ main(int argc, char *argv[])
        }
 
        memset(&dirs, 0, sizeof(struct manpaths));
-       manpath_parse(&dirs, base, aux);
-       ch = manup(&dirs, dir);
+       manpath_parse(&dirs, conf_file, base, aux);
+       ch = manup(&dirs, buf);
        manpath_free(&dirs);
        return(ch ? EXIT_SUCCESS : EXIT_FAILURE);
 }
@@ -126,6 +127,7 @@ usage(void)
        
        fprintf(stderr, "usage: %s "
                        "[-fv] "
+                       "[-C file] "
                        "[-o path] "
                        "[-m manpath] "
                        "[-M manpath]\n",
@@ -194,76 +196,16 @@ out:
        return(rc);
 }
 
-/*
- * Clean up existing child.
- * Return 1 if cleaned up fine (or none was started) and 0 otherwise.
- */
-static int
-jobwait(pid_t pid)
-{
-       int              st;
-
-       if (-1 == pid)
-               return(1);
-
-       if (-1 == waitpid(pid, &st, 0)) {
-               perror(NULL);
-               exit(EXIT_FAILURE);
-       }
-
-       return(WIFEXITED(st) && 0 == WEXITSTATUS(st));
-}
-
-/*
- * Start a job (child process), first making sure that the prior one has
- * finished.
- * Return 1 if the prior child exited and the new one started, else 0.
- */
-static int
-jobstart(const char *dst, const char *src, pid_t *pid)
-{
-       int              fd;
-
-       if ( ! jobwait(*pid))
-               return(0);
-
-       if (-1 == (*pid = fork())) {
-               perror(NULL);
-               exit(EXIT_FAILURE);
-       } else if (*pid > 0)
-               return(1);
-
-       if (-1 == (fd = open(dst, O_WRONLY|O_TRUNC|O_CREAT, 0644))) {
-               perror(dst);
-               exit(EXIT_FAILURE);
-       }
-
-       if (-1 == dup2(fd, STDOUT_FILENO)) {
-               perror(NULL);
-               exit(EXIT_FAILURE);
-       }
-
-       execlp("mandoc", "mandoc", "-T", "html", 
-                       "-O", "fragment",
-                       "-O", "man=man.cgi?expr=%N&sec=%S", 
-                       src, (char *)NULL);
-
-       perror("mandoc");
-       exit(EXIT_FAILURE);
-       /* NOTREACHED */
-}
-
 /*
  * 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 *dst)
+indexhtml(char *src, size_t ssz, char *dst, size_t dsz)
 {
-       DB              *db;
+       DB              *idx;
        DBT              key, val;
-       size_t           sz;
        int              c, rc;
        unsigned int     fl;
        const char      *f;
@@ -271,31 +213,41 @@ indexhtml(char *dst)
        char             fname[MAXPATHLEN];
        pid_t            pid;
 
-       sz = strlen(dst);
        pid = -1;
 
        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;
+               /*
+                * If the record is zero-length, then it's unassigned.
+                * Skip past these.
+                */
+               if (0 == val.size)
+                       continue;
 
-               dst[(int)sz] = '\0';
+               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(dst, ".html", MAXPATHLEN);
 
-               if (-1 == (rc = isnewer(dst, f))) {
-                       fprintf(stderr, "%s: Manpage missing\n", f);
+               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;
@@ -310,18 +262,19 @@ indexhtml(char *dst)
                }
 
                *d = '/';
-               if ( ! jobstart(dst, f, &pid))
+
+               if ( ! filecpy(dst, src))
                        break;
                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);
 
        return(1 == c ? 1 : -1);
 }
@@ -357,9 +310,9 @@ update(char *dst, char *src)
        if (verbose)
                printf("%s\n", dst);
 
-       dst[(int)dsz] = '\0';
+       dst[(int)dsz] = src[(int)ssz] = '\0';
 
-       return(indexhtml(dst));
+       return(indexhtml(src, ssz, dst, dsz));
 }
 
 /*
@@ -408,7 +361,7 @@ treecpy(char *dst, char *src)
  * Returns 1 on success, 0 on failure.
  */
 static int
-manup(const struct manpaths *dirs, const char *dir)
+manup(const struct manpaths *dirs, char *base)
 {
        char             dst[MAXPATHLEN],
                         src[MAXPATHLEN];
@@ -417,40 +370,33 @@ manup(const struct manpaths *dirs, const char *dir)
        size_t           sz;
        FILE            *f;
 
-       xstrlcpy(dst, dir, MAXPATHLEN);
-       xstrlcat(dst, "/etc", MAXPATHLEN);
+       /* 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, "/man.conf", MAXPATHLEN);
-
-       if (verbose)
-               printf("%s\n", dst);
-
+       xstrlcat(dst, "/catman.conf", MAXPATHLEN);
        if (NULL == (f = fopen(dst, "w"))) {
                perror(dst);
                return(0);
-       }
-
-       xstrlcpy(dst, dir, MAXPATHLEN);
-       sz = strlen(dst);
+       } 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)