diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2011-07-07 04:24:36 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2011-07-07 04:24:36 +0000 |
commit | 19703c0e30e9beaa96da075c43ff0412ea45c88d (patch) | |
tree | 7ffc0626cfcdd20f881b57920bd016673c4775e9 /usr.bin/man | |
parent | ef73fe0c4db1445d289c4ac3b6b50b178295bae0 (diff) |
For man -a and -w, drop companion pages that are also in the path,
such that we don't display them twice.
To be able to do that path check, we have to brace-expand the search
path up front - of course, for -a and -w only, so it doesn't slow
us down in the standard case.
As a free bonus, let -wa print all the filenames without looking
at the timestamps. In the past, -w implied -a, so that's not
introducing any incompatibility.
Issue originally reported and fix OK'd by guenther@,
and deraadt@ agrees with the semantics.
Diffstat (limited to 'usr.bin/man')
-rw-r--r-- | usr.bin/man/man.1 | 17 | ||||
-rw-r--r-- | usr.bin/man/man.c | 82 |
2 files changed, 82 insertions, 17 deletions
diff --git a/usr.bin/man/man.1 b/usr.bin/man/man.1 index 7d585a2389e..54d196225a5 100644 --- a/usr.bin/man/man.1 +++ b/usr.bin/man/man.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: man.1,v 1.46 2010/09/19 07:40:01 jmc Exp $ +.\" $OpenBSD: man.1,v 1.47 2011/07/07 04:24:35 schwarze Exp $ .\" .\" Copyright (c) 1989, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" @(#)man.1 8.2 (Berkeley) 1/2/94 .\" -.Dd $Mdocdate: September 19 2010 $ +.Dd $Mdocdate: July 7 2011 $ .Dt MAN 1 .Os .Sh NAME @@ -260,6 +260,19 @@ man pages can be found in .Xr mdoc 7 . A full tutorial for writing man pages is provided in .Xr mdoc.samples 7 . +.Pp +If both a formatted and an unformatted version of the same manual page, +for example +.Pa cat1/foo.0 +and +.Pa man1/foo.1 , +exist in the same directory, and at least one of them is selected, +only the newer one is used. +However, if both the +.Fl a +and the +.Fl w +options are specified, both file names are printed. .Sh ENVIRONMENT .Bl -tag -width MANPATHX .It Ev MACHINE diff --git a/usr.bin/man/man.c b/usr.bin/man/man.c index f7d7c384be9..f833d35c6c8 100644 --- a/usr.bin/man/man.c +++ b/usr.bin/man/man.c @@ -1,4 +1,4 @@ -/* $OpenBSD: man.c,v 1.42 2011/07/05 05:47:20 schwarze Exp $ */ +/* $OpenBSD: man.c,v 1.43 2011/07/07 04:24:35 schwarze Exp $ */ /* $NetBSD: man.c,v 1.7 1995/09/28 06:05:34 tls Exp $ */ /* @@ -83,7 +83,7 @@ static int cleanup(int); static void how(char *); static void jump(char **, char *, char *); static int manual(char *, TAG *, glob_t *); -static void check_companion(char **); +static void check_companion(char **, TAG *); static void onsig(int); static void usage(void); @@ -153,7 +153,7 @@ main(int argc, char *argv[]) jump(argv, "-k", "apropos"); /* NOTREACHED */ case 'w': - f_all = f_where = 1; + f_where = 1; break; case '?': default: @@ -434,20 +434,54 @@ manual(char *page, TAG *tag, glob_t *pg) { ENTRY *ep, *e_sufp, *e_tag; TAG *missp, *sufp; - int anyfound, cnt, found; + int anyfound, cnt, found, globres; char *p, buf[MAXPATHLEN]; anyfound = 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... */ e_tag = tag == NULL ? NULL : TAILQ_FIRST(&tag->list); for (; e_tag != NULL; e_tag = TAILQ_NEXT(e_tag, q)) { (void)snprintf(buf, sizeof(buf), "%s/%s.*", e_tag->s, page); - if (glob(buf, - GLOB_APPEND | GLOB_BRACE | GLOB_NOSORT | GLOB_QUOTE, + switch (glob(buf, GLOB_APPEND | GLOB_BRACE | GLOB_NOSORT, NULL, pg)) { - warn("globbing"); + case (0): + break; + case (GLOB_NOMATCH): + continue; + default: + warn("globbing files"); (void)cleanup(0); exit(1); } @@ -458,8 +492,11 @@ manual(char *page, TAG *tag, glob_t *pg) for (cnt = pg->gl_pathc - pg->gl_matchc; cnt < pg->gl_pathc; ++cnt) { - if (!f_all) - check_companion(pg->gl_pathv + cnt); + if (!f_all || !f_where) { + check_companion(pg->gl_pathv + cnt, tag); + if (*pg->gl_pathv[cnt] == '\0') + continue; + } /* * Try the _suffix key words first. @@ -512,7 +549,7 @@ manual(char *page, TAG *tag, glob_t *pg) } if (found) { next: anyfound = 1; - if (!f_all) { + if (!f_all && !f_where) { /* Delete any other matches. */ while (++cnt< pg->gl_pathc) pg->gl_pathv[cnt] = ""; @@ -525,7 +562,7 @@ next: anyfound = 1; pg->gl_pathv[cnt] = ""; } - if (anyfound && !f_all) + if (anyfound && !f_all && !f_where) break; } @@ -551,13 +588,15 @@ next: anyfound = 1; /* * check_companion -- - * Check for a companion [un]formatted page - * and use the newer one of the two. + * Check for a companion [un]formatted page. + * If one is found, skip this page. + * Use the companion instead, unless it will be found anyway. */ static void -check_companion(char **orig) { +check_companion(char **orig, TAG *tag) { struct stat sb_orig, sb_comp; char *p, *pext, comp[MAXPATHLEN]; + ENTRY *entry; size_t len; int found; @@ -574,14 +613,18 @@ check_companion(char **orig) { /* Search for slashes. */ for (found = 0; 1; p--) { + if (*p != '/') + continue; /* Did not find /{cat,man}. */ if (p == comp) return; /* Pass over one slash, the one before "page". */ - if (*p != '/' || !found++) + if (!found++) { + len = p - comp; continue; + } /* Rewrite manN/page.N <-> catN/page.0. */ if (!strncmp(p+1, "man", 3)) { @@ -611,6 +654,15 @@ check_companion(char **orig) { sb_orig.st_mtim.tv_nsec > sb_comp.st_mtim.tv_nsec)) 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. */ free(*orig); if ((p = strdup(comp)) == NULL) { |