From 1f05bc6c92b037a24315c8408aab875bbd6453b8 Mon Sep 17 00:00:00 2001 From: Johan Karlsson Date: Thu, 22 Aug 2002 01:50:51 +0000 Subject: [PATCH] Add the -a option to report all matches instead of only the first of each requested type. Approved by: joerg, sheldonh (mentor) --- usr.bin/whereis/pathnames.h | 1 + usr.bin/whereis/whereis.1 | 16 +++- usr.bin/whereis/whereis.c | 185 +++++++++++++++++++++++++----------- 3 files changed, 145 insertions(+), 57 deletions(-) diff --git a/usr.bin/whereis/pathnames.h b/usr.bin/whereis/pathnames.h index fce4274e644..09084aefa83 100644 --- a/usr.bin/whereis/pathnames.h +++ b/usr.bin/whereis/pathnames.h @@ -49,6 +49,7 @@ /* How to obtain the location of manpages, and how to match this result. */ #define MANWHEREISCMD "man -S1:8:6 -w %s 2>/dev/null" +#define MANWHEREISALLCMD "man -a -w %s 2>/dev/null" #define MANWHEREISMATCH "^.* [(]source: (.*)[)]$" /* Command used to locate sources that have not been found yet. */ diff --git a/usr.bin/whereis/whereis.1 b/usr.bin/whereis/whereis.1 index 12b9b9897c4..b1f8b953936 100644 --- a/usr.bin/whereis/whereis.1 +++ b/usr.bin/whereis/whereis.1 @@ -35,7 +35,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 11, 2002 +.Dd August 18, 2002 .Dt WHEREIS 1 .Os .Sh NAME @@ -43,7 +43,7 @@ .Nd locate programs .Sh SYNOPSIS .Nm -.Op Fl bmqsux +.Op Fl abmqsux .Op Fl BMS Ar dir Ar ... Fl f .Ar program ... .Sh DESCRIPTION @@ -94,6 +94,8 @@ option. Specify directories to search for program sources. Requires the .Fl f option. +.It Fl a +Report all matches instead of only the first of each requested type. .It Fl b Search for binaries. .It Fl f @@ -119,8 +121,8 @@ Search for source directories. .It Fl u Search for .Dq unusual -entries. A file is said to be unusual if it does not have one entry -of each requested type. +entries. A file is said to be unusual if it does not have at least +one entry of each requested type. Only the name of the unusual entry is printed. .It Fl x Do not use @@ -174,3 +176,9 @@ It is believed to be compatible with the version that was shipping with through .Fx 4.5 though. +.Pp +The +.Nm +utility can report some unrelated source entries when the +.Fl a +option is specified. diff --git a/usr.bin/whereis/whereis.c b/usr.bin/whereis/whereis.c index 58ca04a64d7..5b6a83e7d33 100644 --- a/usr.bin/whereis/whereis.c +++ b/usr.bin/whereis/whereis.c @@ -49,9 +49,13 @@ __FBSDID("$FreeBSD$"); #include "pathnames.h" +#define NO_BIN_FOUND 1 +#define NO_MAN_FOUND 2 +#define NO_SRC_FOUND 4 + typedef const char *ccharp; -int opt_b, opt_m, opt_q, opt_s, opt_u, opt_x; +int opt_a, opt_b, opt_m, opt_q, opt_s, opt_u, opt_x; ccharp *bindirs, *mandirs, *sourcedirs; char **query; @@ -84,7 +88,7 @@ void usage(void) { errx(EX_USAGE, - "usage: whereis [-bmqsux] [-BMS dir... -f] name ..."); + "usage: whereis [-abmqsux] [-BMS dir... -f] name ..."); } /* @@ -100,7 +104,7 @@ scanopts(int argc, char **argv) ccharp **dirlist; opt_f = 0; - while ((c = getopt(argc, argv, "BMSbfmqsux")) != -1) + while ((c = getopt(argc, argv, "BMSabfmqsux")) != -1) switch (c) { case 'B': dirlist = &bindirs; @@ -126,6 +130,10 @@ scanopts(int argc, char **argv) } break; + case 'a': + opt_a = 1; + break; + case 'b': opt_b = 1; break; @@ -353,7 +361,7 @@ main(int argc, char **argv) int unusual, i, printed; char *bin, buf[BUFSIZ], *cp, *cp2, *man, *name, *src; ccharp *dp; - size_t s; + size_t nlen, olen, s; struct stat sb; regex_t re, re2; regmatch_t matches[2]; @@ -412,7 +420,7 @@ main(int argc, char **argv) * Binaries have to match exactly, and must be regular * executable files. */ - unusual++; + unusual = unusual | NO_BIN_FOUND; for (dp = bindirs; *dp != NULL; dp++) { cp = malloc(strlen(*dp) + 1 + s + 1); if (cp == NULL) @@ -424,9 +432,23 @@ main(int argc, char **argv) (sb.st_mode & S_IFMT) == S_IFREG && (sb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0) { - unusual--; - bin = cp; - break; + unusual = unusual & ~NO_BIN_FOUND; + if (bin == NULL) { + bin = strdup(cp); + } else { + olen = strlen(bin); + nlen = strlen(cp); + bin = realloc(bin, + olen + nlen + 2); + if (bin == 0) + abort(); + strcat(bin, " "); + strcat(bin, cp); + } + if (!opt_a) { + free(cp); + break; + } } free(cp); } @@ -436,46 +458,76 @@ main(int argc, char **argv) /* * Ask the man command to perform the search for us. */ - unusual++; - cp = malloc(sizeof MANWHEREISCMD - 2 + s); + unusual = unusual | NO_MAN_FOUND; + if (opt_a) + cp = malloc(sizeof MANWHEREISALLCMD - 2 + s); + else + cp = malloc(sizeof MANWHEREISCMD - 2 + s); + if (cp == NULL) abort(); - sprintf(cp, MANWHEREISCMD, name); - if ((p = popen(cp, "r")) != NULL && - fgets(buf, BUFSIZ - 1, p) != NULL && - pclose(p) == 0) { - unusual--; - if ((cp2 = strchr(buf, '\n')) != NULL) - *cp2 = '\0'; - if (regexec(&re, buf, 2, matches, 0) == 0 && - (rlen = matches[1].rm_eo - matches[1].rm_so) - > 0) { - /* - * man -w found compressed - * page, need to pick up - * source page name. - */ - cp2 = malloc(rlen + 1); - if (cp2 == NULL) - abort(); - memcpy(cp2, buf + matches[1].rm_so, - rlen); - cp2[rlen] = '\0'; - man = cp2; - } else { - /* - * man -w found plain source - * page, use it. - */ - s = strlen(buf); - cp2 = malloc(s + 1); - if (cp2 == NULL) - abort(); - strcpy(cp2, buf); - man = cp2; + + if (opt_a) + sprintf(cp, MANWHEREISALLCMD, name); + else + sprintf(cp, MANWHEREISCMD, name); + + if ((p = popen(cp, "r")) != NULL) { + + while (fgets(buf, BUFSIZ - 1, p) != NULL) { + unusual = unusual & ~NO_MAN_FOUND; + + if ((cp2 = strchr(buf, '\n')) != NULL) + *cp2 = '\0'; + if (regexec(&re, buf, 2, + matches, 0) == 0 && + (rlen = matches[1].rm_eo - + matches[1].rm_so) > 0) { + /* + * man -w found formated + * page, need to pick up + * source page name. + */ + cp2 = malloc(rlen + 1); + if (cp2 == NULL) + abort(); + memcpy(cp2, + buf + matches[1].rm_so, + rlen); + cp2[rlen] = '\0'; + } else { + /* + * man -w found plain source + * page, use it. + */ + s = strlen(buf); + cp2 = malloc(s + 1); + if (cp2 == NULL) + abort(); + strcpy(cp2, buf); + } + + if (man == NULL) { + man = strdup(cp2); + } else { + olen = strlen(man); + nlen = strlen(cp2); + man = realloc(man, + olen + nlen + 2); + if (man == 0) + abort(); + strcat(man, " "); + strcat(man, cp2); + } + + free(cp2); + + if (!opt_a) + break; } + pclose(p); + free(cp); } - free(cp); } if (opt_s) { @@ -483,7 +535,7 @@ main(int argc, char **argv) * Sources match if a subdir with the exact * name is found. */ - unusual++; + unusual = unusual | NO_SRC_FOUND; for (dp = sourcedirs; *dp != NULL; dp++) { cp = malloc(strlen(*dp) + 1 + s + 1); if (cp == NULL) @@ -493,9 +545,23 @@ main(int argc, char **argv) strcat(cp, name); if (stat(cp, &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFDIR) { - unusual--; - src = cp; - break; + unusual = unusual & ~NO_SRC_FOUND; + if (src == NULL) { + src = strdup(cp); + } else { + olen = strlen(src); + nlen = strlen(cp); + src = realloc(src, + olen + nlen + 2); + if (src == 0) + abort(); + strcat(src, " "); + strcat(src, cp); + } + if (!opt_a) { + free(cp); + break; + } } free(cp); } @@ -511,7 +577,7 @@ main(int argc, char **argv) * with one of our source directories, and at * least one further level of subdirectories. */ - if (opt_x || src) + if (opt_x || (src && !opt_a)) goto done_sources; cp = malloc(sizeof LOCATECMD - 2 + s); @@ -520,12 +586,12 @@ main(int argc, char **argv) sprintf(cp, LOCATECMD, name); if ((p = popen(cp, "r")) == NULL) goto done_sources; - while (src == NULL && + while ((src == NULL || opt_a) && (fgets(buf, BUFSIZ - 1, p)) != NULL) { if ((cp2 = strchr(buf, '\n')) != NULL) *cp2 = '\0'; for (dp = sourcedirs; - src == NULL && *dp != NULL; + (src == NULL || opt_a) && *dp != NULL; dp++) { cp2 = malloc(strlen(*dp) + 9); if (cp2 == NULL) @@ -546,8 +612,21 @@ main(int argc, char **argv) if (regexec(&re2, buf, 0, (regmatch_t *)NULL, 0) == 0) { - unusual--; - src = buf; + unusual = unusual & + ~NO_SRC_FOUND; + if (src == NULL) { + src = strdup(buf); + } else { + olen = strlen(src); + nlen = strlen(buf); + src = realloc(src, + olen + + nlen + 2); + if (src == 0) + abort(); + strcat(src, " "); + strcat(src, buf); + } } regfree(&re2); } -- 2.45.2