httpd: require "HTTP/xyz" at the end of request line
[oweals/busybox.git] / debianutils / which.c
index ccfd163445469ed077b5b802b02d7cc830673d8d..98876521f80906730f8b2906f7689d1ba8c10774 100644 (file)
@@ -1,96 +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>
  *
- * Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * 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))
 
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
+//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"
 
+#include "libbb.h"
 
-extern 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)
 {
-       char *path_list;
-       int i, count=1, status = EXIT_SUCCESS;
+       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)];
 
-       if (argc <= 1 || **(argv + 1) == '-') {
-               bb_show_usage();
-       }
-       argc--;
+       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);
 
-       path_list = getenv("PATH");
-       if (path_list != NULL) {
-               for (i=strlen(path_list); i > 0; i--) {
-                       if (path_list[i]==':') {
-                               path_list[i]=0;
-                               count++;
-                       }
-               }
-       } else {
-               path_list = "/bin\0/sbin\0/usr/bin\0/usr/sbin\0/usr/local/bin";
-               count = 5;
-       }
+       getopt32(argv, "^" "a" "\0" "-1"/*at least one arg*/);
+       argv += optind;
 
-       while (argc-- > 0) { 
-               char *buf;
-               char *path_n;
-               char found = 0;
-               argv++;
+       do {
+               int missing = 1;
 
-               /*
-                * Check if we were given the full path, first.
-                * Otherwise see if the file exists in our $PATH.
-                */
-               path_n = path_list;
-               buf = *argv;
-               if (access(buf, X_OK) == 0) {
-                       found = 1;
+               /* If file contains a slash don't use PATH */
+               if (strchr(*argv, '/')) {
+                       if (file_is_executable(*argv)) {
+                               missing = 0;
+                               puts(*argv);
+                       }
                } else {
-                       for (i = 0; i < count; i++) {
-                               buf = concat_path_file(path_n, *argv);
-                               if (access(buf, X_OK) == 0) {
-                                       found = 1;
+                       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);
+                               if (!option_mask32) /* -a not set */
                                        break;
-                               }
-                               free(buf);
-                               path_n += (strlen(path_n) + 1);
                        }
                }
-               if (found) {
-                       puts(buf);
-               } else {
-                       status = EXIT_FAILURE;
-               }
-       }
+               status |= missing;
+       } while (*++argv);
+
        return status;
 }
-
-/*
-Local Variables:
-c-file-style: "linux"
-c-basic-offset: 4
-tab-width: 4
-End:
-*/