diff options
author | Karel Zak <kzak@redhat.com> | 2014-10-23 13:44:00 +0200 |
---|---|---|
committer | Karel Zak <kzak@redhat.com> | 2014-10-24 11:26:18 +0200 |
commit | 0d21f36ff3643ad2ea708f3596d64042331b037a (patch) | |
tree | 8b962d6510882343eba92d0647a41ad802187b79 | |
parent | d2a3cce95a2f4f1329ea4c8d77c09c2ae35de859 (diff) | |
download | util-linux-0d21f36ff3643ad2ea708f3596d64042331b037a.tar.gz |
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>
-rw-r--r-- | include/debug.h | 2 | ||||
-rw-r--r-- | misc-utils/whereis.c | 106 |
2 files changed, 74 insertions, 34 deletions
diff --git a/include/debug.h b/include/debug.h index 2eb9d4421..a3bb14269 100644 --- a/include/debug.h +++ b/include/debug.h @@ -52,7 +52,7 @@ 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) diff --git a/misc-utils/whereis.c b/misc-utils/whereis.c index a422c473b..1def37dfc 100644 --- a/misc-utils/whereis.c +++ b/misc-utils/whereis.c @@ -55,7 +55,21 @@ #include "closestream.h" #include "canonicalize.h" -/*#define DEBUG*/ +#include "debug.h" + +UL_DEBUG_DEFINE_MASK(whereis); + +#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 +166,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 +206,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 +235,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 +250,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 +259,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 +283,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 +300,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 +323,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 +341,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 +405,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 +437,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 +500,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 +512,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 +530,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 +588,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; } |