version 1.42, 2011/07/05 05:47:20 |
version 1.43, 2011/07/07 04:24:35 |
|
|
static void how(char *); |
static void how(char *); |
static void jump(char **, char *, char *); |
static void jump(char **, char *, char *); |
static int manual(char *, TAG *, glob_t *); |
static int manual(char *, TAG *, glob_t *); |
static void check_companion(char **); |
static void check_companion(char **, TAG *); |
static void onsig(int); |
static void onsig(int); |
static void usage(void); |
static void usage(void); |
|
|
|
|
jump(argv, "-k", "apropos"); |
jump(argv, "-k", "apropos"); |
/* NOTREACHED */ |
/* NOTREACHED */ |
case 'w': |
case 'w': |
f_all = f_where = 1; |
f_where = 1; |
break; |
break; |
case '?': |
case '?': |
default: |
default: |
|
|
{ |
{ |
ENTRY *ep, *e_sufp, *e_tag; |
ENTRY *ep, *e_sufp, *e_tag; |
TAG *missp, *sufp; |
TAG *missp, *sufp; |
int anyfound, cnt, found; |
int anyfound, cnt, found, globres; |
char *p, buf[MAXPATHLEN]; |
char *p, buf[MAXPATHLEN]; |
|
|
anyfound = 0; |
anyfound = 0; |
buf[0] = '*'; |
buf[0] = '*'; |
|
|
|
/* Expand the search path. */ |
|
if (f_all != f_where) { |
|
e_tag = tag == NULL ? NULL : TAILQ_FIRST(&tag->list); |
|
for (; e_tag != NULL; e_tag = TAILQ_NEXT(e_tag, q)) { |
|
if (glob(e_tag->s, GLOB_BRACE | GLOB_NOSORT, |
|
NULL, pg)) { |
|
/* No GLOB_NOMATCH here due to {arch,}. */ |
|
warn("globbing directories"); |
|
(void)cleanup(0); |
|
exit(1); |
|
} |
|
ep = e_tag; |
|
for (cnt = 0; cnt < pg->gl_pathc; cnt++) { |
|
if ((e_tag = malloc(sizeof(ENTRY))) == NULL || |
|
(e_tag->s = strdup(pg->gl_pathv[cnt])) == |
|
NULL) { |
|
warn(NULL); |
|
(void)cleanup(0); |
|
exit(1); |
|
} |
|
TAILQ_INSERT_BEFORE(ep, e_tag, q); |
|
} |
|
free(ep->s); |
|
TAILQ_REMOVE(&tag->list, ep, q); |
|
free(ep); |
|
globfree(pg); |
|
pg->gl_pathc = 0; |
|
} |
|
} |
|
|
/* For each element in the list... */ |
/* For each element in the list... */ |
e_tag = tag == NULL ? NULL : TAILQ_FIRST(&tag->list); |
e_tag = tag == NULL ? NULL : TAILQ_FIRST(&tag->list); |
for (; e_tag != NULL; e_tag = TAILQ_NEXT(e_tag, q)) { |
for (; e_tag != NULL; e_tag = TAILQ_NEXT(e_tag, q)) { |
(void)snprintf(buf, sizeof(buf), "%s/%s.*", e_tag->s, page); |
(void)snprintf(buf, sizeof(buf), "%s/%s.*", e_tag->s, page); |
if (glob(buf, |
switch (glob(buf, GLOB_APPEND | GLOB_BRACE | GLOB_NOSORT, |
GLOB_APPEND | GLOB_BRACE | GLOB_NOSORT | GLOB_QUOTE, |
|
NULL, pg)) { |
NULL, pg)) { |
warn("globbing"); |
case (0): |
|
break; |
|
case (GLOB_NOMATCH): |
|
continue; |
|
default: |
|
warn("globbing files"); |
(void)cleanup(0); |
(void)cleanup(0); |
exit(1); |
exit(1); |
} |
} |
|
|
for (cnt = pg->gl_pathc - pg->gl_matchc; |
for (cnt = pg->gl_pathc - pg->gl_matchc; |
cnt < pg->gl_pathc; ++cnt) { |
cnt < pg->gl_pathc; ++cnt) { |
|
|
if (!f_all) |
if (!f_all || !f_where) { |
check_companion(pg->gl_pathv + cnt); |
check_companion(pg->gl_pathv + cnt, tag); |
|
if (*pg->gl_pathv[cnt] == '\0') |
|
continue; |
|
} |
|
|
/* |
/* |
* Try the _suffix key words first. |
* Try the _suffix key words first. |
|
|
} |
} |
if (found) { |
if (found) { |
next: anyfound = 1; |
next: anyfound = 1; |
if (!f_all) { |
if (!f_all && !f_where) { |
/* Delete any other matches. */ |
/* Delete any other matches. */ |
while (++cnt< pg->gl_pathc) |
while (++cnt< pg->gl_pathc) |
pg->gl_pathv[cnt] = ""; |
pg->gl_pathv[cnt] = ""; |
|
|
pg->gl_pathv[cnt] = ""; |
pg->gl_pathv[cnt] = ""; |
} |
} |
|
|
if (anyfound && !f_all) |
if (anyfound && !f_all && !f_where) |
break; |
break; |
} |
} |
|
|
|
|
|
|
/* |
/* |
* check_companion -- |
* check_companion -- |
* Check for a companion [un]formatted page |
* Check for a companion [un]formatted page. |
* and use the newer one of the two. |
* If one is found, skip this page. |
|
* Use the companion instead, unless it will be found anyway. |
*/ |
*/ |
static void |
static void |
check_companion(char **orig) { |
check_companion(char **orig, TAG *tag) { |
struct stat sb_orig, sb_comp; |
struct stat sb_orig, sb_comp; |
char *p, *pext, comp[MAXPATHLEN]; |
char *p, *pext, comp[MAXPATHLEN]; |
|
ENTRY *entry; |
size_t len; |
size_t len; |
int found; |
int found; |
|
|
|
|
|
|
/* Search for slashes. */ |
/* Search for slashes. */ |
for (found = 0; 1; p--) { |
for (found = 0; 1; p--) { |
|
if (*p != '/') |
|
continue; |
|
|
/* Did not find /{cat,man}. */ |
/* Did not find /{cat,man}. */ |
if (p == comp) |
if (p == comp) |
return; |
return; |
|
|
/* Pass over one slash, the one before "page". */ |
/* Pass over one slash, the one before "page". */ |
if (*p != '/' || !found++) |
if (!found++) { |
|
len = p - comp; |
continue; |
continue; |
|
} |
|
|
/* Rewrite manN/page.N <-> catN/page.0. */ |
/* Rewrite manN/page.N <-> catN/page.0. */ |
if (!strncmp(p+1, "man", 3)) { |
if (!strncmp(p+1, "man", 3)) { |
|
|
sb_orig.st_mtim.tv_sec == sb_comp.st_mtim.tv_sec && |
sb_orig.st_mtim.tv_sec == sb_comp.st_mtim.tv_sec && |
sb_orig.st_mtim.tv_nsec > sb_comp.st_mtim.tv_nsec)) |
sb_orig.st_mtim.tv_nsec > sb_comp.st_mtim.tv_nsec)) |
return; |
return; |
|
|
|
/* Drop the companion if it is in the path, too. */ |
|
if (f_all || f_where) |
|
for(entry = TAILQ_FIRST(&tag->list); entry != NULL; |
|
entry = TAILQ_NEXT(entry, q)) |
|
if (!strncmp(entry->s, comp, len)) { |
|
**orig = '\0'; |
|
return; |
|
} |
|
|
/* The companion file is newer, use it. */ |
/* The companion file is newer, use it. */ |
free(*orig); |
free(*orig); |