=================================================================== RCS file: /cvs/mandoc/mandocdb.c,v retrieving revision 1.16 retrieving revision 1.22 diff -u -p -r1.16 -r1.22 --- mandoc/mandocdb.c 2011/11/27 23:27:31 1.16 +++ mandoc/mandocdb.c 2011/12/03 12:09:07 1.22 @@ -1,4 +1,4 @@ -/* $Id: mandocdb.c,v 1.16 2011/11/27 23:27:31 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.22 2011/12/03 12:09:07 kristaps Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * Copyright (c) 2011 Ingo Schwarze @@ -31,9 +31,14 @@ #include #include #include +#include -#ifdef __linux__ +#if defined(__linux__) +# include # include +#elif defined(__APPLE__) +# include +# include #else # include #endif @@ -328,6 +333,7 @@ main(int argc, char *argv[]) argv += optind; memset(&info, 0, sizeof(BTREEINFO)); + info.lorder = 4321; info.flags = R_DUP; mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL); @@ -383,10 +389,18 @@ main(int argc, char *argv[]) index_prune(of, db, fbuf, idx, ibuf, &maxrec, &recs, &recsz); - if (OP_UPDATE == op) + /* + * Go to the root of the respective manual tree + * such that .so links work. In case of failure, + * just prod on, even though .so links won't work. + */ + + if (OP_UPDATE == op) { + chdir(dir); index_merge(of, mp, &dbuf, &buf, hash, db, fbuf, idx, ibuf, maxrec, recs, reccur); + } goto out; } @@ -455,6 +469,13 @@ main(int argc, char *argv[]) of = of->first; + /* + * Go to the root of the respective manual tree + * such that .so links work. In case of failure, + * just prod on, even though .so links won't work. + */ + + chdir(dirs.paths[i]); index_merge(of, mp, &dbuf, &buf, hash, db, fbuf, idx, ibuf, maxrec, recs, reccur); } @@ -610,18 +631,13 @@ index_merge(const struct of *of, struct mparse *mp, * into the database. */ - vbuf.rec = rec; + vbuf.rec = htobe32(rec); seq = R_FIRST; while (0 == (ch = (*hash->seq)(hash, &key, &val, seq))) { seq = R_NEXT; - - vbuf.mask = *(uint64_t *)val.data; + vbuf.mask = htobe64(*(uint64_t *)val.data); 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) { @@ -645,6 +661,7 @@ index_merge(const struct of *of, struct mparse *mp, if (verb) printf("%s: Added index\n", fn); + dbt_put(idx, idxf, &key, &val); } } @@ -661,7 +678,7 @@ index_prune(const struct of *ofile, DB *db, const char 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; @@ -673,18 +690,32 @@ index_prune(const struct of *ofile, DB *db, const char 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; - fn = (char *)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. + */ + for (of = ofile; of; of = of->next) if (0 == strcmp(fn, of->fname)) break; @@ -692,23 +723,31 @@ index_prune(const struct of *ofile, DB *db, const char 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) + if (*maxrec != betoh32(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) @@ -716,11 +755,10 @@ index_prune(const struct of *ofile, DB *db, const char 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 @@ -730,6 +768,15 @@ index_prune(const struct of *ofile, DB *db, const char (*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)++; }