-/* $OpenBSD$ */
+/* $Id: mandocdb.c,v 1.166 2014/10/12 20:32:39 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
*/
#include "config.h"
-#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/wait.h>
#include <assert.h>
const struct mdoc_node *, uint64_t);
static void render_key(struct mchars *, struct str *);
static void say(const char *, const char *, ...);
-static int set_basedir(const char *);
+static int set_basedir(const char *, int);
static int treescan(void);
static size_t utf8(unsigned int, char [7]);
{ NULL, 0 }, /* sp */
{ NULL, 0 }, /* %U */
{ NULL, 0 }, /* Ta */
+ { NULL, 0 }, /* ll */
};
* Most of these deal with a specific directory.
* Jump into that directory first.
*/
- if (OP_TEST != op && 0 == set_basedir(path_arg))
+ if (OP_TEST != op && 0 == set_basedir(path_arg, 1))
goto out;
if (dbopen(1)) {
ohash_init(&mlinks, 6, &mlinks_info);
}
- if (0 == set_basedir(dirs.paths[j]))
- goto out;
+ if (0 == set_basedir(dirs.paths[j], argc > 0))
+ continue;
if (0 == treescan())
- goto out;
+ continue;
if (0 == dbopen(0))
- goto out;
+ continue;
mpages_merge(mc, mp);
if (warnings && !nodb &&
{
char any[] = "any";
struct ohash_info str_info;
- int fd[2];
struct mpage *mpage, *mpage_dest;
struct mlink *mlink, *mlink_dest;
struct mdoc *mdoc;
char *sodest;
char *cp;
pid_t child_pid;
- int status;
+ int fd;
unsigned int pslot;
enum mandoclevel lvl;
man = NULL;
sodest = NULL;
child_pid = 0;
- fd[0] = -1;
- fd[1] = -1;
-
- if (mpage->mlinks->gzip) {
- if (-1 == pipe(fd)) {
- exitcode = (int)MANDOCLEVEL_SYSERR;
- say(mpage->mlinks->file, "&pipe gunzip");
- goto nextpage;
- }
- switch (child_pid = fork()) {
- case -1:
- exitcode = (int)MANDOCLEVEL_SYSERR;
- say(mpage->mlinks->file, "&fork gunzip");
- child_pid = 0;
- close(fd[1]);
- close(fd[0]);
- goto nextpage;
- case 0:
- close(fd[0]);
- if (-1 == dup2(fd[1], STDOUT_FILENO)) {
- say(mpage->mlinks->file,
- "&dup gunzip");
- exit(1);
- }
- execlp("gunzip", "gunzip", "-c",
- mpage->mlinks->file, NULL);
- say(mpage->mlinks->file, "&exec gunzip");
- exit(1);
- default:
- close(fd[1]);
- break;
- }
+
+ mparse_open(mp, &fd, mpage->mlinks->file, &child_pid);
+ if (fd == -1) {
+ say(mpage->mlinks->file, "&open");
+ goto nextpage;
}
/*
*/
if (FORM_CAT != mpage->mlinks->dform ||
FORM_CAT != mpage->mlinks->fform) {
- lvl = mparse_readfd(mp, fd[0], mpage->mlinks->file);
+ lvl = mparse_readfd(mp, fd, mpage->mlinks->file);
if (lvl < MANDOCLEVEL_FATAL)
mparse_result(mp, &mdoc, &man, &sodest);
}
if (mpage->mlinks->gzip)
mpage->form |= FORM_GZ;
putkey(mpage, mpage->sec, TYPE_sec);
- putkey(mpage, '\0' == *mpage->arch ?
- any : mpage->arch, TYPE_arch);
+ if (*mpage->arch != '\0')
+ putkey(mpage, mpage->arch, TYPE_arch);
for (mlink = mpage->mlinks; mlink; mlink = mlink->next) {
if ('\0' != *mlink->dsec)
} else if (NULL != man)
parse_man(mpage, man_node(man));
else
- parse_cat(mpage, fd[0]);
+ parse_cat(mpage, fd);
if (NULL == mpage->desc)
mpage->desc = mandoc_strdup(mpage->mlinks->name);
dbadd(mpage, mc);
nextpage:
- if (child_pid) {
- if (-1 == waitpid(child_pid, &status, 0)) {
- exitcode = (int)MANDOCLEVEL_SYSERR;
- say(mpage->mlinks->file, "&wait gunzip");
- } else if (WIFSIGNALED(status)) {
- exitcode = (int)MANDOCLEVEL_SYSERR;
- say(mpage->mlinks->file,
- "gunzip died from signal %d",
- WTERMSIG(status));
- } else if (WEXITSTATUS(status)) {
- exitcode = (int)MANDOCLEVEL_SYSERR;
- say(mpage->mlinks->file,
- "gunzip failed with code %d",
- WEXITSTATUS(status));
- }
+ if (child_pid &&
+ mparse_wait(mp, child_pid) != MANDOCLEVEL_OK) {
+ exitcode = (int)MANDOCLEVEL_SYSERR;
+ say(mpage->mlinks->file, "&wait gunzip");
}
ohash_delete(&strings);
ohash_delete(&names);
htab = &strings;
if (debug > 1)
for (i = 0; i < mansearch_keymax; i++)
- if (1 << i & v)
+ if ((uint64_t)1 << i & v)
say(mpage->mlinks->file,
"Adding key %s=%*s",
mansearch_keynames[i], sz, cp);
"PRAGMA synchronous = OFF", NULL, NULL, NULL)) {
exitcode = (int)MANDOCLEVEL_SYSERR;
say(MANDOC_DB, "PRAGMA synchronous: %s",
- sqlite3_errmsg(db));
+ sqlite3_errmsg(db));
sqlite3_close(db);
return(0);
}
}
static int
-set_basedir(const char *targetdir)
+set_basedir(const char *targetdir, int report_baddir)
{
static char startdir[PATH_MAX];
static int getcwd_status; /* 1 = ok, 2 = failure */
* we can reliably check whether files are inside.
*/
if (NULL == realpath(targetdir, basedir)) {
- exitcode = (int)MANDOCLEVEL_BADARG;
- say("", "&%s: realpath", targetdir);
+ if (report_baddir || errno != ENOENT) {
+ exitcode = (int)MANDOCLEVEL_BADARG;
+ say("", "&%s: realpath", targetdir);
+ }
return(0);
} else if (-1 == chdir(basedir)) {
- exitcode = (int)MANDOCLEVEL_BADARG;
- say("", "&chdir");
+ if (report_baddir || errno != ENOENT) {
+ exitcode = (int)MANDOCLEVEL_BADARG;
+ say("", "&chdir");
+ }
return(0);
}
chdir_status = 1;