=================================================================== RCS file: /cvs/mandoc/mandocdb.c,v retrieving revision 1.34 retrieving revision 1.37 diff -u -p -r1.34 -r1.37 --- mandoc/mandocdb.c 2011/12/12 02:00:49 1.34 +++ mandoc/mandocdb.c 2011/12/20 21:41:11 1.37 @@ -1,4 +1,4 @@ -/* $Id: mandocdb.c,v 1.34 2011/12/12 02:00:49 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.37 2011/12/20 21:41:11 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * Copyright (c) 2011 Ingo Schwarze @@ -21,7 +21,6 @@ #include #include -#include #include #include @@ -110,7 +109,7 @@ static void index_prune(const struct of *, DB *, recno_t *, recno_t **, size_t *, size_t *); static void ofile_argbuild(int, char *[], struct of **); -static int ofile_dirbuild(const char *, 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 *, @@ -384,12 +383,8 @@ main(int argc, char *argv[]) exit((int)MANDOCLEVEL_SYSERR); } - if (verb > 2) { - printf("%s: Opened\n", fbuf); - printf("%s: Opened\n", ibuf); - } - ofile_argbuild(argc, argv, &of); + if (NULL == of) goto out; @@ -399,13 +394,16 @@ main(int argc, char *argv[]) &maxrec, &recs, &recsz, &reccur); /* - * 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. + * Go to the root of the respective manual tree. + * This must work or no manuals may be found (they're + * indexed relative to the root). */ if (OP_UPDATE == op) { - chdir(dir); + if (-1 == chdir(dir)) { + perror(dir); + exit((int)MANDOCLEVEL_SYSERR); + } index_merge(of, mp, &dbuf, &buf, hash, db, fbuf, idx, ibuf, maxrec, recs, reccur); @@ -466,30 +464,32 @@ main(int argc, char *argv[]) exit((int)MANDOCLEVEL_SYSERR); } - if (verb > 2) { - printf("%s: Truncated\n", fbuf); - printf("%s: Truncated\n", ibuf); - } - ofile_free(of); of = NULL; - if ( ! ofile_dirbuild(dirs.paths[i], NULL, NULL, - 0, &of)) + if (-1 == chdir(dirs.paths[i])) { + perror(dirs.paths[i]); exit((int)MANDOCLEVEL_SYSERR); + } + ofile_dirbuild(".", NULL, NULL, 0, &of); + if (NULL == of) continue; 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. + * Go to the root of the respective manual tree. + * This must work or no manuals may be found (they're + * indexed relative to the root). */ - chdir(dirs.paths[i]); + if (-1 == chdir(dirs.paths[i])) { + perror(dirs.paths[i]); + exit((int)MANDOCLEVEL_SYSERR); + } + index_merge(of, mp, &dbuf, &buf, hash, db, fbuf, idx, ibuf, maxrec, recs, reccur); } @@ -525,9 +525,11 @@ index_merge(const struct of *of, struct mparse *mp, struct mdoc *mdoc; struct man *man; const char *fn, *msec, *mtitle, *arch; + uint64_t mask; size_t sv; unsigned seq; struct db_val vbuf; + char type; for (rec = 0; of; of = of->next) { fn = of->fname; @@ -608,7 +610,8 @@ index_merge(const struct of *of, struct mparse *mp, */ dbuf->len = 0; - buf_append(dbuf, mdoc ? "mdoc" : (man ? "man" : "cat")); + type = mdoc ? 'd' : (man ? 'a' : 'c'); + buf_appendb(dbuf, &type, 1); buf_appendb(dbuf, fn, strlen(fn) + 1); buf_appendb(dbuf, msec, strlen(msec) + 1); buf_appendb(dbuf, mtitle, strlen(mtitle) + 1); @@ -653,7 +656,9 @@ index_merge(const struct of *of, struct mparse *mp, seq = R_FIRST; while (0 == (ch = (*hash->seq)(hash, &key, &val, seq))) { seq = R_NEXT; - vbuf.mask = htobe64(*(uint64_t *)val.data); + assert(sizeof(uint64_t) == val.size); + memcpy(&mask, val.data, val.size); + vbuf.mask = htobe64(mask); val.size = sizeof(struct db_val); val.data = &vbuf; dbt_put(db, dbf, &key, &val); @@ -696,7 +701,7 @@ index_prune(const struct of *ofile, DB *db, const char recno_t **recs, size_t *recsz, size_t *reccur) { const struct of *of; - const char *fn, *cp; + const char *fn; struct db_val *vbuf; unsigned seq, sseq; DBT key, val; @@ -706,8 +711,8 @@ index_prune(const struct of *ofile, DB *db, const char seq = R_FIRST; while (0 == (ch = (*idx->seq)(idx, &key, &val, seq))) { seq = R_NEXT; - *maxrec = *(recno_t *)key.data; - cp = val.data; + assert(sizeof(recno_t) == key.size); + memcpy(maxrec, key.data, key.size); /* Deleted records are zero-sized. Skip them. */ @@ -721,12 +726,9 @@ index_prune(const struct of *ofile, DB *db, const char * Failing any of these, we go into our error handler. */ - if (NULL == (fn = memchr(cp, '\0', val.size))) + fn = (char *)val.data + 1; + if (NULL == memchr(fn, '\0', val.size - 1)) 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. @@ -1070,6 +1072,7 @@ pmdoc_Sh(MDOC_ARGS) static void hash_put(DB *db, const struct buf *buf, uint64_t mask) { + uint64_t oldmask; DBT key, val; int rc; @@ -1082,8 +1085,11 @@ hash_put(DB *db, const struct buf *buf, uint64_t mask) if ((rc = (*db->get)(db, &key, &val, 0)) < 0) { perror("hash"); exit((int)MANDOCLEVEL_SYSERR); - } else if (0 == rc) - mask |= *(uint64_t *)val.data; + } else if (0 == rc) { + assert(sizeof(uint64_t) == val.size); + memcpy(&oldmask, val.data, val.size); + mask |= oldmask; + } val.data = &mask; val.size = sizeof(uint64_t); @@ -1434,8 +1440,6 @@ ofile_argbuild(int argc, char *argv[], struct of **of) * Add the structure to the list. */ - if (verb > 2) - printf("%s: Scheduling\n", argv[i]); if (NULL == *of) { *of = nof; (*of)->first = nof; @@ -1455,12 +1459,11 @@ ofile_argbuild(int argc, char *argv[], struct of **of) * everything else is a manual. * Pass in a pointer to a NULL structure for the first invocation. */ -static int +static void ofile_dirbuild(const char *dir, const char* psec, const char *parch, int p_src_form, struct of **of) { char buf[MAXPATHLEN]; - struct stat sb; size_t sz; DIR *d; const char *fn, *sec, *arch; @@ -1471,7 +1474,7 @@ ofile_dirbuild(const char *dir, const char* psec, cons if (NULL == (d = opendir(dir))) { perror(dir); - return(0); + exit((int)MANDOCLEVEL_SYSERR); } while (NULL != (dp = readdir(d))) { @@ -1516,20 +1519,16 @@ ofile_dirbuild(const char *dir, const char* psec, cons if (MAXPATHLEN <= sz) { fprintf(stderr, "%s: Path too long\n", dir); - return(0); + exit((int)MANDOCLEVEL_SYSERR); } - if (verb > 2) - printf("%s: Scanning\n", buf); - - if ( ! ofile_dirbuild(buf, sec, arch, - src_form, of)) - return(0); + ofile_dirbuild(buf, sec, arch, src_form, of); } + if (DT_REG != dp->d_type || - (NULL == psec && !use_all) || - !strcmp(MANDOC_DB, fn) || - !strcmp(MANDOC_IDX, fn)) + (NULL == psec && !use_all) || + ! strcmp(MANDOC_DB, fn) || + ! strcmp(MANDOC_IDX, fn)) continue; /* @@ -1593,13 +1592,15 @@ ofile_dirbuild(const char *dir, const char* psec, cons "%s: Path too long\n", buf); continue; } - if (0 == stat(buf, &sb)) + if (0 == access(buf, R_OK)) continue; } } + assert('.' == dir[0]); + assert('/' == dir[1]); buf[0] = '\0'; - strlcat(buf, dir, MAXPATHLEN); + strlcat(buf, dir + 2, MAXPATHLEN); strlcat(buf, "/", MAXPATHLEN); sz = strlcat(buf, fn, MAXPATHLEN); if (sz >= MAXPATHLEN) { @@ -1628,8 +1629,6 @@ ofile_dirbuild(const char *dir, const char* psec, cons * Add the structure to the list. */ - if (verb > 2) - printf("%s: Scheduling\n", buf); if (NULL == *of) { *of = nof; (*of)->first = nof; @@ -1641,7 +1640,6 @@ ofile_dirbuild(const char *dir, const char* psec, cons } closedir(d); - return(1); } static void