diff options
author | Pavel Roskin <proski@gnu.org> | 2000-06-05 23:41:27 +0000 |
---|---|---|
committer | Pavel Roskin <proski@gnu.org> | 2000-06-05 23:41:27 +0000 |
commit | c389d9118152e45303173c221a33a8083e769884 (patch) | |
tree | db75949ed22190763981c4b19752e6450723fd8f | |
parent | 82c0ac7e4f2def7ebc7110fa817ce534094af2a2 (diff) |
"which" rewritten to use stat(). Fixes to improve its compatability
with traditional implementations
-rw-r--r-- | Changelog | 2 | ||||
-rw-r--r-- | findutils/which.c | 63 | ||||
-rw-r--r-- | which.c | 63 |
3 files changed, 92 insertions, 36 deletions
@@ -50,6 +50,8 @@ * Fixed all fatalError() calls lacking a "\n", thanks to Pavel Roskin. * Fixed a segfault in yes when no args were given -- Pavel Roskin. * Simplified freeramdisk and added argument checking -- Pavel Roskin. + * "which" rewritten to use stat(). Fixes to improve its compatability + with traditional implementations -- Pavel Roskin. * More doc updates diff --git a/findutils/which.c b/findutils/which.c index 46c2204a5..7a11bf787 100644 --- a/findutils/which.c +++ b/findutils/which.c @@ -23,15 +23,18 @@ #include "internal.h" #include <stdio.h> -#include <dirent.h> +#include <sys/stat.h> +#include <sys/param.h> extern int which_main(int argc, char **argv) { - char *path_list, *test, *tmp; - struct dirent *next; + char *path_list, *test, *tmp, *path_parsed; + char buf[PATH_MAX]; + struct stat filestat; + int count = 0; - if (**(argv + 1) == '-') { + if (argc <= 1 || **(argv + 1) == '-') { usage("which [COMMAND ...]\n" #ifndef BB_FEATURE_TRIVIAL_HELP "\nLocates a COMMAND.\n" @@ -44,21 +47,45 @@ extern int which_main(int argc, char **argv) if (!path_list) path_list = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin"; - while(argc-- > 0 && *(argv++) != '\0' && strlen(*argv)) { - for( test=path_list; (tmp=strchr(test, ':')) && (tmp+1)!=NULL; test=++tmp) { - DIR *dir; - *tmp='\0'; - //printf("Checking directory '%s'\n", test); - dir = opendir(test); - if (!dir) - continue; - while ((next = readdir(dir)) != NULL) { - //printf("Checking file '%s'\n", next->d_name); - if ((strcmp(next->d_name, *argv) == 0)) { - printf("%s/%s\n", test, next->d_name); - exit(TRUE); - } + path_parsed = malloc (strlen(path_list) + 1); + strcpy (path_parsed, path_list); + + /* Replace colons with zeros in path_parsed and count them */ + count = 1; + test = path_parsed; + while (1) { + tmp = strchr(test, ':'); + if (tmp == NULL) + break; + *tmp = 0; + test = tmp + 1; + count++; + } + + + while(argc-- > 0) { + int i; + int found = FALSE; + test = path_parsed; + argv++; + for (i = 0; i < count; i++) { + strcpy (buf, test); + strcat (buf, "/"); + strcat (buf, *argv); + if (stat (buf, &filestat) == 0 + && filestat.st_mode & S_IXUSR) + { + found = TRUE; + break; } + test += (strlen(test) + 1); + } + if (found == TRUE) + printf ("%s\n", buf); + else + { + printf ("which: no %s in (%s)\n", *argv, path_list); + exit (FALSE); } } exit(TRUE); @@ -23,15 +23,18 @@ #include "internal.h" #include <stdio.h> -#include <dirent.h> +#include <sys/stat.h> +#include <sys/param.h> extern int which_main(int argc, char **argv) { - char *path_list, *test, *tmp; - struct dirent *next; + char *path_list, *test, *tmp, *path_parsed; + char buf[PATH_MAX]; + struct stat filestat; + int count = 0; - if (**(argv + 1) == '-') { + if (argc <= 1 || **(argv + 1) == '-') { usage("which [COMMAND ...]\n" #ifndef BB_FEATURE_TRIVIAL_HELP "\nLocates a COMMAND.\n" @@ -44,21 +47,45 @@ extern int which_main(int argc, char **argv) if (!path_list) path_list = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin"; - while(argc-- > 0 && *(argv++) != '\0' && strlen(*argv)) { - for( test=path_list; (tmp=strchr(test, ':')) && (tmp+1)!=NULL; test=++tmp) { - DIR *dir; - *tmp='\0'; - //printf("Checking directory '%s'\n", test); - dir = opendir(test); - if (!dir) - continue; - while ((next = readdir(dir)) != NULL) { - //printf("Checking file '%s'\n", next->d_name); - if ((strcmp(next->d_name, *argv) == 0)) { - printf("%s/%s\n", test, next->d_name); - exit(TRUE); - } + path_parsed = malloc (strlen(path_list) + 1); + strcpy (path_parsed, path_list); + + /* Replace colons with zeros in path_parsed and count them */ + count = 1; + test = path_parsed; + while (1) { + tmp = strchr(test, ':'); + if (tmp == NULL) + break; + *tmp = 0; + test = tmp + 1; + count++; + } + + + while(argc-- > 0) { + int i; + int found = FALSE; + test = path_parsed; + argv++; + for (i = 0; i < count; i++) { + strcpy (buf, test); + strcat (buf, "/"); + strcat (buf, *argv); + if (stat (buf, &filestat) == 0 + && filestat.st_mode & S_IXUSR) + { + found = TRUE; + break; } + test += (strlen(test) + 1); + } + if (found == TRUE) + printf ("%s\n", buf); + else + { + printf ("which: no %s in (%s)\n", *argv, path_list); + exit (FALSE); } } exit(TRUE); |