whereis: cleanup debug stuff, fix argv[] usage
* use debug stuff from include/debug.h and make whereis(1) sensitive to WHEREIS_DEBUG=0xffff mask * fix problem with argv[] usage # whereis -b -m -M /usr/share/man/man1 -B /usr/bin -f gcc bin: /usr/local/bin gcc: /usr/bin/gcc /usr/lib/gcc /usr/libexec/gcc /usr/share/man/man1/gcc.1.gz the code ignores "-B" and /usr/bin is interpreted as search pattern, expected result is: # whereis -b -m -M /usr/share/man/man1 -B /usr/bin -f gcc gcc: /usr/share/man/man1/gcc.1.gz /usr/bin/gcc Addresses: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765306 Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
fd211531e8
commit
3635f53ca2
|
@ -57,7 +57,7 @@ struct dbg_mask { char *mname; int val; };
|
|||
lib ## _debug_mask = mask; \
|
||||
lib ## _debug_mask |= pref ## INIT; \
|
||||
if (lib ## _debug_mask != pref ## INIT) { \
|
||||
__UL_DBG(lib, pref, INIT, ul_debug("library debug mask: 0x%04x", \
|
||||
__UL_DBG(lib, pref, INIT, ul_debug("debug mask: 0x%04x", \
|
||||
lib ## _debug_mask)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
|
|
@ -55,7 +55,22 @@
|
|||
#include "closestream.h"
|
||||
#include "canonicalize.h"
|
||||
|
||||
/*#define DEBUG*/
|
||||
#include "debug.h"
|
||||
|
||||
UL_DEBUG_DEFINE_MASK(whereis);
|
||||
UL_DEBUG_DEFINE_MASKANEMS(whereis) = UL_DEBUG_EMPTY_MASKNAMES;
|
||||
|
||||
#define WHEREIS_DEBUG_INIT (1 << 1)
|
||||
#define WHEREIS_DEBUG_PATH (1 << 2)
|
||||
#define WHEREIS_DEBUG_ENV (1 << 3)
|
||||
#define WHEREIS_DEBUG_ARGV (1 << 4)
|
||||
#define WHEREIS_DEBUG_SEARCH (1 << 5)
|
||||
#define WHEREIS_DEBUG_STATIC (1 << 6)
|
||||
#define WHEREIS_DEBUG_LIST (1 << 7)
|
||||
#define WHEREIS_DEBUG_ALL 0xFFFF
|
||||
|
||||
#define DBG(m, x) __UL_DBG(whereis, WHEREIS_DEBUG_, m, x)
|
||||
#define ON_DBG(m, x) __UL_DBG_CALL(whereis, WHEREIS_DEBUG_, m, x)
|
||||
|
||||
static char uflag = 0;
|
||||
|
||||
|
@ -152,15 +167,20 @@ static const char *srcdirs[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
# define DBG(_x) do { \
|
||||
printf("DEBUG: "); \
|
||||
_x; \
|
||||
fputc('\n', stdout); \
|
||||
} while (0)
|
||||
#else
|
||||
# define DBG(_x)
|
||||
#endif
|
||||
static void whereis_init_debug(void)
|
||||
{
|
||||
__UL_INIT_DEBUG(whereis, WHEREIS_DEBUG_, 0, WHEREIS_DEBUG);
|
||||
}
|
||||
|
||||
static const char *whereis_type_to_name(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case BIN_DIR: return "bin";
|
||||
case MAN_DIR: return "man";
|
||||
case SRC_DIR: return "src";
|
||||
default: return "???";
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((__noreturn__)) usage(FILE *out)
|
||||
{
|
||||
|
@ -187,24 +207,22 @@ static void dirlist_add_dir(struct wh_dirlist **ls0, int type, const char *dir)
|
|||
struct stat st;
|
||||
struct wh_dirlist *prev = NULL, *ls = *ls0;
|
||||
|
||||
DBG(printf("add dir: '%s'", dir));
|
||||
|
||||
if (access(dir, R_OK) != 0)
|
||||
return;
|
||||
if (stat(dir, &st) != 0 || !S_ISDIR(st.st_mode))
|
||||
return;
|
||||
|
||||
while (ls) {
|
||||
if (ls->st_ino == st.st_ino &&
|
||||
ls->st_dev == st.st_dev &&
|
||||
ls->type == type) {
|
||||
DBG(printf(" already in the list, ignore"));
|
||||
DBG(LIST, ul_debugobj(*ls0, " ignore (already in list): %s", dir));
|
||||
return;
|
||||
}
|
||||
prev = ls;
|
||||
ls = ls->next;
|
||||
}
|
||||
|
||||
DBG(printf(" adding new directory"));
|
||||
|
||||
ls = xcalloc(1, sizeof(*ls));
|
||||
ls->st_ino = st.st_ino;
|
||||
|
@ -218,6 +236,8 @@ static void dirlist_add_dir(struct wh_dirlist **ls0, int type, const char *dir)
|
|||
assert(prev);
|
||||
prev->next = ls; /* add to the end of the list */
|
||||
}
|
||||
|
||||
DBG(LIST, ul_debugobj(*ls0, " add dir: %s", ls->path));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -231,8 +251,6 @@ static void dirlist_add_subdir(struct wh_dirlist **ls, int type, const char *dir
|
|||
strncpy(buf, dir, PATH_MAX);
|
||||
buf[PATH_MAX - 1] = '\0';
|
||||
|
||||
DBG(printf("add subdir: %s", buf));
|
||||
|
||||
d = strchr(buf, '*');
|
||||
if (!d)
|
||||
return;
|
||||
|
@ -242,7 +260,7 @@ static void dirlist_add_subdir(struct wh_dirlist **ls, int type, const char *dir
|
|||
if (!dirp)
|
||||
return;
|
||||
|
||||
DBG(printf(" scan: %s", buf));
|
||||
DBG(LIST, ul_debugobj(*ls, " scanning subdir: %s", dir));
|
||||
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
|
||||
|
@ -266,7 +284,8 @@ static void construct_dirlist_from_env(const char *env,
|
|||
return;
|
||||
pathcp = xstrdup(path);
|
||||
|
||||
DBG(printf("construct from env: %s", path));
|
||||
DBG(ENV, ul_debugobj(*ls, "construct %s dirlist from: %s",
|
||||
whereis_type_to_name(type), path));
|
||||
|
||||
for (tok = strtok_r(pathcp, ":", &key); tok;
|
||||
tok = strtok_r(NULL, ":", &key))
|
||||
|
@ -282,13 +301,20 @@ static void construct_dirlist_from_argv(struct wh_dirlist **ls,
|
|||
char *argv[],
|
||||
int type)
|
||||
{
|
||||
DBG(printf("construct argv[%d..]", *idx));
|
||||
int i;
|
||||
|
||||
for (; *idx < argc; (*idx)++) {
|
||||
if (*argv[*idx] == '-') /* end of the list */
|
||||
return;
|
||||
dirlist_add_dir(ls, type, argv[*idx]);
|
||||
DBG(ARGV, ul_debugobj(*ls, "construct %s dirlist from argv[%d..]",
|
||||
whereis_type_to_name(type), *idx));
|
||||
|
||||
for (i = *idx; i < argc; i++) {
|
||||
if (*argv[i] == '-') /* end of the list */
|
||||
break;
|
||||
|
||||
DBG(ARGV, ul_debugobj(*ls, " using argv[%d]: %s", *idx, argv[*idx]));
|
||||
dirlist_add_dir(ls, type, argv[i]);
|
||||
*idx = i;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -298,7 +324,8 @@ static void construct_dirlist(struct wh_dirlist **ls,
|
|||
{
|
||||
size_t i;
|
||||
|
||||
DBG(printf("construct from dirs"));
|
||||
DBG(STATIC, ul_debugobj(*ls, "construct %s dirlist from static array",
|
||||
whereis_type_to_name(type)));
|
||||
|
||||
for (i = 0; paths[i]; i++) {
|
||||
if (!strchr(paths[i], '*'))
|
||||
|
@ -315,14 +342,12 @@ static void free_dirlist(struct wh_dirlist **ls0, int type)
|
|||
|
||||
*ls0 = NULL;
|
||||
|
||||
DBG(printf("freeing dirlist"));
|
||||
DBG(LIST, ul_debugobj(*ls0, "free dirlist"));
|
||||
|
||||
while (ls) {
|
||||
if (ls->type & type) {
|
||||
next = ls->next;
|
||||
|
||||
DBG(printf("freeing dir: %s", ls->path));
|
||||
|
||||
DBG(LIST, ul_debugobj(*ls0, " free: %s", ls->path));
|
||||
free(ls->path);
|
||||
free(ls);
|
||||
ls = next;
|
||||
|
@ -381,7 +406,7 @@ static void findin(const char *dir, const char *pattern, int *count, char **wait
|
|||
if (dirp == NULL)
|
||||
return;
|
||||
|
||||
DBG(printf("find '%s' in '%s'", pattern, dir));
|
||||
DBG(SEARCH, ul_debug("find '%s' in '%s'", pattern, dir));
|
||||
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
if (!filename_equal(pattern, dp->d_name))
|
||||
|
@ -413,7 +438,12 @@ static void lookup(const char *pattern, struct wh_dirlist *ls, int want)
|
|||
p = p ? p + 1 : (char *) pattern;
|
||||
strncpy(patbuf, p, PATH_MAX);
|
||||
patbuf[PATH_MAX - 1] = '\0';
|
||||
DBG(printf("lookup dirs for '%s' (%s)", patbuf, pattern));
|
||||
|
||||
DBG(SEARCH, ul_debug("lookup dirs for '%s' (%s), want: %s %s %s",
|
||||
patbuf, pattern,
|
||||
want & BIN_DIR ? "bin" : "",
|
||||
want & MAN_DIR ? "min" : "",
|
||||
want & SRC_DIR ? "src" : ""));
|
||||
p = strrchr(patbuf, '.');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
|
@ -471,6 +501,8 @@ int main(int argc, char **argv)
|
|||
if (argc == 1)
|
||||
usage(stderr);
|
||||
|
||||
whereis_init_debug();
|
||||
|
||||
construct_dirlist(&ls, BIN_DIR, bindirs);
|
||||
construct_dirlist_from_env("PATH", &ls, BIN_DIR);
|
||||
|
||||
|
@ -481,13 +513,16 @@ int main(int argc, char **argv)
|
|||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
int arg_i = i;
|
||||
|
||||
DBG(ARGV, ul_debug("argv[%d]: %s", i, arg));
|
||||
|
||||
if (*arg != '-') {
|
||||
lookup(arg, ls, want);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i > 1 && *argv[i - 1] != '-')
|
||||
if (i > 1 && *argv[i - 1] != '-') {
|
||||
/* the list of search patterns has been interupted by
|
||||
* any non-pattern option, then reset the mask for
|
||||
* wanted directories. For example:
|
||||
|
@ -496,9 +531,14 @@ int main(int argc, char **argv)
|
|||
*
|
||||
* search for "ls" in mandirs and "tr" in bindirs
|
||||
*/
|
||||
DBG(ARGV, ul_debug("list of search patterns interupted "
|
||||
"by non-pattern"));
|
||||
want = ALL_DIRS;
|
||||
}
|
||||
|
||||
for (++arg; arg && *arg; arg++) {
|
||||
DBG(ARGV, ul_debug(" arg: %s", arg));
|
||||
|
||||
switch (*arg) {
|
||||
case 'f':
|
||||
break;
|
||||
|
@ -549,11 +589,12 @@ int main(int argc, char **argv)
|
|||
default:
|
||||
usage(stderr);
|
||||
}
|
||||
|
||||
if (arg_i < i) /* moved the the next argv[] item */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DBG(printf("DONE"));
|
||||
free_dirlist(&ls, ALL_DIRS);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue