From 80b6034777e548d7a3c485c70e19cead39641d9f Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Thu, 10 Oct 2013 21:27:48 +0200 Subject: [PATCH] man: fix suffix parsing for good Instead of guessing the suffix in the code, use the suffix list previously loaded via man.conf(5). While there, zap unused interation code. --- usr.bin/man/man.c | 65 ++++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/usr.bin/man/man.c b/usr.bin/man/man.c index 6ea0df2919..4744f75849 100644 --- a/usr.bin/man/man.c +++ b/usr.bin/man/man.c @@ -464,6 +464,43 @@ main(int argc, char **argv) exit(cleanup()); } +static int +manual_find_literalfile(struct manstate *mp, glob_t *pg, size_t cnt) +{ + ENTRY *suffix; + int found; + char buf[MAXPATHLEN]; + const char *p; + int suflen; + + found = 0; + + /* + * Expand both '*' and suffix to force an actual + * match via fnmatch(3). Since the only match in pg + * is the literal file, the match is genuine. + */ + + TAILQ_FOREACH(suffix, &mp->buildlist->entrylist, q) { + for (p = suffix->s, suflen = 0; + *p != '\0' && !isspace((unsigned char)*p); + ++p) + ++suflen; + if (*p == '\0') + continue; + + (void)snprintf(buf, sizeof(buf), "*%.*s", suflen, suffix->s); + if (!fnmatch(buf, pg->gl_pathv[cnt], 0)) { + if (!mp->where) + build_page(p + 1, &pg->gl_pathv[cnt], mp); + found = 1; + break; + } + } + + return found; +} + static int manual_find_buildkeyword(const char *prefix, const char *escpage, struct manstate *mp, glob_t *pg, size_t cnt) @@ -554,30 +591,12 @@ manual(char *page, struct manstate *mp, glob_t *pg) if (pg->gl_matchc == 0) goto notfound; - /* clip suffix for the suffix check below */ - p = strrchr(escpage, '/'); - while ((p = strchr(p, '.')) && !isdigit(p[1])) - ++p; - if (p) - p[0] = '\0'; - - found = 0; - for (cnt = pg->gl_pathc - pg->gl_matchc; - cnt < pg->gl_pathc; ++cnt) - { - found = manual_find_buildkeyword("", escpage, - mp, pg, cnt); - if (found) { - anyfound = 1; - if (!mp->all) { - /* Delete any other matches. */ - while (++cnt< pg->gl_pathc) - *pg->gl_pathv[cnt] = '\0'; - break; - } - continue; - } + /* literal file only yields one match */ + cnt = pg->gl_pathc - pg->gl_matchc; + if (manual_find_literalfile(mp, pg, cnt)) { + anyfound = 1; + } else { /* It's not a man page, forget about it. */ *pg->gl_pathv[cnt] = '\0'; } -- 2.41.0