diff options
Diffstat (limited to 'toys/which.c')
-rw-r--r-- | toys/which.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/toys/which.c b/toys/which.c new file mode 100644 index 00000000..6d00bc82 --- /dev/null +++ b/toys/which.c @@ -0,0 +1,72 @@ +/* vi: set sw=4 ts=4: */ +/* + * which.c - + * + * Copyright 2006 Rob landley <rob@landley.net> + */ + +#include "toys.h" + +#define OPTIONS "a" +#define OPT_a 1 + +// Find an exectuable file either at a path with a slash in it (absolute or +// relative to current directory), or in $PATH. Returns absolute path to file, +// or NULL if not found. + +static int which_in_path(char *filename) +{ + struct string_list *list; + + // If they gave us a path, don't worry about $PATH or -a + + if (index(filename, '/')) { + // Confirm it has the executable bit set, and it's not a directory. + if (!access(filename, X_OK)) { + struct stat st; + + if (!stat(filename, &st) && S_ISREG(st.st_mode)) { + puts(filename); + return 0; + } + return 1; + } + } + + // Search $PATH for matches. + list = find_in_path(getenv("PATH"), filename); + if (!list) return 1; + + // Print out matches + while (list) { + if (!access(list->str, X_OK)) { + puts(list->str); + // If we should stop at one match, do so + if (toys.optflags & OPT_a) { + llist_free(list, NULL); + break; + } + } + free(llist_pop(&list)); + } + + return 0; +} + +int which_main(void) +{ + char **argv; + int rc = 0; + + // get_optflags(OPTIONS); + argv = toys.argv+1; + + if (!*argv) rc++; + else { + int i; + for (i=0; argv[i]; i++) rc |= which_in_path(argv[i]); + } + // if (CFG_TOYS_FREE) free(argv); + + return rc; +} |