httpd: require "HTTP/xyz" at the end of request line
[oweals/busybox.git] / debianutils / which.c
index 02992d0f6235692f3121dfb9899bea6477e0bf50..98876521f80906730f8b2906f7689d1ba8c10774 100644 (file)
@@ -1,48 +1,73 @@
 /* vi: set sw=4 ts=4: */
 /*
- * Which implementation for busybox
- *
  * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
  * Copyright (C) 2006 Gabriel Somlo <somlo at cmu.edu>
  *
- * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
- *
- * Based on which from debianutils
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  */
+//config:config WHICH
+//config:      bool "which (3.8 kb)"
+//config:      default y
+//config:      help
+//config:      which is used to find programs in your PATH and
+//config:      print out their pathnames.
+
+//applet:IF_WHICH(APPLET_NOFORK(which, which, BB_DIR_USR_BIN, BB_SUID_DROP, which))
+
+//kbuild:lib-$(CONFIG_WHICH) += which.o
 
-#include "busybox.h"
+//usage:#define which_trivial_usage
+//usage:       "[COMMAND]..."
+//usage:#define which_full_usage "\n\n"
+//usage:       "Locate a COMMAND"
+//usage:
+//usage:#define which_example_usage
+//usage:       "$ which login\n"
+//usage:       "/bin/login\n"
 
-int which_main(int argc, char **argv);
-int which_main(int argc, char **argv)
+#include "libbb.h"
+
+int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int which_main(int argc UNUSED_PARAM, char **argv)
 {
-       int status = EXIT_SUCCESS;
-       char *p;
+       char *env_path;
+       int status = 0;
+       /* This sizeof(): bb_default_root_path is shorter than BB_PATH_ROOT_PATH */
+       char buf[sizeof(BB_PATH_ROOT_PATH)];
+
+       env_path = getenv("PATH");
+       if (!env_path)
+               /* env_path must be writable, and must not alloc, so... */
+               env_path = strcpy(buf, bb_default_root_path);
 
-       if (argc <= 1 || argv[1][0] == '-') {
-               bb_show_usage();
-       }
+       getopt32(argv, "^" "a" "\0" "-1"/*at least one arg*/);
+       argv += optind;
 
-       if (!getenv("PATH")) {
-               setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin", 1);
-       }
+       do {
+               int missing = 1;
 
-       while (--argc > 0) {
-               argv++;
+               /* If file contains a slash don't use PATH */
                if (strchr(*argv, '/')) {
-                       if (execable_file(*argv)) {
+                       if (file_is_executable(*argv)) {
+                               missing = 0;
                                puts(*argv);
-                               continue;
                        }
                } else {
-                       p = find_execable(*argv);
-                       if (p) {
+                       char *path;
+                       char *p;
+
+                       path = env_path;
+                       /* NOFORK NB: xmalloc inside find_executable(), must have no allocs above! */
+                       while ((p = find_executable(*argv, &path)) != NULL) {
+                               missing = 0;
                                puts(p);
                                free(p);
-                               continue;
+                               if (!option_mask32) /* -a not set */
+                                       break;
                        }
                }
-               status = EXIT_FAILURE;
-       }
+               status |= missing;
+       } while (*++argv);
 
-       fflush_stdout_and_exit(status);
+       return status;
 }