=================================================================== RCS file: /cvs/mandoc/mandocdb.c,v retrieving revision 1.216 retrieving revision 1.220.2.3 diff -u -p -r1.216 -r1.220.2.3 --- mandoc/mandocdb.c 2016/03/17 21:26:26 1.216 +++ mandoc/mandocdb.c 2016/10/20 18:52:27 1.220.2.3 @@ -1,7 +1,8 @@ -/* $Id: mandocdb.c,v 1.216 2016/03/17 21:26:26 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.220.2.3 2016/10/20 18:52:27 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011-2016 Ingo Schwarze + * Copyright (c) 2016 Ed Maste * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -33,8 +34,10 @@ #else #include "compat_fts.h" #endif -#include #include +#if HAVE_SANDBOX_INIT +#include +#endif #include #include #include @@ -101,6 +104,7 @@ struct mpage { char *arch; /* architecture from file content */ char *title; /* title from file content */ char *desc; /* description from file content */ + struct mpage *next; /* singly linked list */ struct mlink *mlinks; /* singly linked list */ int form; /* format from file content */ int name_head_done; @@ -137,6 +141,9 @@ struct mdoc_handler { uint64_t mask; /* set unless handler returns 0 */ }; + +int mandocdb(int, char *[]); + static void dbclose(int); static void dbadd(struct mpage *); static void dbadd_mlink(const struct mlink *mlink); @@ -144,6 +151,11 @@ static void dbadd_mlink_name(const struct mlink *mlin static int dbopen(int); static void dbprune(void); static void filescan(const char *); +#if HAVE_FTS_COMPARE_CONST +static int fts_compare(const FTSENT *const *, const FTSENT *const *); +#else +static int fts_compare(const FTSENT **, const FTSENT **); +#endif static void mlink_add(struct mlink *, const struct stat *); static void mlink_check(struct mpage *, struct mlink *); static void mlink_free(struct mlink *); @@ -180,7 +192,8 @@ static void putkeys(const struct mpage *, char *, siz static void putmdockey(const struct mpage *, const struct roff_node *, uint64_t); static int render_string(char **, size_t *); -static void say(const char *, const char *, ...); +static void say(const char *, const char *, ...) + __attribute__((__format__ (printf, 2, 3))); static int set_basedir(const char *, int); static int treescan(void); static size_t utf8(unsigned int, char [7]); @@ -195,6 +208,7 @@ static int write_utf8; /* write UTF-8 output; else A static int exitcode; /* to be returned by main */ static enum op op; /* operational mode */ static char basedir[PATH_MAX]; /* current base directory */ +static struct mpage *mpage_head; /* list of distinct manual pages */ static struct ohash mpages; /* table of distinct manual pages */ static struct ohash mlinks; /* table of directory entries */ static struct ohash names; /* table of all names */ @@ -346,6 +360,13 @@ mandocdb(int argc, char *argv[]) } #endif +#if HAVE_SANDBOX_INIT + if (sandbox_init(kSBXProfileNoInternet, SANDBOX_NAMED, NULL) == -1) { + warnx("sandbox_init"); + return (int)MANDOCLEVEL_SYSERR; + } +#endif + memset(&conf, 0, sizeof(conf)); memset(stmts, 0, STMT__MAX * sizeof(sqlite3_stmt *)); @@ -563,6 +584,20 @@ usage: } /* + * To get a singly linked list in alpha order while inserting entries + * at the beginning, process directory entries in reverse alpha order. + */ +static int +#if HAVE_FTS_COMPARE_CONST +fts_compare(const FTSENT *const *a, const FTSENT *const *b) +#else +fts_compare(const FTSENT **a, const FTSENT **b) +#endif +{ + return -strcmp((*a)->fts_name, (*b)->fts_name); +} + +/* * Scan a directory tree rooted at "basedir" for manpages. * We use fts(), scanning directory parts along the way for clues to our * section and architecture. @@ -591,8 +626,8 @@ treescan(void) argv[0] = "."; argv[1] = (char *)NULL; - f = fts_open((char * const *)argv, - FTS_PHYSICAL | FTS_NOCHDIR, NULL); + f = fts_open((char * const *)argv, FTS_PHYSICAL | FTS_NOCHDIR, + fts_compare); if (f == NULL) { exitcode = (int)MANDOCLEVEL_SYSERR; say("", "&fts_open"); @@ -957,6 +992,8 @@ mlink_add(struct mlink *mlink, const struct stat *st) mpage = mandoc_calloc(1, sizeof(struct mpage)); mpage->inodev.st_ino = inodev.st_ino; mpage->inodev.st_dev = inodev.st_dev; + mpage->next = mpage_head; + mpage_head = mpage; ohash_insert(&mpages, slot, mpage); } else mlink->next = mpage->mlinks; @@ -980,20 +1017,18 @@ mpages_free(void) { struct mpage *mpage; struct mlink *mlink; - unsigned int slot; - mpage = ohash_first(&mpages, &slot); - while (NULL != mpage) { - while (NULL != (mlink = mpage->mlinks)) { + while ((mpage = mpage_head) != NULL) { + while ((mlink = mpage->mlinks) != NULL) { mpage->mlinks = mlink->next; mlink_free(mlink); } + mpage_head = mpage->next; free(mpage->sec); free(mpage->arch); free(mpage->title); free(mpage->desc); free(mpage); - mpage = ohash_next(&mpages, &slot); } } @@ -1114,18 +1149,14 @@ mpages_merge(struct mparse *mp) char *sodest; char *cp; int fd; - unsigned int pslot; if ( ! nodb) SQL_EXEC("BEGIN TRANSACTION"); - mpage = ohash_first(&mpages, &pslot); - while (mpage != NULL) { + for (mpage = mpage_head; mpage != NULL; mpage = mpage->next) { mlinks_undupe(mpage); - if ((mlink = mpage->mlinks) == NULL) { - mpage = ohash_next(&mpages, &pslot); + if ((mlink = mpage->mlinks) == NULL) continue; - } name_mask = NAME_MASK; mandoc_ohash_init(&names, 4, offsetof(struct str, key)); @@ -1247,7 +1278,6 @@ mpages_merge(struct mparse *mp) nextpage: ohash_delete(&strings); ohash_delete(&names); - mpage = ohash_next(&mpages, &pslot); } if (0 == nodb) @@ -1758,7 +1788,7 @@ parse_mdoc_Nm(struct mpage *mpage, const struct roff_m if ( ! (mpage->name_head_done || n->child == NULL || n->child->string == NULL || strcasecmp(n->child->string, meta->title))) { - putkey(mpage, n->child->string, ROFFT_HEAD); + putkey(mpage, n->child->string, NAME_HEAD); mpage->name_head_done = 1; } return 0; @@ -1806,7 +1836,7 @@ putkeys(const struct mpage *mpage, char *cp, size_t sz name_mask &= ~NAME_FIRST; if (debug > 1) say(mpage->mlinks->file, - "Adding name %*s, bits=%d", sz, cp, v); + "Adding name %*s, bits=0x%llx", (int)sz, cp, v); } else { htab = &strings; if (debug > 1) @@ -1814,7 +1844,7 @@ putkeys(const struct mpage *mpage, char *cp, size_t sz if ((uint64_t)1 << i & v) say(mpage->mlinks->file, "Adding key %s=%*s", - mansearch_keynames[i], sz, cp); + mansearch_keynames[i], (int)sz, cp); } end = cp + sz;