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:       "[-a] COMMAND..."
  21//usage:#define which_full_usage "\n\n"
  22//usage:       "Locate COMMAND\n"
  23//usage:     "\n        -a      Show all matches"
  24//usage:
  25//usage:#define which_example_usage
  26//usage:       "$ which login\n"
  27//usage:       "/bin/login\n"
  28
  29#include "libbb.h"
  30
  31int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  32int which_main(int argc UNUSED_PARAM, char **argv)
  33{
  34        char *env_path;
  35        int status = 0;
  36        /* This sizeof(): bb_default_root_path is shorter than BB_PATH_ROOT_PATH */
  37        char buf[sizeof(BB_PATH_ROOT_PATH)];
  38
  39        env_path = getenv("PATH");
  40        if (!env_path)
  41                /* env_path must be writable, and must not alloc, so... */
  42                env_path = strcpy(buf, bb_default_root_path);
  43
  44        getopt32(argv, "^" "a" "\0" "-1"/*at least one arg*/);
  45        argv += optind;
  46
  47        do {
  48                int missing = 1;
  49
  50                /* If file contains a slash don't use PATH */
  51                if (strchr(*argv, '/')) {
  52                        if (file_is_executable(*argv)) {
  53                                missing = 0;
  54                                puts(*argv);
  55                        }
  56                } else {
  57                        char *path;
  58                        char *p;
  59
  60                        path = env_path;
  61                        /* NOFORK NB: xmalloc inside find_executable(), must have no allocs above! */
  62                        while ((p = find_executable(*argv, &path)) != NULL) {
  63                                missing = 0;
  64                                puts(p);
  65                                free(p);
  66                                if (!option_mask32) /* -a not set */
  67                                        break;
  68                        }
  69                }
  70                status |= missing;
  71        } while (*++argv);
  72
  73        return status;
  74}
  75