diff --git a/configure.ac b/configure.ac index 52d84cdd8..ce814eede 100644 --- a/configure.ac +++ b/configure.ac @@ -1651,7 +1651,11 @@ if test "x$matriplet" != "x"; then AC_DEFINE_UNQUOTED([MULTIARCHTRIPLET], ["$matriplet"], ["Multi-arch triplet for whereis library search path"]) fi -UL_BUILD_INIT([whereis], [yes]) +AC_ARG_ENABLE([whereis], + AS_HELP_STRING([--disable-whereis], [do not build whereis]), + [], [UL_DEFAULT_ENABLE([whereis], [check])] +) +UL_BUILD_INIT([whereis]) AM_CONDITIONAL([BUILD_WHEREIS], [test "x$build_whereis" = xyes]) UL_BUILD_INIT([getopt], [yes]) diff --git a/misc-utils/whereis.1 b/misc-utils/whereis.1 index 08e351cec..2ecc70f21 100644 --- a/misc-utils/whereis.1 +++ b/misc-utils/whereis.1 @@ -42,11 +42,7 @@ whereis \- locate the binary, source, and manual page files for a command .SH DESCRIPTION .B whereis locates the binary, source and manual files for the specified command names. -The supplied names are first stripped of leading pathname components and any -(single) trailing extension of the form -.BI . ext -(for example: -.BR .c ) +The supplied names are first stripped of leading pathname components. Prefixes of .B s. resulting from use of source code control are also dealt with. diff --git a/misc-utils/whereis.c b/misc-utils/whereis.c index 7a28a2c35..db092ce60 100644 --- a/misc-utils/whereis.c +++ b/misc-utils/whereis.c @@ -107,10 +107,12 @@ static const char *bindirs[] = { "/usr/local/lib/" MULTIARCHTRIPLET, #endif "/usr/lib", + "/usr/lib32", "/usr/lib64", "/etc", "/usr/etc", "/lib", + "/lib32", "/lib64", "/usr/games", "/usr/games/bin", @@ -390,29 +392,32 @@ static void free_dirlist(struct wh_dirlist **ls0, int type) } -static int filename_equal(const char *cp, const char *dp) +static int filename_equal(const char *cp, const char *dp, int type) { int i = strlen(dp); DBG(SEARCH, ul_debug("compare '%s' and '%s'", cp, dp)); - if (dp[0] == 's' && dp[1] == '.' && filename_equal(cp, dp + 2)) + if (type & SRC_DIR && + dp[0] == 's' && dp[1] == '.' && filename_equal(cp, dp + 2, type)) return 1; - if (!strcmp(dp + i - 2, ".Z")) - i -= 2; - else if (!strcmp(dp + i - 3, ".gz")) - i -= 3; - else if (!strcmp(dp + i - 3, ".xz")) - i -= 3; - else if (!strcmp(dp + i - 4, ".bz2")) - i -= 4; + if (type & MAN_DIR) { + if (i > 1 && !strcmp(dp + i - 2, ".Z")) + i -= 2; + else if (i > 2 && !strcmp(dp + i - 3, ".gz")) + i -= 3; + else if (i > 2 && !strcmp(dp + i - 3, ".xz")) + i -= 3; + else if (i > 3 && !strcmp(dp + i - 4, ".bz2")) + i -= 4; + else if (i > 3 && !strcmp(dp + i - 4, ".zst")) + i -= 4; + } while (*cp && *dp && *cp == *dp) cp++, dp++, i--; if (*cp == 0 && *dp == 0) return 1; - while (isdigit(*dp)) - dp++; - if (*cp == 0 && *dp++ == '.') { + if (!(type & BIN_DIR) && *cp == 0 && *dp++ == '.') { --i; while (i > 0 && *dp) if (--i, *dp++ == '.') @@ -422,7 +427,8 @@ static int filename_equal(const char *cp, const char *dp) return 0; } -static void findin(const char *dir, const char *pattern, int *count, char **wait) +static void findin(const char *dir, const char *pattern, int *count, + char **wait, int type) { DIR *dirp; struct dirent *dp; @@ -434,7 +440,7 @@ static void findin(const char *dir, const char *pattern, int *count, char **wait DBG(SEARCH, ul_debug("find '%s' in '%s'", pattern, dir)); while ((dp = readdir(dirp)) != NULL) { - if (!filename_equal(pattern, dp->d_name)) + if (!filename_equal(pattern, dp->d_name, type)) continue; if (uflag && *count == 0) @@ -467,9 +473,6 @@ static void lookup(const char *pattern, struct wh_dirlist *ls, int want) want & BIN_DIR ? "bin" : "", want & MAN_DIR ? "man" : "", want & SRC_DIR ? "src" : "")); - p = strrchr(patbuf, '.'); - if (p) - *p = '\0'; if (!uflag) /* if -u not specified then we always print the pattern */ @@ -477,7 +480,7 @@ static void lookup(const char *pattern, struct wh_dirlist *ls, int want) for (; ls; ls = ls->next) { if ((ls->type & want) && ls->path) - findin(ls->path, patbuf, &count, &wait); + findin(ls->path, patbuf, &count, &wait, ls->type); } free(wait); diff --git a/tests/expected/misc/whereis b/tests/expected/misc/whereis index 2e9ba477f..69d1a6ef2 100644 --- a/tests/expected/misc/whereis +++ b/tests/expected/misc/whereis @@ -1 +1,5 @@ -success +fsck success +fsck.ext4 success +python success +python3 success +python3.8 success diff --git a/tests/ts/misc/whereis b/tests/ts/misc/whereis index ee7ec2701..44643aefa 100755 --- a/tests/ts/misc/whereis +++ b/tests/ts/misc/whereis @@ -20,11 +20,31 @@ ts_init "$*" ts_check_test_command "$TS_CMD_WHEREIS" -LS_COUNT=$($TS_CMD_WHEREIS ls | wc -w) -if [ $LS_COUNT -lt 2 ]; then - echo "ls binary nor manual not found?" > $TS_OUTPUT -else - echo "success" > $TS_OUTPUT -fi +BIN_DIR="$(mktemp -d "${TS_OUTDIR}/binXXXXXXXXXXXXX")" +MAN_DIR="$(mktemp -d "${TS_OUTDIR}/manXXXXXXXXXXXXX")" +touch "$BIN_DIR/fsck" +touch "$MAN_DIR/fsck.8.zst" +touch "$BIN_DIR/fsck.ext4" +touch "$MAN_DIR/fsck.ext4.8.zst" +touch "$BIN_DIR/fsck.minix" +touch "$BIN_DIR/python" +touch "$MAN_DIR/python.1.gz" +touch "$BIN_DIR/python3" +touch "$MAN_DIR/python3.1" +touch "$BIN_DIR/python3.8" +touch "$BIN_DIR/python3.8-config" +touch "$MAN_DIR/python3.8.1" + +for COMMAND in fsck fsck.ext4 python python3 python3.8 +do + COUNT=$($TS_CMD_WHEREIS -B $BIN_DIR -M $MAN_DIR -f $COMMAND | wc -w) + if [ $COUNT -eq 3 ]; then + echo "$COMMAND success" >> $TS_OUTPUT + else + echo "$COMMAND failure" >> $TS_OUTPUT + fi +done + +rm -rf "$BIN_DIR" "$MAN_DIR" ts_finalize