version 1.180, 2014/12/30 20:41:00 |
version 1.187, 2015/03/27 17:37:25 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
* copyright notice and this permission notice appear in all copies. |
* copyright notice and this permission notice appear in all copies. |
* |
* |
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES |
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR |
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
|
|
#include "man.h" |
#include "man.h" |
#include "mandoc.h" |
#include "mandoc.h" |
#include "mandoc_aux.h" |
#include "mandoc_aux.h" |
#include "manpath.h" |
#include "manconf.h" |
#include "mansearch.h" |
#include "mansearch.h" |
|
|
extern int mansearch_keymax; |
extern int mansearch_keymax; |
Line 338 static const struct mdoc_handler mdocs[MDOC_MAX] = { |
|
Line 338 static const struct mdoc_handler mdocs[MDOC_MAX] = { |
|
int |
int |
mandocdb(int argc, char *argv[]) |
mandocdb(int argc, char *argv[]) |
{ |
{ |
int ch, i; |
struct manconf conf; |
size_t j, sz; |
|
const char *path_arg; |
|
struct manpaths dirs; |
|
struct mparse *mp; |
|
struct ohash_info mpages_info, mlinks_info; |
struct ohash_info mpages_info, mlinks_info; |
|
struct mparse *mp; |
|
const char *path_arg; |
|
size_t j, sz; |
|
int ch, i; |
|
|
|
memset(&conf, 0, sizeof(conf)); |
memset(stmts, 0, STMT__MAX * sizeof(sqlite3_stmt *)); |
memset(stmts, 0, STMT__MAX * sizeof(sqlite3_stmt *)); |
memset(&dirs, 0, sizeof(struct manpaths)); |
|
|
|
mpages_info.alloc = mlinks_info.alloc = hash_alloc; |
mpages_info.alloc = mlinks_info.alloc = hash_alloc; |
mpages_info.calloc = mlinks_info.calloc = hash_calloc; |
mpages_info.calloc = mlinks_info.calloc = hash_calloc; |
mpages_info.free = mlinks_info.free = hash_free; |
mpages_info.free = mlinks_info.free = hash_free; |
|
mpages_info.data = mlinks_info.data = NULL; |
|
|
mpages_info.key_offset = offsetof(struct mpage, inodev); |
mpages_info.key_offset = offsetof(struct mpage, inodev); |
mlinks_info.key_offset = offsetof(struct mlink, file); |
mlinks_info.key_offset = offsetof(struct mlink, file); |
Line 441 mandocdb(int argc, char *argv[]) |
|
Line 442 mandocdb(int argc, char *argv[]) |
|
|
|
exitcode = (int)MANDOCLEVEL_OK; |
exitcode = (int)MANDOCLEVEL_OK; |
mchars = mchars_alloc(); |
mchars = mchars_alloc(); |
mp = mparse_alloc(mparse_options, MANDOCLEVEL_FATAL, NULL, |
mp = mparse_alloc(mparse_options, MANDOCLEVEL_BADARG, NULL, |
mchars, NULL); |
mchars, NULL); |
ohash_init(&mpages, 6, &mpages_info); |
ohash_init(&mpages, 6, &mpages_info); |
ohash_init(&mlinks, 6, &mlinks_info); |
ohash_init(&mlinks, 6, &mlinks_info); |
Line 484 mandocdb(int argc, char *argv[]) |
|
Line 485 mandocdb(int argc, char *argv[]) |
|
/* |
/* |
* If we have arguments, use them as our manpaths. |
* If we have arguments, use them as our manpaths. |
* If we don't, grok from manpath(1) or however else |
* If we don't, grok from manpath(1) or however else |
* manpath_parse() wants to do it. |
* manconf_parse() wants to do it. |
*/ |
*/ |
if (argc > 0) { |
if (argc > 0) { |
dirs.paths = mandoc_reallocarray(NULL, |
conf.manpath.paths = mandoc_reallocarray(NULL, |
argc, sizeof(char *)); |
argc, sizeof(char *)); |
dirs.sz = (size_t)argc; |
conf.manpath.sz = (size_t)argc; |
for (i = 0; i < argc; i++) |
for (i = 0; i < argc; i++) |
dirs.paths[i] = mandoc_strdup(argv[i]); |
conf.manpath.paths[i] = mandoc_strdup(argv[i]); |
} else |
} else |
manpath_parse(&dirs, path_arg, NULL, NULL); |
manconf_parse(&conf, path_arg, NULL, NULL); |
|
|
if (0 == dirs.sz) { |
if (conf.manpath.sz == 0) { |
exitcode = (int)MANDOCLEVEL_BADARG; |
exitcode = (int)MANDOCLEVEL_BADARG; |
say("", "Empty manpath"); |
say("", "Empty manpath"); |
} |
} |
Line 506 mandocdb(int argc, char *argv[]) |
|
Line 507 mandocdb(int argc, char *argv[]) |
|
* Ignore zero-length directories and strip trailing |
* Ignore zero-length directories and strip trailing |
* slashes. |
* slashes. |
*/ |
*/ |
for (j = 0; j < dirs.sz; j++) { |
for (j = 0; j < conf.manpath.sz; j++) { |
sz = strlen(dirs.paths[j]); |
sz = strlen(conf.manpath.paths[j]); |
if (sz && '/' == dirs.paths[j][sz - 1]) |
if (sz && conf.manpath.paths[j][sz - 1] == '/') |
dirs.paths[j][--sz] = '\0'; |
conf.manpath.paths[j][--sz] = '\0'; |
if (0 == sz) |
if (0 == sz) |
continue; |
continue; |
|
|
Line 518 mandocdb(int argc, char *argv[]) |
|
Line 519 mandocdb(int argc, char *argv[]) |
|
ohash_init(&mlinks, 6, &mlinks_info); |
ohash_init(&mlinks, 6, &mlinks_info); |
} |
} |
|
|
if (0 == set_basedir(dirs.paths[j], argc > 0)) |
if ( ! set_basedir(conf.manpath.paths[j], argc > 0)) |
continue; |
continue; |
if (0 == treescan()) |
if (0 == treescan()) |
continue; |
continue; |
Line 531 mandocdb(int argc, char *argv[]) |
|
Line 532 mandocdb(int argc, char *argv[]) |
|
names_check(); |
names_check(); |
dbclose(0); |
dbclose(0); |
|
|
if (j + 1 < dirs.sz) { |
if (j + 1 < conf.manpath.sz) { |
mpages_free(); |
mpages_free(); |
ohash_delete(&mpages); |
ohash_delete(&mpages); |
ohash_delete(&mlinks); |
ohash_delete(&mlinks); |
Line 539 mandocdb(int argc, char *argv[]) |
|
Line 540 mandocdb(int argc, char *argv[]) |
|
} |
} |
} |
} |
out: |
out: |
manpath_free(&dirs); |
manconf_free(&conf); |
mparse_free(mp); |
mparse_free(mp); |
mchars_free(mchars); |
mchars_free(mchars); |
mpages_free(); |
mpages_free(); |
|
|
say(path, "&realpath"); |
say(path, "&realpath"); |
continue; |
continue; |
} |
} |
if (strstr(buf, basedir) != buf) { |
if (strstr(buf, basedir) != buf |
|
#ifdef HOMEBREWDIR |
|
&& strstr(buf, HOMEBREWDIR) != buf |
|
#endif |
|
) { |
if (warnings) say("", |
if (warnings) say("", |
"%s: outside base directory", buf); |
"%s: outside base directory", buf); |
continue; |
continue; |
|
|
say(path, "Skip pdf"); |
say(path, "Skip pdf"); |
continue; |
continue; |
} else if ( ! use_all && |
} else if ( ! use_all && |
((FORM_SRC == dform && strcmp(fsec, dsec)) || |
((FORM_SRC == dform && |
|
strncmp(fsec, dsec, strlen(dsec))) || |
(FORM_CAT == dform && strcmp(fsec, "0")))) { |
(FORM_CAT == dform && strcmp(fsec, "0")))) { |
if (warnings) |
if (warnings) |
say(path, "Wrong filename suffix"); |
say(path, "Wrong filename suffix"); |
Line 817 filescan(const char *file) |
|
Line 823 filescan(const char *file) |
|
start = buf; |
start = buf; |
else if (strstr(buf, basedir) == buf) |
else if (strstr(buf, basedir) == buf) |
start = buf + strlen(basedir); |
start = buf + strlen(basedir); |
|
#ifdef HOMEBREWDIR |
|
else if (strstr(buf, HOMEBREWDIR) == buf) |
|
start = buf; |
|
#endif |
else { |
else { |
exitcode = (int)MANDOCLEVEL_BADARG; |
exitcode = (int)MANDOCLEVEL_BADARG; |
say("", "%s: outside base directory", buf); |
say("", "%s: outside base directory", buf); |
Line 932 mlink_add(struct mlink *mlink, const struct stat *st) |
|
Line 942 mlink_add(struct mlink *mlink, const struct stat *st) |
|
assert(NULL == ohash_find(&mlinks, slot)); |
assert(NULL == ohash_find(&mlinks, slot)); |
ohash_insert(&mlinks, slot, mlink); |
ohash_insert(&mlinks, slot, mlink); |
|
|
|
memset(&inodev, 0, sizeof(inodev)); /* Clear padding. */ |
inodev.st_ino = st->st_ino; |
inodev.st_ino = st->st_ino; |
inodev.st_dev = st->st_dev; |
inodev.st_dev = st->st_dev; |
slot = ohash_lookup_memory(&mpages, (char *)&inodev, |
slot = ohash_lookup_memory(&mpages, (char *)&inodev, |
Line 1101 mpages_merge(struct mparse *mp) |
|
Line 1112 mpages_merge(struct mparse *mp) |
|
char *cp; |
char *cp; |
int fd; |
int fd; |
unsigned int pslot; |
unsigned int pslot; |
enum mandoclevel lvl; |
|
|
|
str_info.alloc = hash_alloc; |
str_info.alloc = hash_alloc; |
str_info.calloc = hash_calloc; |
str_info.calloc = hash_calloc; |
str_info.free = hash_free; |
str_info.free = hash_free; |
|
str_info.data = NULL; |
str_info.key_offset = offsetof(struct str, key); |
str_info.key_offset = offsetof(struct str, key); |
|
|
if ( ! nodb) |
if ( ! nodb) |
Line 1114 mpages_merge(struct mparse *mp) |
|
Line 1125 mpages_merge(struct mparse *mp) |
|
mpage = ohash_first(&mpages, &pslot); |
mpage = ohash_first(&mpages, &pslot); |
while (mpage != NULL) { |
while (mpage != NULL) { |
mlinks_undupe(mpage); |
mlinks_undupe(mpage); |
if (mpage->mlinks == NULL) { |
if ((mlink = mpage->mlinks) == NULL) { |
mpage = ohash_next(&mpages, &pslot); |
mpage = ohash_next(&mpages, &pslot); |
continue; |
continue; |
} |
} |
Line 1127 mpages_merge(struct mparse *mp) |
|
Line 1138 mpages_merge(struct mparse *mp) |
|
man = NULL; |
man = NULL; |
sodest = NULL; |
sodest = NULL; |
|
|
mparse_open(mp, &fd, mpage->mlinks->file); |
mparse_open(mp, &fd, mlink->file); |
if (fd == -1) { |
if (fd == -1) { |
say(mpage->mlinks->file, "&open"); |
say(mlink->file, "&open"); |
goto nextpage; |
goto nextpage; |
} |
} |
|
|
/* |
/* |
* Try interpreting the file as mdoc(7) or man(7) |
* Interpret the file as mdoc(7) or man(7) source |
* source code, unless it is already known to be |
* code, unless it is known to be formatted. |
* formatted. Fall back to formatted mode. |
|
*/ |
*/ |
if (mpage->mlinks->dform != FORM_CAT || |
if (mlink->dform != FORM_CAT || mlink->fform != FORM_CAT) { |
mpage->mlinks->fform != FORM_CAT) { |
mparse_readfd(mp, fd, mlink->file); |
lvl = mparse_readfd(mp, fd, mpage->mlinks->file); |
mparse_result(mp, &mdoc, &man, &sodest); |
if (lvl < MANDOCLEVEL_FATAL) |
|
mparse_result(mp, &mdoc, &man, &sodest); |
|
} |
} |
|
|
if (sodest != NULL) { |
if (sodest != NULL) { |
Line 1159 mpages_merge(struct mparse *mp) |
|
Line 1167 mpages_merge(struct mparse *mp) |
|
/* The .so target exists. */ |
/* The .so target exists. */ |
|
|
mpage_dest = mlink_dest->mpage; |
mpage_dest = mlink_dest->mpage; |
mlink = mpage->mlinks; |
|
while (1) { |
while (1) { |
mlink->mpage = mpage_dest; |
mlink->mpage = mpage_dest; |
|
|
Line 1199 mpages_merge(struct mparse *mp) |
|
Line 1206 mpages_merge(struct mparse *mp) |
|
mandoc_strdup(mdoc_meta(mdoc)->title); |
mandoc_strdup(mdoc_meta(mdoc)->title); |
} else if (man != NULL) { |
} else if (man != NULL) { |
mpage->form = FORM_SRC; |
mpage->form = FORM_SRC; |
mpage->sec = |
mpage->sec = mandoc_strdup(man_meta(man)->msec); |
mandoc_strdup(man_meta(man)->msec); |
mpage->arch = mandoc_strdup(mlink->arch); |
mpage->arch = |
mpage->title = mandoc_strdup(man_meta(man)->title); |
mandoc_strdup(mpage->mlinks->arch); |
|
mpage->title = |
|
mandoc_strdup(man_meta(man)->title); |
|
} else { |
} else { |
mpage->form = FORM_CAT; |
mpage->form = FORM_CAT; |
mpage->sec = |
mpage->sec = mandoc_strdup(mlink->dsec); |
mandoc_strdup(mpage->mlinks->dsec); |
mpage->arch = mandoc_strdup(mlink->arch); |
mpage->arch = |
mpage->title = mandoc_strdup(mlink->name); |
mandoc_strdup(mpage->mlinks->arch); |
|
mpage->title = |
|
mandoc_strdup(mpage->mlinks->name); |
|
} |
} |
putkey(mpage, mpage->sec, TYPE_sec); |
putkey(mpage, mpage->sec, TYPE_sec); |
if (*mpage->arch != '\0') |
if (*mpage->arch != '\0') |
putkey(mpage, mpage->arch, TYPE_arch); |
putkey(mpage, mpage->arch, TYPE_arch); |
|
|
for (mlink = mpage->mlinks; mlink; mlink = mlink->next) { |
for ( ; mlink != NULL; mlink = mlink->next) { |
if ('\0' != *mlink->dsec) |
if ('\0' != *mlink->dsec) |
putkey(mpage, mlink->dsec, TYPE_sec); |
putkey(mpage, mlink->dsec, TYPE_sec); |
if ('\0' != *mlink->fsec) |
if ('\0' != *mlink->fsec) |
Line 1244 mpages_merge(struct mparse *mp) |
|
Line 1245 mpages_merge(struct mparse *mp) |
|
mlink_check(mpage, mlink); |
mlink_check(mpage, mlink); |
|
|
dbadd(mpage); |
dbadd(mpage); |
|
mlink = mpage->mlinks; |
|
|
nextpage: |
nextpage: |
if (mparse_wait(mp) != MANDOCLEVEL_OK) { |
if (mparse_wait(mp) != MANDOCLEVEL_OK) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say(mpage->mlinks->file, "&wait gunzip"); |
say(mlink->file, "&wait gunzip"); |
} |
} |
ohash_delete(&strings); |
ohash_delete(&strings); |
ohash_delete(&names); |
ohash_delete(&names); |