Re-organized some sections and added a whole new section on avoiding the
[oweals/busybox.git] / which.c
diff --git a/which.c b/which.c
index 46c2204a56d7356be4553edff3d45cc9f6233707..a92777eb7ec34b7bb8fe3f0637106dbb71a2fc02 100644 (file)
--- a/which.c
+++ b/which.c
  *
  */
 
-#include "internal.h"
+#include "busybox.h"
 #include <stdio.h>
-#include <dirent.h>
-
 
 extern int which_main(int argc, char **argv)
 {
-       char *path_list, *test, *tmp;
-       struct dirent *next;
+       char *path_list, *path_n;
+       struct stat filestat;
+       int i, count=1, found, status = EXIT_SUCCESS;
 
-       if (**(argv + 1) == '-') {
-               usage("which [COMMAND ...]\n"
-#ifndef BB_FEATURE_TRIVIAL_HELP
-                               "\nLocates a COMMAND.\n"
-#endif
-                        );
-       }
+       if (argc <= 1 || **(argv + 1) == '-')
+               usage(which_usage);
        argc--;
 
        path_list = getenv("PATH");
        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);
-                               }
+       /* Replace colons with zeros in path_parsed and count them */
+       for(i=strlen(path_list); i > 0; i--) 
+               if (path_list[i]==':') {
+                       path_list[i]=0;
+                       count++;
+               }
+
+       while(argc-- > 0) { 
+               path_n = path_list;
+               argv++;
+               found = 0;
+               for (i = 0; i < count; i++) {
+                       char buf[strlen(path_n)+1+strlen(*argv)];
+                       strcpy (buf, path_n);
+                       strcat (buf, "/");
+                       strcat (buf, *argv);
+                       if (stat (buf, &filestat) == 0
+                           && filestat.st_mode & S_IXUSR)
+                       {
+                               printf ("%s\n", buf);
+                               found = 1;
+                               break;
                        }
+                       path_n += (strlen(path_n) + 1);
                }
+               if (!found)
+                       status = EXIT_FAILURE;
        }
-       exit(TRUE);
+       return status;
 }
 
 /*