=================================================================== RCS file: /cvs/mandoc/catman.c,v retrieving revision 1.1 retrieving revision 1.10 diff -u -p -r1.1 -r1.10 --- mandoc/catman.c 2011/11/26 19:54:13 1.1 +++ mandoc/catman.c 2012/01/03 15:17:20 1.10 @@ -1,4 +1,4 @@ -/* $Id: catman.c,v 1.1 2011/11/26 19:54:13 kristaps Exp $ */ +/* $Id: catman.c,v 1.10 2012/01/03 15:17:20 kristaps Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * @@ -38,6 +38,7 @@ #endif #include "manpath.h" +#include "mandocdb.h" #define xstrlcpy(_dst, _src, _sz) \ do if (strlcpy((_dst), (_src), (_sz)) >= (_sz)) { \ @@ -51,10 +52,8 @@ 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 +67,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; @@ -80,11 +79,14 @@ main(int argc, char *argv[]) else ++progname; - aux = base = NULL; - dir = "/var/www/cache/man.cgi"; + aux = base = conf_file = NULL; + 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 +97,7 @@ main(int argc, char *argv[]) base = optarg; break; case ('o'): - dir = optarg; + xstrlcpy(buf, optarg, MAXPATHLEN); break; case ('v'): verbose++; @@ -114,8 +116,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 +128,7 @@ usage(void) fprintf(stderr, "usage: %s " "[-fv] " + "[-C file] " "[-o path] " "[-m manpath] " "[-M manpath]\n", @@ -195,75 +198,15 @@ out: } /* - * 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 +214,42 @@ indexhtml(char *dst) char fname[MAXPATHLEN]; pid_t pid; - sz = strlen(dst); pid = -1; xstrlcpy(fname, dst, MAXPATHLEN); - xstrlcat(fname, "/mandoc.index", MAXPATHLEN); + xstrlcat(fname, "/", MAXPATHLEN); + xstrlcat(fname, MANDOC_IDX, 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 +264,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); } @@ -339,9 +294,12 @@ update(char *dst, char *src) dsz = strlen(dst); ssz = strlen(src); - xstrlcat(src, "/mandoc.db", MAXPATHLEN); - xstrlcat(dst, "/mandoc.db", MAXPATHLEN); + xstrlcat(src, "/", MAXPATHLEN); + xstrlcat(dst, "/", MAXPATHLEN); + xstrlcat(src, MANDOC_DB, MAXPATHLEN); + xstrlcat(dst, MANDOC_DB, MAXPATHLEN); + if ( ! filecpy(dst, src)) return(-1); if (verbose) @@ -349,17 +307,20 @@ update(char *dst, char *src) dst[(int)dsz] = src[(int)ssz] = '\0'; - xstrlcat(src, "/mandoc.index", MAXPATHLEN); - xstrlcat(dst, "/mandoc.index", MAXPATHLEN); + 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] = '\0'; + dst[(int)dsz] = src[(int)ssz] = '\0'; - return(indexhtml(dst)); + return(indexhtml(src, ssz, dst, dsz)); } /* @@ -377,9 +338,12 @@ treecpy(char *dst, char *src) dsz = strlen(dst); ssz = strlen(src); - xstrlcat(src, "/mandoc.index", MAXPATHLEN); - xstrlcat(dst, "/mandoc.index", MAXPATHLEN); + xstrlcat(src, "/", MAXPATHLEN); + xstrlcat(dst, "/", MAXPATHLEN); + xstrlcat(src, MANDOC_IDX, MAXPATHLEN); + xstrlcat(dst, MANDOC_IDX, MAXPATHLEN); + if (-1 == (rc = isnewer(dst, src))) return(0); @@ -388,9 +352,12 @@ treecpy(char *dst, char *src) if (1 == rc) return(update(dst, src)); - xstrlcat(src, "/mandoc.db", MAXPATHLEN); - xstrlcat(dst, "/mandoc.db", MAXPATHLEN); + 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) @@ -408,7 +375,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 +384,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); - } + } else if (verbose) + printf("%s\n", dst); - xstrlcpy(dst, dir, MAXPATHLEN); - sz = strlen(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)