version 1.119, 2014/03/23 11:25:26 |
version 1.123, 2014/03/26 20:53:36 |
|
|
f = fts_open((char * const *)argv, FTS_LOGICAL, NULL); |
f = fts_open((char * const *)argv, FTS_LOGICAL, NULL); |
if (NULL == f) { |
if (NULL == f) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say("", NULL); |
say("", "&fts_open"); |
return(0); |
return(0); |
} |
} |
|
|
Line 705 filescan(const char *file) |
|
Line 705 filescan(const char *file) |
|
|
|
if (NULL == realpath(file, buf)) { |
if (NULL == realpath(file, buf)) { |
exitcode = (int)MANDOCLEVEL_BADARG; |
exitcode = (int)MANDOCLEVEL_BADARG; |
say(file, NULL); |
say(file, "&realpath"); |
return; |
return; |
} |
} |
|
|
Line 721 filescan(const char *file) |
|
Line 721 filescan(const char *file) |
|
|
|
if (-1 == stat(buf, &st)) { |
if (-1 == stat(buf, &st)) { |
exitcode = (int)MANDOCLEVEL_BADARG; |
exitcode = (int)MANDOCLEVEL_BADARG; |
say(file, NULL); |
say(file, "&stat"); |
return; |
return; |
} else if ( ! (S_IFREG & st.st_mode)) { |
} else if ( ! (S_IFREG & st.st_mode)) { |
exitcode = (int)MANDOCLEVEL_BADARG; |
exitcode = (int)MANDOCLEVEL_BADARG; |
Line 1124 parse_cat(struct mpage *mpage) |
|
Line 1124 parse_cat(struct mpage *mpage) |
|
|
|
if (NULL == (stream = fopen(mpage->mlinks->file, "r"))) { |
if (NULL == (stream = fopen(mpage->mlinks->file, "r"))) { |
if (warnings) |
if (warnings) |
say(mpage->mlinks->file, NULL); |
say(mpage->mlinks->file, "&fopen"); |
return; |
return; |
} |
} |
|
|
|
|
parse_man(struct mpage *mpage, const struct man_node *n) |
parse_man(struct mpage *mpage, const struct man_node *n) |
{ |
{ |
const struct man_node *head, *body; |
const struct man_node *head, *body; |
char *start, *sv, *title; |
char *start, *title; |
char byte; |
char byte; |
size_t sz, titlesz; |
size_t sz; |
|
|
if (NULL == n) |
if (NULL == n) |
return; |
return; |
Line 1285 parse_man(struct mpage *mpage, const struct man_node * |
|
Line 1285 parse_man(struct mpage *mpage, const struct man_node * |
|
NULL != (head = (head->child)) && |
NULL != (head = (head->child)) && |
MAN_TEXT == head->type && |
MAN_TEXT == head->type && |
0 == strcmp(head->string, "NAME") && |
0 == strcmp(head->string, "NAME") && |
NULL != (body = body->child) && |
NULL != body->child) { |
MAN_TEXT == body->type) { |
|
|
|
title = NULL; |
|
titlesz = 0; |
|
|
|
/* |
/* |
* Suck the entire NAME section into memory. |
* Suck the entire NAME section into memory. |
* Yes, we might run away. |
* Yes, we might run away. |
Line 1298 parse_man(struct mpage *mpage, const struct man_node * |
|
Line 1294 parse_man(struct mpage *mpage, const struct man_node * |
|
* NAME sections over many lines. |
* NAME sections over many lines. |
*/ |
*/ |
|
|
for ( ; NULL != body; body = body->next) { |
title = NULL; |
if (MAN_TEXT != body->type) |
man_deroff(&title, body); |
break; |
|
if (0 == (sz = strlen(body->string))) |
|
continue; |
|
title = mandoc_realloc |
|
(title, titlesz + sz + 1); |
|
memcpy(title + titlesz, body->string, sz); |
|
titlesz += sz + 1; |
|
title[titlesz - 1] = ' '; |
|
} |
|
if (NULL == title) |
if (NULL == title) |
return; |
return; |
|
|
title = mandoc_realloc(title, titlesz + 1); |
|
title[titlesz] = '\0'; |
|
|
|
/* Skip leading space. */ |
|
|
|
sv = title; |
|
while (isspace((unsigned char)*sv)) |
|
sv++; |
|
|
|
if (0 == (sz = strlen(sv))) { |
|
free(title); |
|
return; |
|
} |
|
|
|
/* Erase trailing space. */ |
|
|
|
start = &sv[sz - 1]; |
|
while (start > sv && isspace((unsigned char)*start)) |
|
*start-- = '\0'; |
|
|
|
if (start == sv) { |
|
free(title); |
|
return; |
|
} |
|
|
|
start = sv; |
|
|
|
/* |
/* |
* Go through a special heuristic dance here. |
* Go through a special heuristic dance here. |
* Conventionally, one or more manual names are |
* Conventionally, one or more manual names are |
Line 1347 parse_man(struct mpage *mpage, const struct man_node * |
|
Line 1307 parse_man(struct mpage *mpage, const struct man_node * |
|
* the name parts here. |
* the name parts here. |
*/ |
*/ |
|
|
|
start = title; |
for ( ;; ) { |
for ( ;; ) { |
sz = strcspn(start, " ,"); |
sz = strcspn(start, " ,"); |
if ('\0' == start[sz]) |
if ('\0' == start[sz]) |
Line 1377 parse_man(struct mpage *mpage, const struct man_node * |
|
Line 1338 parse_man(struct mpage *mpage, const struct man_node * |
|
start++; |
start++; |
} |
} |
|
|
if (sv == start) { |
if (start == title) { |
putkey(mpage, start, TYPE_Nm); |
putkey(mpage, start, TYPE_Nm); |
free(title); |
free(title); |
return; |
return; |
Line 1536 parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_n |
|
Line 1497 parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_n |
|
return(0); |
return(0); |
} |
} |
|
|
if (-1 == asprintf(&cp, "%s(%s)", n->string, n->next->string)) { |
mandoc_asprintf(&cp, "%s(%s)", n->string, n->next->string); |
perror(NULL); |
|
exit((int)MANDOCLEVEL_SYSERR); |
|
} |
|
putkey(mpage, cp, TYPE_Xr); |
putkey(mpage, cp, TYPE_Xr); |
free(cp); |
free(cp); |
return(0); |
return(0); |
Line 1548 parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_n |
|
Line 1506 parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_n |
|
static int |
static int |
parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_node *n) |
parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_node *n) |
{ |
{ |
size_t sz; |
|
|
|
if (MDOC_BODY != n->type) |
if (MDOC_BODY == n->type) |
return(0); |
mdoc_deroff(&mpage->desc, n); |
|
return(0); |
/* |
|
* Special-case the `Nd' because we need to put the description |
|
* into the document table. |
|
*/ |
|
|
|
for (n = n->child; NULL != n; n = n->next) { |
|
if (MDOC_TEXT == n->type) { |
|
if (NULL != mpage->desc) { |
|
sz = strlen(mpage->desc) + |
|
strlen(n->string) + 2; |
|
mpage->desc = mandoc_realloc( |
|
mpage->desc, sz); |
|
strlcat(mpage->desc, " ", sz); |
|
strlcat(mpage->desc, n->string, sz); |
|
} else |
|
mpage->desc = mandoc_strdup(n->string); |
|
} |
|
if (NULL != n->child) |
|
parse_mdoc_Nd(mpage, n); |
|
} |
|
return(1); |
|
} |
} |
|
|
static int |
static int |
Line 1945 dbclose(int real) |
|
Line 1881 dbclose(int real) |
|
if ('\0' == *tempfilename) { |
if ('\0' == *tempfilename) { |
if (-1 == rename(MANDOC_DB "~", MANDOC_DB)) { |
if (-1 == rename(MANDOC_DB "~", MANDOC_DB)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say(MANDOC_DB, "%s", strerror(errno)); |
say(MANDOC_DB, "&rename"); |
} |
} |
return; |
return; |
} |
} |
Line 1953 dbclose(int real) |
|
Line 1889 dbclose(int real) |
|
switch (child = fork()) { |
switch (child = fork()) { |
case (-1): |
case (-1): |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say("fork cmp", "%s", strerror(errno)); |
say("", "&fork cmp"); |
return; |
return; |
case (0): |
case (0): |
execlp("cmp", "cmp", "-s", |
execlp("cmp", "cmp", "-s", |
tempfilename, MANDOC_DB, NULL); |
tempfilename, MANDOC_DB, NULL); |
say("exec cmp", "%s", strerror(errno)); |
say("", "&exec cmp"); |
exit(0); |
exit(0); |
default: |
default: |
break; |
break; |
} |
} |
if (-1 == waitpid(child, &status, 0)) { |
if (-1 == waitpid(child, &status, 0)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say("wait cmp", "%s", strerror(errno)); |
say("", "&wait cmp"); |
} else if (WIFSIGNALED(status)) { |
} else if (WIFSIGNALED(status)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say("cmp", "Died from a signal"); |
say("", "cmp died from signal %d", WTERMSIG(status)); |
} else if (WEXITSTATUS(status)) { |
} else if (WEXITSTATUS(status)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say(MANDOC_DB, |
say(MANDOC_DB, |
Line 1979 dbclose(int real) |
|
Line 1915 dbclose(int real) |
|
switch (child = fork()) { |
switch (child = fork()) { |
case (-1): |
case (-1): |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say("fork rm", "%s", strerror(errno)); |
say("", "&fork rm"); |
return; |
return; |
case (0): |
case (0): |
execlp("rm", "rm", "-rf", tempfilename, NULL); |
execlp("rm", "rm", "-rf", tempfilename, NULL); |
say("exec rm", "%s", strerror(errno)); |
say("", "&exec rm"); |
exit((int)MANDOCLEVEL_SYSERR); |
exit((int)MANDOCLEVEL_SYSERR); |
default: |
default: |
break; |
break; |
} |
} |
if (-1 == waitpid(child, &status, 0)) { |
if (-1 == waitpid(child, &status, 0)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say("wait rm", "%s", strerror(errno)); |
say("", "&wait rm"); |
} else if (WIFSIGNALED(status) || WEXITSTATUS(status)) { |
} else if (WIFSIGNALED(status) || WEXITSTATUS(status)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say(tempfilename, |
say("", "%s: Cannot remove temporary directory", |
"Cannot remove temporary directory"); |
tempfilename); |
} |
} |
} |
} |
|
|
Line 2043 dbopen(int real) |
|
Line 1979 dbopen(int real) |
|
if (strlcpy(tempfilename, "/tmp/mandocdb.XXXXXX", |
if (strlcpy(tempfilename, "/tmp/mandocdb.XXXXXX", |
sizeof(tempfilename)) >= sizeof(tempfilename)) { |
sizeof(tempfilename)) >= sizeof(tempfilename)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say("/tmp/mandocdb.XXXXXX", "Filename too long"); |
say("", "/tmp/mandocdb.XXXXXX: Filename too long"); |
return(0); |
return(0); |
} |
} |
if (NULL == mkdtemp(tempfilename)) { |
if (NULL == mkdtemp(tempfilename)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say(tempfilename, "%s", strerror(errno)); |
say("", "&%s", tempfilename); |
return(0); |
return(0); |
} |
} |
if (strlcat(tempfilename, "/" MANDOC_DB, |
if (strlcat(tempfilename, "/" MANDOC_DB, |
sizeof(tempfilename)) >= sizeof(tempfilename)) { |
sizeof(tempfilename)) >= sizeof(tempfilename)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say(tempfilename, "Filename too long"); |
say("", "%s/" MANDOC_DB ": Filename too long", |
|
tempfilename); |
return(0); |
return(0); |
} |
} |
rc = sqlite3_open_v2(tempfilename, &db, ofl, NULL); |
rc = sqlite3_open_v2(tempfilename, &db, ofl, NULL); |
if (SQLITE_OK != rc) { |
if (SQLITE_OK != rc) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say(tempfilename, "%s", sqlite3_errmsg(db)); |
say("", "%s: %s", tempfilename, sqlite3_errmsg(db)); |
return(0); |
return(0); |
} |
} |
|
|
Line 2157 set_basedir(const char *targetdir) |
|
Line 2094 set_basedir(const char *targetdir) |
|
if (NULL == getcwd(startdir, PATH_MAX)) { |
if (NULL == getcwd(startdir, PATH_MAX)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
if (NULL != targetdir) |
if (NULL != targetdir) |
say(".", NULL); |
say("", "&getcwd"); |
return(0); |
return(0); |
} |
} |
if (-1 == (fd = open(startdir, O_RDONLY, 0))) { |
if (-1 == (fd = open(startdir, O_RDONLY, 0))) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say(startdir, NULL); |
say("", "&open %s", startdir); |
return(0); |
return(0); |
} |
} |
if (NULL == targetdir) |
if (NULL == targetdir) |
Line 2174 set_basedir(const char *targetdir) |
|
Line 2111 set_basedir(const char *targetdir) |
|
close(fd); |
close(fd); |
basedir[0] = '\0'; |
basedir[0] = '\0'; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say(startdir, NULL); |
say("", "&chdir %s", startdir); |
return(0); |
return(0); |
} |
} |
if (NULL == targetdir) { |
if (NULL == targetdir) { |
Line 2185 set_basedir(const char *targetdir) |
|
Line 2122 set_basedir(const char *targetdir) |
|
if (NULL == realpath(targetdir, basedir)) { |
if (NULL == realpath(targetdir, basedir)) { |
basedir[0] = '\0'; |
basedir[0] = '\0'; |
exitcode = (int)MANDOCLEVEL_BADARG; |
exitcode = (int)MANDOCLEVEL_BADARG; |
say(targetdir, NULL); |
say("", "&%s: realpath", targetdir); |
return(0); |
return(0); |
} else if (-1 == chdir(basedir)) { |
} else if (-1 == chdir(basedir)) { |
exitcode = (int)MANDOCLEVEL_BADARG; |
exitcode = (int)MANDOCLEVEL_BADARG; |
say("", NULL); |
say("", "&chdir"); |
return(0); |
return(0); |
} |
} |
return(1); |
return(1); |
|
|
say(const char *file, const char *format, ...) |
say(const char *file, const char *format, ...) |
{ |
{ |
va_list ap; |
va_list ap; |
|
int use_errno; |
|
|
if ('\0' != *basedir) |
if ('\0' != *basedir) |
fprintf(stderr, "%s", basedir); |
fprintf(stderr, "%s", basedir); |
Line 2206 say(const char *file, const char *format, ...) |
|
Line 2144 say(const char *file, const char *format, ...) |
|
fputs("//", stderr); |
fputs("//", stderr); |
if ('\0' != *file) |
if ('\0' != *file) |
fprintf(stderr, "%s", file); |
fprintf(stderr, "%s", file); |
fputs(": ", stderr); |
|
|
|
if (NULL == format) { |
use_errno = 1; |
perror(NULL); |
if (NULL != format) { |
return; |
switch (*format) { |
|
case ('&'): |
|
format++; |
|
break; |
|
case ('\0'): |
|
format = NULL; |
|
break; |
|
default: |
|
use_errno = 0; |
|
break; |
|
} |
} |
} |
|
if (NULL != format) { |
va_start(ap, format); |
if ('\0' != *basedir || '\0' != *file) |
vfprintf(stderr, format, ap); |
fputs(": ", stderr); |
va_end(ap); |
va_start(ap, format); |
|
vfprintf(stderr, format, ap); |
fputc('\n', stderr); |
va_end(ap); |
|
} |
|
if (use_errno) { |
|
if ('\0' != *basedir || '\0' != *file || NULL != format) |
|
fputs(": ", stderr); |
|
perror(NULL); |
|
} else |
|
fputc('\n', stderr); |
} |
} |