=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/mandocdb.c,v retrieving revision 1.40 retrieving revision 1.41 diff -c -r1.40 -r1.41 *** src/usr.bin/mandoc/mandocdb.c 2012/04/15 13:26:14 1.40 --- src/usr.bin/mandoc/mandocdb.c 2012/04/18 01:41:41 1.41 *************** *** 1,4 **** ! /* $Id: mandocdb.c,v 1.40 2012/04/15 13:26:14 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * Copyright (c) 2011 Ingo Schwarze --- 1,4 ---- ! /* $Id: mandocdb.c,v 1.41 2012/04/18 01:41:41 deraadt Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * Copyright (c) 2011 Ingo Schwarze *************** *** 43,57 **** #define MANDOC_SRC 0x1 #define MANDOC_FORM 0x2 - #define WARNING(_f, _b, _fmt, _args...) \ - do if (warnings) { \ - fprintf(stderr, "%s: ", (_b)); \ - fprintf(stderr, (_fmt), ##_args); \ - if ('\0' != *(_f)) \ - fprintf(stderr, ": %s", (_f)); \ - fprintf(stderr, "\n"); \ - } while (/* CONSTCOND */ 0) - /* Access to the mandoc database on disk. */ struct mdb { --- 43,48 ---- *************** *** 120,136 **** static void hash_reset(DB **); static void index_merge(const struct of *, struct mparse *, struct buf *, struct buf *, DB *, ! struct mdb *, struct recs *, ! const char *); static void index_prune(const struct of *, struct mdb *, ! struct recs *, const char *); ! static void ofile_argbuild(int, char *[], ! struct of **, const char *); static void ofile_dirbuild(const char *, const char *, ! const char *, int, struct of **, char *); static void ofile_free(struct of *); ! static void pformatted(DB *, struct buf *, struct buf *, ! const struct of *, const char *); static int pman_node(MAN_ARGS); static void pmdoc_node(MDOC_ARGS); static int pmdoc_head(MDOC_ARGS); --- 111,126 ---- static void hash_reset(DB **); static void index_merge(const struct of *, struct mparse *, struct buf *, struct buf *, DB *, ! struct mdb *, struct recs *); static void index_prune(const struct of *, struct mdb *, ! struct recs *); ! static void ofile_argbuild(int, char *[], struct of **, ! const char *); static void ofile_dirbuild(const char *, const char *, ! const char *, int, struct of **); static void ofile_free(struct of *); ! static void pformatted(DB *, struct buf *, ! struct buf *, const struct of *); static int pman_node(MAN_ARGS); static void pmdoc_node(MDOC_ARGS); static int pmdoc_head(MDOC_ARGS); *************** *** 291,298 **** struct recs recs; enum op op; /* current operation */ const char *dir; int ch, i, flags; - char dirbuf[MAXPATHLEN]; DB *hash; /* temporary keyword hashtable */ BTREEINFO info; /* btree configuration */ size_t sz1, sz2; --- 281,289 ---- struct recs recs; enum op op; /* current operation */ const char *dir; + char *cp; + char pbuf[PATH_MAX]; int ch, i, flags; DB *hash; /* temporary keyword hashtable */ BTREEINFO info; /* btree configuration */ size_t sz1, sz2; *************** *** 394,418 **** dbuf.cp = mandoc_malloc(dbuf.size); if (OP_TEST == op) { ! ofile_argbuild(argc, argv, &of, "."); if (NULL == of) goto out; ! index_merge(of, mp, &dbuf, &buf, ! hash, &mdb, &recs, "."); goto out; } if (OP_UPDATE == op || OP_DELETE == op) { ! strlcat(mdb.dbn, dir, MAXPATHLEN); ! strlcat(mdb.dbn, "/", MAXPATHLEN); sz1 = strlcat(mdb.dbn, MANDOC_DB, MAXPATHLEN); ! strlcat(mdb.idxn, dir, MAXPATHLEN); ! strlcat(mdb.idxn, "/", MAXPATHLEN); sz2 = strlcat(mdb.idxn, MANDOC_IDX, MAXPATHLEN); if (sz1 >= MAXPATHLEN || sz2 >= MAXPATHLEN) { ! fprintf(stderr, "%s: path too long\n", dir); exit((int)MANDOCLEVEL_BADARG); } --- 385,415 ---- dbuf.cp = mandoc_malloc(dbuf.size); if (OP_TEST == op) { ! ofile_argbuild(argc, argv, &of, NULL); if (NULL == of) goto out; ! index_merge(of, mp, &dbuf, &buf, hash, &mdb, &recs); goto out; } if (OP_UPDATE == op || OP_DELETE == op) { ! if (NULL == realpath(dir, pbuf)) { ! perror(dir); ! exit((int)MANDOCLEVEL_BADARG); ! } ! if (strlcat(pbuf, "/", PATH_MAX) >= PATH_MAX) { ! fprintf(stderr, "%s: path too long\n", pbuf); ! exit((int)MANDOCLEVEL_BADARG); ! } ! ! strlcat(mdb.dbn, pbuf, MAXPATHLEN); sz1 = strlcat(mdb.dbn, MANDOC_DB, MAXPATHLEN); ! strlcat(mdb.idxn, pbuf, MAXPATHLEN); sz2 = strlcat(mdb.idxn, MANDOC_IDX, MAXPATHLEN); if (sz1 >= MAXPATHLEN || sz2 >= MAXPATHLEN) { ! fprintf(stderr, "%s: path too long\n", mdb.idxn); exit((int)MANDOCLEVEL_BADARG); } *************** *** 428,439 **** exit((int)MANDOCLEVEL_SYSERR); } ! ofile_argbuild(argc, argv, &of, dir); if (NULL == of) goto out; ! index_prune(of, &mdb, &recs, dir); /* * Go to the root of the respective manual tree. --- 425,436 ---- exit((int)MANDOCLEVEL_SYSERR); } ! ofile_argbuild(argc, argv, &of, pbuf); if (NULL == of) goto out; ! index_prune(of, &mdb, &recs); /* * Go to the root of the respective manual tree. *************** *** 447,453 **** exit((int)MANDOCLEVEL_SYSERR); } index_merge(of, mp, &dbuf, &buf, hash, ! &mdb, &recs, dir); } goto out; --- 444,450 ---- exit((int)MANDOCLEVEL_SYSERR); } index_merge(of, mp, &dbuf, &buf, hash, ! &mdb, &recs); } goto out; *************** *** 462,473 **** if (argc > 0) { dirs.paths = mandoc_calloc(argc, sizeof(char *)); dirs.sz = argc; ! for (i = 0; i < argc; i++) ! dirs.paths[i] = mandoc_strdup(argv[i]); } else manpath_parse(&dirs, dir, NULL, NULL); for (i = 0; i < dirs.sz; i++) { /* * Go to the root of the respective manual tree. * This must work or no manuals may be found: --- 459,476 ---- if (argc > 0) { dirs.paths = mandoc_calloc(argc, sizeof(char *)); dirs.sz = argc; ! for (i = 0; i < argc; i++) { ! if (NULL == (cp = realpath(argv[i], pbuf))) { ! perror(argv[i]); ! goto out; ! } ! dirs.paths[i] = mandoc_strdup(cp); ! } } else manpath_parse(&dirs, dir, NULL, NULL); for (i = 0; i < dirs.sz; i++) { + /* * Go to the root of the respective manual tree. * This must work or no manuals may be found: *************** *** 517,528 **** * Search for manuals and fill the new database. */ ! strlcpy(dirbuf, dirs.paths[i], MAXPATHLEN); ! ofile_dirbuild(".", "", "", 0, &of, dirbuf); if (NULL != of) { index_merge(of, mp, &dbuf, &buf, hash, ! &mdb, &recs, dirs.paths[i]); ofile_free(of); of = NULL; } --- 520,530 ---- * Search for manuals and fill the new database. */ ! ofile_dirbuild(".", "", "", 0, &of); if (NULL != of) { index_merge(of, mp, &dbuf, &buf, hash, ! &mdb, &recs); ofile_free(of); of = NULL; } *************** *** 573,579 **** usage: fprintf(stderr, ! "usage: %s [-av] [-C file] | dir ... | -t file ...\n" " -d dir [file ...] | " "-u dir [file ...]\n", progname); --- 575,581 ---- usage: fprintf(stderr, ! "usage: %s [-avvv] [-C file] | dir ... | -t file ...\n" " -d dir [file ...] | " "-u dir [file ...]\n", progname); *************** *** 584,601 **** void index_merge(const struct of *of, struct mparse *mp, struct buf *dbuf, struct buf *buf, DB *hash, ! struct mdb *mdb, struct recs *recs, ! const char *basedir) { recno_t rec; int ch, skip; DBT key, val; DB *files; /* temporary file name table */ - char emptystring[1] = {'\0'}; struct mdoc *mdoc; struct man *man; - char *p; const char *fn, *msec, *march, *mtitle; uint64_t mask; size_t sv; unsigned seq; --- 586,601 ---- void index_merge(const struct of *of, struct mparse *mp, struct buf *dbuf, struct buf *buf, DB *hash, ! struct mdb *mdb, struct recs *recs) { recno_t rec; int ch, skip; DBT key, val; DB *files; /* temporary file name table */ struct mdoc *mdoc; struct man *man; const char *fn, *msec, *march, *mtitle; + char *p; uint64_t mask; size_t sv; unsigned seq; *************** *** 655,663 **** skip = 0; assert(of->sec); assert(msec); ! if (strcasecmp(msec, of->sec)) ! WARNING(fn, basedir, "Section \"%s\" manual " ! "in \"%s\" directory", msec, of->sec); /* * Manual page directories exist for each kernel * architecture as returned by machine(1). --- 655,667 ---- skip = 0; assert(of->sec); assert(msec); ! if (warnings) ! if (strcasecmp(msec, of->sec)) ! fprintf(stderr, "%s: " ! "section \"%s\" manual " ! "in \"%s\" directory\n", ! fn, msec, of->sec); ! /* * Manual page directories exist for each kernel * architecture as returned by machine(1). *************** *** 675,684 **** assert(of->arch); assert(march); ! if (strcasecmp(march, of->arch)) ! WARNING(fn, basedir, "Architecture \"%s\" " ! "manual in \"%s\" directory", ! march, of->arch); /* * By default, skip a file if the title given --- 679,690 ---- assert(of->arch); assert(march); ! if (warnings) ! if (strcasecmp(march, of->arch)) ! fprintf(stderr, "%s: " ! "architecture \"%s\" manual " ! "in \"%s\" directory\n", ! fn, march, of->arch); /* * By default, skip a file if the title given *************** *** 714,720 **** val.data = NULL; val.size = 0; if (0 == skip) ! val.data = emptystring; else { ch = (*files->get)(files, &key, &val, 0); if (ch < 0) { --- 720,726 ---- val.data = NULL; val.size = 0; if (0 == skip) ! val.data = ""; else { ch = (*files->get)(files, &key, &val, 0); if (ch < 0) { *************** *** 768,774 **** else if (man) pman_node(hash, buf, dbuf, man_node(man)); else ! pformatted(hash, buf, dbuf, of, basedir); /* Test mode, do not access any database. */ --- 774,780 ---- else if (man) pman_node(hash, buf, dbuf, man_node(man)); else ! pformatted(hash, buf, dbuf, of); /* Test mode, do not access any database. */ *************** *** 815,820 **** --- 821,828 ---- } if (ch < 0) { perror("hash"); + unlink(mdb->dbn); + unlink(mdb->idxn); exit((int)MANDOCLEVEL_SYSERR); } *************** *** 833,839 **** val.size = dbuf->len; if (verb) ! printf("%s: Adding to index: %s\n", basedir, fn); dbt_put(mdb->idx, mdb->idxn, &key, &val); } --- 841,847 ---- val.size = dbuf->len; if (verb) ! printf("%s: adding to index\n", fn); dbt_put(mdb->idx, mdb->idxn, &key, &val); } *************** *** 848,856 **** while (0 == (*files->seq)(files, &key, &val, seq)) { seq = R_NEXT; if (val.size) ! WARNING((char *)val.data, basedir, ! "Probably unreachable, title " ! "is %s", (char *)key.data); } (*files->close)(files); } --- 856,864 ---- while (0 == (*files->seq)(files, &key, &val, seq)) { seq = R_NEXT; if (val.size) ! fprintf(stderr, "%s: probably " ! "unreachable, title is %s\n", ! (char *)val.data, (char *)key.data); } (*files->close)(files); } *************** *** 863,870 **** * in `idx' (zeroing its value size). */ static void ! index_prune(const struct of *ofile, struct mdb *mdb, ! struct recs *recs, const char *basedir) { const struct of *of; const char *fn; --- 871,877 ---- * in `idx' (zeroing its value size). */ static void ! index_prune(const struct of *ofile, struct mdb *mdb, struct recs *recs) { const struct of *of; const char *fn; *************** *** 939,946 **** } if (verb) ! printf("%s: Deleting from index: %s\n", ! basedir, fn); val.size = 0; ch = (*mdb->idx->put)(mdb->idx, &key, &val, R_CURSOR); --- 946,952 ---- } if (verb) ! printf("%s: deleting from index\n", fn); val.size = 0; ch = (*mdb->idx->put)(mdb->idx, &key, &val, R_CURSOR); *************** *** 1500,1514 **** * By necessity, this involves rather crude guesswork. */ static void ! pformatted(DB *hash, struct buf *buf, struct buf *dbuf, ! const struct of *of, const char *basedir) { FILE *stream; char *line, *p, *title; size_t len, plen, titlesz; if (NULL == (stream = fopen(of->fname, "r"))) { ! WARNING(of->fname, basedir, "%s", strerror(errno)); return; } --- 1506,1521 ---- * By necessity, this involves rather crude guesswork. */ static void ! pformatted(DB *hash, struct buf *buf, ! struct buf *dbuf, const struct of *of) { FILE *stream; char *line, *p, *title; size_t len, plen, titlesz; if (NULL == (stream = fopen(of->fname, "r"))) { ! if (warnings) ! perror(of->fname); return; } *************** *** 1563,1568 **** --- 1570,1576 ---- title[(int)titlesz - 1] = ' '; } + /* * If no page content can be found, or the input line * is already the next section header, or there is no *************** *** 1571,1578 **** */ if (NULL == title || '\0' == *title) { ! WARNING(of->fname, basedir, ! "Cannot find NAME section"); buf_appendb(dbuf, buf->cp, buf->size); hash_put(hash, buf, TYPE_Nd); fclose(stream); --- 1579,1587 ---- */ if (NULL == title || '\0' == *title) { ! if (warnings) ! fprintf(stderr, "%s: cannot find NAME section\n", ! of->fname); buf_appendb(dbuf, buf->cp, buf->size); hash_put(hash, buf, TYPE_Nd); fclose(stream); *************** *** 1593,1600 **** for (p += 2; ' ' == *p || '\b' == *p; p++) /* Skip to next word. */ ; } else { ! WARNING(of->fname, basedir, ! "No dash in title line"); p = title; } --- 1602,1610 ---- for (p += 2; ' ' == *p || '\b' == *p; p++) /* Skip to next word. */ ; } else { ! if (warnings) ! fprintf(stderr, "%s: no dash in title line\n", ! of->fname); p = title; } *************** *** 1621,1636 **** } static void ! ofile_argbuild(int argc, char *argv[], ! struct of **of, const char *basedir) { char buf[MAXPATHLEN]; const char *sec, *arch, *title; ! char *p; int i, src_form; struct of *nof; for (i = 0; i < argc; i++) { /* * Try to infer the manual section, architecture and --- 1631,1660 ---- } static void ! ofile_argbuild(int argc, char *argv[], struct of **of, ! const char *basedir) { char buf[MAXPATHLEN]; + char pbuf[PATH_MAX]; const char *sec, *arch, *title; ! char *relpath, *p; int i, src_form; struct of *nof; for (i = 0; i < argc; i++) { + if (NULL == (relpath = realpath(argv[i], pbuf))) { + perror(argv[i]); + continue; + } + if (NULL != basedir) { + if (strstr(pbuf, basedir) != pbuf) { + fprintf(stderr, "%s: file outside " + "base directory %s\n", + pbuf, basedir); + continue; + } + relpath = pbuf + strlen(basedir); + } /* * Try to infer the manual section, architecture and *************** *** 1639,1646 **** * cat
[/]/.0 */ ! if (strlcpy(buf, argv[i], sizeof(buf)) >= sizeof(buf)) { ! fprintf(stderr, "%s: Path too long\n", argv[i]); continue; } sec = arch = title = ""; --- 1663,1670 ---- * cat<section>[/<arch>]/<title>.0 */ ! if (strlcpy(buf, relpath, sizeof(buf)) >= sizeof(buf)) { ! fprintf(stderr, "%s: path too long\n", relpath); continue; } sec = arch = title = ""; *************** *** 1672,1679 **** break; } if ('\0' == *title) { ! WARNING(argv[i], basedir, ! "Cannot deduce title from filename"); title = buf; } --- 1696,1706 ---- break; } if ('\0' == *title) { ! if (warnings) ! fprintf(stderr, ! "%s: cannot deduce title " ! "from filename\n", ! relpath); title = buf; } *************** *** 1682,1688 **** */ nof = mandoc_calloc(1, sizeof(struct of)); ! nof->fname = mandoc_strdup(argv[i]); nof->sec = mandoc_strdup(sec); nof->arch = mandoc_strdup(arch); nof->title = mandoc_strdup(title); --- 1709,1715 ---- */ nof = mandoc_calloc(1, sizeof(struct of)); ! nof->fname = mandoc_strdup(relpath); nof->sec = mandoc_strdup(sec); nof->arch = mandoc_strdup(arch); nof->title = mandoc_strdup(title); *************** *** 1693,1700 **** */ if (verb > 1) ! printf("%s: scheduling\n", argv[i]); ! if (NULL == *of) { *of = nof; (*of)->first = nof; --- 1720,1726 ---- */ if (verb > 1) ! printf("%s: scheduling\n", relpath); if (NULL == *of) { *of = nof; (*of)->first = nof; *************** *** 1716,1722 **** */ static void ofile_dirbuild(const char *dir, const char* psec, const char *parch, ! int p_src_form, struct of **of, char *basedir) { char buf[MAXPATHLEN]; size_t sz; --- 1742,1748 ---- */ static void ofile_dirbuild(const char *dir, const char* psec, const char *parch, ! int p_src_form, struct of **of) { char buf[MAXPATHLEN]; size_t sz; *************** *** 1728,1734 **** int src_form; if (NULL == (d = opendir(dir))) { ! WARNING("", dir, "%s", strerror(errno)); return; } --- 1754,1761 ---- int src_form; if (NULL == (d = opendir(dir))) { ! if (warnings) ! perror(dir); return; } *************** *** 1758,1764 **** src_form |= MANDOC_FORM; sec = fn + 3; } else { ! WARNING(fn, basedir, "Bad section"); if (use_all) sec = fn; else --- 1785,1793 ---- src_form |= MANDOC_FORM; sec = fn + 3; } else { ! if (warnings) fprintf(stderr, ! "%s/%s: bad section\n", ! dir, fn); if (use_all) sec = fn; else *************** *** 1766,1778 **** } } else if ('\0' == *arch) { if (NULL != strchr(fn, '.')) { ! WARNING(fn, basedir, "Bad architecture"); if (0 == use_all) continue; } arch = fn; } else { ! WARNING(fn, basedir, "Excessive subdirectory"); if (0 == use_all) continue; } --- 1795,1810 ---- } } else if ('\0' == *arch) { if (NULL != strchr(fn, '.')) { ! if (warnings) fprintf(stderr, ! "%s/%s: bad architecture\n", ! dir, fn); if (0 == use_all) continue; } arch = fn; } else { ! if (warnings) fprintf(stderr, "%s/%s: " ! "excessive subdirectory\n", dir, fn); if (0 == use_all) continue; } *************** *** 1780,1813 **** buf[0] = '\0'; strlcat(buf, dir, MAXPATHLEN); strlcat(buf, "/", MAXPATHLEN); - strlcat(basedir, "/", MAXPATHLEN); - strlcat(basedir, fn, MAXPATHLEN); sz = strlcat(buf, fn, MAXPATHLEN); if (MAXPATHLEN <= sz) { ! WARNING(fn, basedir, "Path too long"); continue; } if (verb > 1) printf("%s: scanning\n", buf); ! ofile_dirbuild(buf, sec, arch, ! src_form, of, basedir); ! ! p = strrchr(basedir, '/'); ! *p = '\0'; continue; } if (DT_REG != dp->d_type) { ! WARNING(fn, basedir, "Not a regular file"); continue; } if (!strcmp(MANDOC_DB, fn) || !strcmp(MANDOC_IDX, fn)) continue; if ('\0' == *psec) { ! WARNING(fn, basedir, "File outside section"); if (0 == use_all) continue; } --- 1812,1846 ---- buf[0] = '\0'; strlcat(buf, dir, MAXPATHLEN); strlcat(buf, "/", MAXPATHLEN); sz = strlcat(buf, fn, MAXPATHLEN); if (MAXPATHLEN <= sz) { ! if (warnings) fprintf(stderr, "%s/%s: " ! "path too long\n", dir, fn); continue; } if (verb > 1) printf("%s: scanning\n", buf); ! ofile_dirbuild(buf, sec, arch, src_form, of); continue; } if (DT_REG != dp->d_type) { ! if (warnings) ! fprintf(stderr, ! "%s/%s: not a regular file\n", ! dir, fn); continue; } if (!strcmp(MANDOC_DB, fn) || !strcmp(MANDOC_IDX, fn)) continue; if ('\0' == *psec) { ! if (warnings) ! fprintf(stderr, ! "%s/%s: file outside section\n", ! dir, fn); if (0 == use_all) continue; } *************** *** 1820,1833 **** suffix = strrchr(fn, '.'); if (NULL == suffix) { ! WARNING(fn, basedir, "No filename suffix"); if (0 == use_all) continue; } else if ((MANDOC_SRC & src_form && strcmp(suffix + 1, psec)) || (MANDOC_FORM & src_form && strcmp(suffix + 1, "0"))) { ! WARNING(fn, basedir, "Wrong filename suffix"); if (0 == use_all) continue; if ('0' == suffix[1]) --- 1853,1872 ---- suffix = strrchr(fn, '.'); if (NULL == suffix) { ! if (warnings) ! fprintf(stderr, ! "%s/%s: no filename suffix\n", ! dir, fn); if (0 == use_all) continue; } else if ((MANDOC_SRC & src_form && strcmp(suffix + 1, psec)) || (MANDOC_FORM & src_form && strcmp(suffix + 1, "0"))) { ! if (warnings) ! fprintf(stderr, ! "%s/%s: wrong filename suffix\n", ! dir, fn); if (0 == use_all) continue; if ('0' == suffix[1]) *************** *** 1861,1867 **** strlcat(buf, "/", MAXPATHLEN); sz = strlcat(buf, fn, MAXPATHLEN); if (sz >= MAXPATHLEN) { ! WARNING(fn, basedir, "Path too long"); continue; } q = strrchr(buf, '.'); --- 1900,1908 ---- strlcat(buf, "/", MAXPATHLEN); sz = strlcat(buf, fn, MAXPATHLEN); if (sz >= MAXPATHLEN) { ! if (warnings) fprintf(stderr, ! "%s/%s: path too long\n", ! dir, fn); continue; } q = strrchr(buf, '.'); *************** *** 1869,1875 **** *q = '\0'; sz = strlcat(buf, psec, MAXPATHLEN); if (sz >= MAXPATHLEN) { ! WARNING(fn, basedir, "Path too long"); continue; } if (0 == access(buf, R_OK)) --- 1910,1918 ---- *q = '\0'; sz = strlcat(buf, psec, MAXPATHLEN); if (sz >= MAXPATHLEN) { ! if (warnings) fprintf(stderr, ! "%s/%s: path too long\n", ! dir, fn); continue; } if (0 == access(buf, R_OK)) *************** *** 1885,1891 **** } sz = strlcat(buf, fn, MAXPATHLEN); if (sz >= MAXPATHLEN) { ! WARNING(fn, basedir, "Path too long"); continue; } --- 1928,1935 ---- } sz = strlcat(buf, fn, MAXPATHLEN); if (sz >= MAXPATHLEN) { ! if (warnings) fprintf(stderr, ! "%s/%s: path too long\n", dir, fn); continue; }