busybox/debianutils/which.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
   4 * Copyright (C) 2006 Gabriel Somlo <somlo at cmu.edu>
   5 *
   6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   7 */
   8//config:config WHICH
   9//config:       bool "which (3.8 kb)"
  10//config:       default y
  11//config:       help
  12//config:       which is used to find programs in your PATH and
  13//config:       print out their pathnames.
  14
  15//applet:IF_WHICH(APPLET_NOFORK(which, which, BB_DIR_USR_BIN, BB_SUID_DROP, which))
  16
  17//kbuild:lib-$(CONFIG_WHICH) += which.o
  18
  19//usage:#define which_trivial_usage
  20//usage:       "COMMAND..."
  21//usage:#define which_full_usage "\n\n"
  22//usage:       "Locate COMMAND"
  23//usage:
  24//usage:#define which_example_usage
  25//usage:       "$ which login\n"
  26//usage:       "/bin/login\n"
  27
  28#include "libbb.h"
  29
  30int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  31int which_main(int argc UNUSED_PARAM, char **argv)
  32{
  33        char *env_path;
  34        int status = 0;
  35        /* This sizeof(): bb_default_root_path is shorter than BB_PATH_ROOT_PATH */
  36        char buf[sizeof(BB_PATH_ROOT_PATH)];
  37
  38        env_path = getenv("PATH");
  39        if (!env_path)
  40                /* env_path must be writable, and must not alloc, so... */
  41                env_path = strcpy(buf, bb_default_root_path);
  42
  43        getopt32(argv, "^" "a" "\0" "-1"/*at least one arg*/);
  44        argv += optind;
  45
  46        do {
  47                int missing = 1;
  48
  49                /* If file contains a slash don't use PATH */
  50                if (strchr(*argv, '/')) {
  51                        if (file_is_executable(*argv)) {
  52                                missing = 0;
  53                                puts(*argv);
  54                        }
  55                } else {
  56                        char *path;
  57                        char *p;
  58
  59                        path = env_path;
  60                        /* NOFORK NB: xmalloc inside find_executable(), must have no allocs above! */
  61                        while ((p = find_executable(*argv, &path)) != NULL) {
  62                                missing = 0;
  63                                puts(p);
  64                                free(p);
  65                                if (!option_mask32) /* -a not set */
  66                                        break;
  67                        }
  68                }
  69                status |= missing;
  70        } while (*++argv);
  71
  72        return status;
  73}
  74