From fe601f87b54c0e4c28459c08fb59627e673e2094 Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Thu, 1 Dec 2011 21:05:49 +0000 Subject: Fix mandocdb(8) to pass over the type when pruning the database. This fixed `-d' perpetually adding the same files. While here, clean up the code and document it. Remove -vv (complain if you want it back in). Document the error messages in a DIAGNOSTICS section of mandocdb(8). --- mandocdb.8 | 28 ++++++++++++++++++---- mandocdb.c | 80 ++++++++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 77 insertions(+), 31 deletions(-) diff --git a/mandocdb.8 b/mandocdb.8 index 48ae0d0a..4c0ef876 100644 --- a/mandocdb.8 +++ b/mandocdb.8 @@ -1,4 +1,4 @@ -.\" $Id: mandocdb.8,v 1.9 2011/11/29 11:17:47 kristaps Exp $ +.\" $Id: mandocdb.8,v 1.10 2011/12/01 21:05:49 kristaps Exp $ .\" .\" Copyright (c) 2011 Kristaps Dzonsons .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: November 29 2011 $ +.Dd $Mdocdate: December 1 2011 $ .Dt MANDOCDB 8 .Os .Sh NAME @@ -86,9 +86,7 @@ from the database in .Ar dir without truncating it. .It Fl v -Verbose operation. -Use once to display all files added or removed and twice for keywords as -well. +Display all files added or removed to the index. .El .Pp If fatal parse errors are encountered while parsing, the offending file @@ -230,6 +228,26 @@ Such errors cause to exit at once, possibly in the middle of parsing or formatting a file. The output databases are corrupt and should be removed . .El +.Sh DIAGNOSTICS +If the following errors occur, the +.Nm +databases should be rebuilt. +.Bl -diag +.It "%s: Corrupt database" +The keyword database file indicated by +.Pa %s +is unreadable. +.It "%s: Corrupt index" +The index database file indicated by +.Pa %s +is unreadable. +.It "%s: Path too long" +The file +.Pa %s +is too long. +This usually indicates database corruption or invalid command-line +arguments. +.El .Sh SEE ALSO .Xr man 1 , .Xr btree 3 , diff --git a/mandocdb.c b/mandocdb.c index c1daa2d8..8a3409ae 100644 --- a/mandocdb.c +++ b/mandocdb.c @@ -1,4 +1,4 @@ -/* $Id: mandocdb.c,v 1.17 2011/11/29 00:34:50 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.18 2011/12/01 21:05:49 kristaps Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * Copyright (c) 2011 Ingo Schwarze @@ -635,9 +635,6 @@ index_merge(const struct of *of, struct mparse *mp, val.size = sizeof(struct db_val); val.data = &vbuf; - if (verb > 1) - printf("%s: Added keyword: %s\n", - fn, (char *)key.data); dbt_put(db, dbf, &key, &val); } if (ch < 0) { @@ -661,6 +658,7 @@ index_merge(const struct of *of, struct mparse *mp, if (verb) printf("%s: Added index\n", fn); + dbt_put(idx, idxf, &key, &val); } } @@ -677,7 +675,7 @@ index_prune(const struct of *ofile, DB *db, const char *dbf, recno_t *maxrec, recno_t **recs, size_t *recsz) { const struct of *of; - const char *fn; + const char *fn, *cp; struct db_val *vbuf; unsigned seq, sseq; DBT key, val; @@ -689,18 +687,32 @@ index_prune(const struct of *ofile, DB *db, const char *dbf, while (0 == (ch = (*idx->seq)(idx, &key, &val, seq))) { seq = R_NEXT; *maxrec = *(recno_t *)key.data; - if (0 == val.size) { - if (reccur >= *recsz) { - *recsz += MANDOC_SLOP; - *recs = mandoc_realloc(*recs, - *recsz * sizeof(recno_t)); - } - (*recs)[(int)reccur] = *maxrec; - reccur++; - continue; - } + cp = val.data; + + /* Deleted records are zero-sized. Skip them. */ + + if (0 == val.size) + goto cont; + + /* + * Make sure we're sane. + * Read past our mdoc/man/cat type to the next string, + * then make sure it's bounded by a NUL. + * Failing any of these, we go into our error handler. + */ + + if (NULL == (fn = memchr(cp, '\0', val.size))) + break; + if (++fn - cp >= (int)val.size) + break; + if (NULL == memchr(fn, '\0', val.size - (fn - cp))) + break; + + /* + * Search for the file in those we care about. + * XXX: build this into a tree. Too slow. + */ - fn = (char *)val.data; for (of = ofile; of; of = of->next) if (0 == strcmp(fn, of->fname)) break; @@ -708,23 +720,31 @@ index_prune(const struct of *ofile, DB *db, const char *dbf, if (NULL == of) continue; + /* + * Search through the keyword database, throwing out all + * references to our file. + */ + sseq = R_FIRST; while (0 == (ch = (*db->seq)(db, &key, &val, sseq))) { sseq = R_NEXT; - assert(sizeof(struct db_val) == val.size); + if (sizeof(struct db_val) != val.size) + break; + vbuf = val.data; if (*maxrec != vbuf->rec) continue; - if (verb) - printf("%s: Deleted keyword: %s\n", - fn, (char *)key.data); - ch = (*db->del)(db, &key, R_CURSOR); - if (ch < 0) + + if ((ch = (*db->del)(db, &key, R_CURSOR)) < 0) break; } + if (ch < 0) { perror(dbf); exit((int)MANDOCLEVEL_SYSERR); + } else if (1 != ch) { + fprintf(stderr, "%s: Corrupt database\n", dbf); + exit((int)MANDOCLEVEL_SYSERR); } if (verb) @@ -732,11 +752,10 @@ index_prune(const struct of *ofile, DB *db, const char *dbf, val.size = 0; ch = (*idx->put)(idx, &key, &val, R_CURSOR); - if (ch < 0) { - perror(idxf); - exit((int)MANDOCLEVEL_SYSERR); - } + if (ch < 0) + break; +cont: if (reccur >= *recsz) { *recsz += MANDOC_SLOP; *recs = mandoc_realloc @@ -746,6 +765,15 @@ index_prune(const struct of *ofile, DB *db, const char *dbf, (*recs)[(int)reccur] = *maxrec; reccur++; } + + if (ch < 0) { + perror(idxf); + exit((int)MANDOCLEVEL_SYSERR); + } else if (1 != ch) { + fprintf(stderr, "%s: Corrupt index\n", idxf); + exit((int)MANDOCLEVEL_SYSERR); + } + (*maxrec)++; } -- cgit v1.2.3-56-ge451