vi: move key reading routine out of vi into llbbb
[oweals/busybox.git] / debianutils / which.c
index a715a2664409cddd0bba1c8aa68af19e437c8fec..748e6dc2511ba413fe6ba75a0f0fda36b838a199 100644 (file)
  * Based on which from debianutils
  */
 
-#include "busybox.h"
+#include "libbb.h"
 
-int which_main(int argc, char **argv)
+int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int which_main(int argc UNUSED_PARAM, char **argv)
 {
+       USE_DESKTOP(int opt;)
        int status = EXIT_SUCCESS;
+       char *path;
        char *p;
 
-       if (argc <= 1 || argv[1][0] == '-') {
-               bb_show_usage();
+       opt_complementary = "-1"; /* at least one argument */
+       USE_DESKTOP(opt =) getopt32(argv, "a");
+       argv += optind;
+
+       /* This matches what is seen on e.g. ubuntu.
+        * "which" there is a shell script. */
+       path = getenv("PATH");
+       if (!path) {
+               path = (char*)bb_PATH_root_path;
+               putenv(path);
+               path += 5; /* skip "PATH=" */
        }
 
-       while (--argc > 0) {
-               argv++;
+       do {
+#if ENABLE_DESKTOP
+/* Much bloat just to support -a */
                if (strchr(*argv, '/')) {
                        if (execable_file(*argv)) {
                                puts(*argv);
                                continue;
                        }
+                       status = EXIT_FAILURE;
                } else {
-                       p = find_execable(*argv);
+                       char *path2 = xstrdup(path);
+                       char *tmp = path2;
+
+                       p = find_execable(*argv, &tmp);
+                       if (!p)
+                               status = EXIT_FAILURE;
+                       else {
+ print:
+                               puts(p);
+                               free(p);
+                               if (opt) {
+                                       /* -a: show matches in all PATH components */
+                                       if (tmp) {
+                                               p = find_execable(*argv, &tmp);
+                                               if (p)
+                                                       goto print;
+                                       }
+                               }
+                       }
+                       free(path2);
+               }
+#else
+/* Just ignoring -a */
+               if (strchr(*argv, '/')) {
+                       if (execable_file(*argv)) {
+                               puts(*argv);
+                               continue;
+                       }
+               } else {
+                       char *path2 = xstrdup(path);
+                       char *tmp = path2;
+                       p = find_execable(*argv, &tmp);
+                       free(path2);
                        if (p) {
                                puts(p);
                                free(p);
@@ -37,7 +83,8 @@ int which_main(int argc, char **argv)
                        }
                }
                status = EXIT_FAILURE;
-       }
+#endif
+       } while (*(++argv) != NULL);
 
        fflush_stdout_and_exit(status);
 }