version 1.150, 2014/06/19 00:45:37 |
version 1.152, 2014/06/20 02:24:40 |
Line 145 static int dbopen(int); |
|
Line 145 static int dbopen(int); |
|
static void dbprune(void); |
static void dbprune(void); |
static void filescan(const char *); |
static void filescan(const char *); |
static void *hash_alloc(size_t, void *); |
static void *hash_alloc(size_t, void *); |
static void hash_free(void *, size_t, void *); |
static void hash_free(void *, void *); |
static void *hash_halloc(size_t, void *); |
static void *hash_calloc(size_t, size_t, void *); |
static void mlink_add(struct mlink *, const struct stat *); |
static void mlink_add(struct mlink *, const struct stat *); |
static void mlink_check(struct mpage *, struct mlink *); |
static void mlink_check(struct mpage *, struct mlink *); |
static void mlink_free(struct mlink *); |
static void mlink_free(struct mlink *); |
Line 336 main(int argc, char *argv[]) |
|
Line 336 main(int argc, char *argv[]) |
|
memset(&dirs, 0, sizeof(struct manpaths)); |
memset(&dirs, 0, sizeof(struct manpaths)); |
|
|
mpages_info.alloc = mlinks_info.alloc = hash_alloc; |
mpages_info.alloc = mlinks_info.alloc = hash_alloc; |
mpages_info.halloc = mlinks_info.halloc = hash_halloc; |
mpages_info.calloc = mlinks_info.calloc = hash_calloc; |
mpages_info.hfree = mlinks_info.hfree = hash_free; |
mpages_info.free = mlinks_info.free = hash_free; |
|
|
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 506 main(int argc, char *argv[]) |
|
Line 506 main(int argc, char *argv[]) |
|
goto out; |
goto out; |
if (0 == treescan()) |
if (0 == treescan()) |
goto out; |
goto out; |
if (0 == set_basedir(dirs.paths[j])) |
|
goto out; |
|
if (0 == dbopen(0)) |
if (0 == dbopen(0)) |
goto out; |
goto out; |
|
|
Line 1090 mpages_merge(struct mchars *mc, struct mparse *mp) |
|
Line 1088 mpages_merge(struct mchars *mc, struct mparse *mp) |
|
enum mandoclevel lvl; |
enum mandoclevel lvl; |
|
|
str_info.alloc = hash_alloc; |
str_info.alloc = hash_alloc; |
str_info.halloc = hash_halloc; |
str_info.calloc = hash_calloc; |
str_info.hfree = hash_free; |
str_info.free = hash_free; |
str_info.key_offset = offsetof(struct str, key); |
str_info.key_offset = offsetof(struct str, key); |
|
|
if (0 == nodb) |
if (0 == nodb) |
Line 2350 prepare_statements: |
|
Line 2348 prepare_statements: |
|
} |
} |
|
|
static void * |
static void * |
hash_halloc(size_t sz, void *arg) |
hash_calloc(size_t n, size_t sz, void *arg) |
{ |
{ |
|
|
return(mandoc_calloc(1, sz)); |
return(mandoc_calloc(n, sz)); |
} |
} |
|
|
static void * |
static void * |
Line 2364 hash_alloc(size_t sz, void *arg) |
|
Line 2362 hash_alloc(size_t sz, void *arg) |
|
} |
} |
|
|
static void |
static void |
hash_free(void *p, size_t sz, void *arg) |
hash_free(void *p, void *arg) |
{ |
{ |
|
|
free(p); |
free(p); |
|
|
set_basedir(const char *targetdir) |
set_basedir(const char *targetdir) |
{ |
{ |
static char startdir[PATH_MAX]; |
static char startdir[PATH_MAX]; |
static int fd; |
static int getcwd_status; /* 1 = ok, 2 = failure */ |
|
static int chdir_status; /* 1 = changed directory */ |
char *cp; |
char *cp; |
|
|
/* |
/* |
* Remember where we started by keeping a fd open to the origin |
* Remember the original working directory, if possible. |
* path component: throughout this utility, we chdir() a lot to |
* This will be needed if the second or a later directory |
* handle relative paths, and by doing this, we can return to |
* on the command line is given as a relative path. |
* the starting point. |
* Do not error out if the current directory is not |
|
* searchable: Maybe it won't be needed after all. |
*/ |
*/ |
if ('\0' == *startdir) { |
if (0 == getcwd_status) { |
if (NULL == getcwd(startdir, PATH_MAX)) { |
if (NULL == getcwd(startdir, sizeof(startdir))) { |
|
getcwd_status = 2; |
|
(void)strlcpy(startdir, strerror(errno), |
|
sizeof(startdir)); |
|
} else |
|
getcwd_status = 1; |
|
} |
|
|
|
/* |
|
* We are leaving the old base directory. |
|
* Do not use it any longer, not even for messages. |
|
*/ |
|
*basedir = '\0'; |
|
|
|
/* |
|
* If and only if the directory was changed earlier and |
|
* the next directory to process is given as a relative path, |
|
* first go back, or bail out if that is impossible. |
|
*/ |
|
if (chdir_status && '/' != *targetdir) { |
|
if (2 == getcwd_status) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say("", "&getcwd"); |
say("", "getcwd: %s", startdir); |
return(0); |
return(0); |
} |
} |
if (-1 == (fd = open(startdir, O_RDONLY, 0))) { |
if (-1 == chdir(startdir)) { |
exitcode = (int)MANDOCLEVEL_SYSERR; |
exitcode = (int)MANDOCLEVEL_SYSERR; |
say("", "&open %s", startdir); |
|
return(0); |
|
} |
|
} else { |
|
if (-1 == fd) |
|
return(0); |
|
if (-1 == fchdir(fd)) { |
|
close(fd); |
|
basedir[0] = '\0'; |
|
exitcode = (int)MANDOCLEVEL_SYSERR; |
|
say("", "&chdir %s", startdir); |
say("", "&chdir %s", startdir); |
return(0); |
return(0); |
} |
} |
} |
} |
|
|
|
/* |
|
* Always resolve basedir to the canonicalized absolute |
|
* pathname and append a trailing slash, such that |
|
* we can reliably check whether files are inside. |
|
*/ |
if (NULL == realpath(targetdir, basedir)) { |
if (NULL == realpath(targetdir, basedir)) { |
basedir[0] = '\0'; |
|
exitcode = (int)MANDOCLEVEL_BADARG; |
exitcode = (int)MANDOCLEVEL_BADARG; |
say("", "&%s: realpath", targetdir); |
say("", "&%s: realpath", targetdir); |
return(0); |
return(0); |
Line 2415 set_basedir(const char *targetdir) |
|
Line 2430 set_basedir(const char *targetdir) |
|
say("", "&chdir"); |
say("", "&chdir"); |
return(0); |
return(0); |
} |
} |
|
chdir_status = 1; |
cp = strchr(basedir, '\0'); |
cp = strchr(basedir, '\0'); |
if ('/' != cp[-1]) { |
if ('/' != cp[-1]) { |
if (cp - basedir >= PATH_MAX - 1) { |
if (cp - basedir >= PATH_MAX - 1) { |
Line 2437 say(const char *file, const char *format, ...) |
|
Line 2453 say(const char *file, const char *format, ...) |
|
if ('\0' != *basedir) |
if ('\0' != *basedir) |
fprintf(stderr, "%s", basedir); |
fprintf(stderr, "%s", basedir); |
if ('\0' != *basedir && '\0' != *file) |
if ('\0' != *basedir && '\0' != *file) |
fputs("//", stderr); |
fputc('/', stderr); |
if ('\0' != *file) |
if ('\0' != *file) |
fprintf(stderr, "%s", file); |
fprintf(stderr, "%s", file); |
|
|