* 'whereis' of https://github.com/ferivoz/util-linux:
  whereis: extend test case
  whereis: filter bin, man and src differently
  whereis: do not strip suffixes
  whereis: do not ignore trailing numbers
  whereis: add --disable-whereis to configure
  whereis: add lib32 directories
  whereis: support zst compressed man pages
  whereis: fix out of boundary read
This commit is contained in:
Karel Zak 2020-11-06 09:44:52 +01:00
commit de9cbcdcef
5 changed files with 59 additions and 32 deletions

View File

@ -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])

View File

@ -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.

View File

@ -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);

View File

@ -1 +1,5 @@
success
fsck success
fsck.ext4 success
python success
python3 success
python3.8 success

View File

@ -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