From: Karel Zak Date: Wed, 25 Jan 2023 13:13:05 +0000 (+0100) Subject: whereis: add glob(7) support (new option -g) X-Git-Tag: v2.39-rc1~110 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d9b022bd2627bee6162361cba39bba64837324a9;p=thirdparty%2Futil-linux.git whereis: add glob(7) support (new option -g) $ whereis -b -g 'find???' find???: /usr/bin/findmnt /usr/bin/findscu Fixes: https://github.com/util-linux/util-linux/issues/2021 Signed-off-by: Karel Zak --- diff --git a/bash-completion/whereis b/bash-completion/whereis index 013f68c72d..7db67a398c 100644 --- a/bash-completion/whereis +++ b/bash-completion/whereis @@ -17,7 +17,7 @@ _whereis_module() esac case $cur in -*) - OPTS="-b -B -m -M -s -S -f -u -l" + OPTS="-b -B -m -M -s -S -f -u -l -g" COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) ) return 0 ;; diff --git a/configure.ac b/configure.ac index 06843d2ab8..675098d37f 100644 --- a/configure.ac +++ b/configure.ac @@ -545,6 +545,7 @@ AC_CHECK_FUNCS([ \ __fpending \ __fpurge \ fpurge \ + fnmatch \ fsconfig \ fsmount \ fsopen \ diff --git a/meson.build b/meson.build index 50648935af..d263cb6d20 100644 --- a/meson.build +++ b/meson.build @@ -485,6 +485,7 @@ funcs = ''' errx explicit_bzero fmemopen + fnmatch fseeko fsconfig fsmount diff --git a/misc-utils/whereis.1.adoc b/misc-utils/whereis.1.adoc index 2b07a967d8..e5b5457ed3 100644 --- a/misc-utils/whereis.1.adoc +++ b/misc-utils/whereis.1.adoc @@ -50,7 +50,7 @@ whereis - locate the binary, source, and manual page files for a command == DESCRIPTION -*whereis* locates the binary, source and manual files for the specified command names. The supplied names are first stripped of leading pathname components. Prefixes of *s.* resulting from use of source code control are also dealt with. *whereis* then attempts to locate the desired program in the standard Linux places, and in the places specified by *$PATH* and *$MANPATH*. +*whereis* locates the binary, source and manual files for the specified command names. The supplied names are *first stripped of leading pathname components*. Prefixes of *s.* resulting from use of source code control are also dealt with. *whereis* then attempts to locate the desired program in the standard Linux places, and in the places specified by *$PATH* and *$MANPATH*. The search restrictions (options *-b*, *-m* and *-s*) are cumulative and apply to the subsequent _name_ patterns on the command line. Any new search restriction resets the search mask. For example, @@ -97,6 +97,12 @@ Terminates the directory list and signals the start of filenames. It _must_ be u *-l*:: Output the list of effective lookup paths that *whereis* is using. When none of *-B*, *-M*, or *-S* is specified, the option will output the hard-coded paths that the command was able to find on the system. +*-g*:: +Interpret the next names as a *glob(7)* patterns. *whereis* always compares only filenames (aka basename) and never complete path. Using directory names in the pattern has no effect. Don’t forget that the shell interprets the pattern when specified on the command line without quotes. It’s necessary to use quotes for the _name_, for example: +____ + whereis -g 'find*' +____ + include::man-common/help-version.adoc[] == FILE SEARCH PATHS diff --git a/misc-utils/whereis.c b/misc-utils/whereis.c index db092ce609..d21b434762 100644 --- a/misc-utils/whereis.c +++ b/misc-utils/whereis.c @@ -48,6 +48,9 @@ #include #include #include +#ifdef HAVE_FNMATCH +# include +#endif #include "xalloc.h" #include "nls.h" @@ -75,7 +78,8 @@ UL_DEBUG_DEFINE_MASKNAMES(whereis) = UL_DEBUG_EMPTY_MASKNAMES; #define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(whereis) #include "debugobj.h" -static char uflag = 0; +static char uflag; +static char use_glob; /* supported types */ enum { @@ -212,6 +216,7 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_(" -S define sources lookup path\n"), out); fputs(_(" -f terminate argument list\n"), out); fputs(_(" -u search for unusual entries\n"), out); + fputs(_(" -g interpret name as glob (pathnames pattern)\n"), out); fputs(_(" -l output effective lookup paths\n"), out); fputs(USAGE_SEPARATOR, out); @@ -394,13 +399,20 @@ static void free_dirlist(struct wh_dirlist **ls0, int type) static int filename_equal(const char *cp, const char *dp, int type) { - int i = strlen(dp); + size_t i; DBG(SEARCH, ul_debug("compare '%s' and '%s'", cp, dp)); +#ifdef HAVE_FNMATCH + if (use_glob) + return fnmatch(cp, dp, 0) == 0; +#endif if (type & SRC_DIR && dp[0] == 's' && dp[1] == '.' && filename_equal(cp, dp + 2, type)) return 1; + + i = strlen(dp); + if (type & MAN_DIR) { if (i > 1 && !strcmp(dp + i - 2, ".Z")) i -= 2; @@ -635,6 +647,9 @@ int main(int argc, char **argv) case 'l': list_dirlist(ls); break; + case 'g': + use_glob = 1; + break; case 'V': print_version(EXIT_SUCCESS);