busybox/debianutils/which.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * Which implementation for busybox
   4 *
   5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
   6 * Copyright (C) 2006 Gabriel Somlo <somlo at cmu.edu>
   7 *
   8 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   9 *
  10 * Based on which from debianutils
  11 */
  12
  13//usage:#define which_trivial_usage
  14//usage:       "[COMMAND]..."
  15//usage:#define which_full_usage "\n\n"
  16//usage:       "Locate a COMMAND"
  17//usage:
  18//usage:#define which_example_usage
  19//usage:       "$ which login\n"
  20//usage:       "/bin/login\n"
  21
  22#include "libbb.h"
  23
  24int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  25int which_main(int argc UNUSED_PARAM, char **argv)
  26{
  27        IF_DESKTOP(int opt;)
  28        int status = EXIT_SUCCESS;
  29        char *path;
  30        char *p;
  31
  32        opt_complementary = "-1"; /* at least one argument */
  33        IF_DESKTOP(opt =) getopt32(argv, "a");
  34        argv += optind;
  35
  36        /* This matches what is seen on e.g. ubuntu.
  37         * "which" there is a shell script. */
  38        path = getenv("PATH");
  39        if (!path) {
  40                path = (char*)bb_PATH_root_path;
  41                putenv(path);
  42                path += 5; /* skip "PATH=" */
  43        }
  44
  45        do {
  46#if ENABLE_DESKTOP
  47/* Much bloat just to support -a */
  48                if (strchr(*argv, '/')) {
  49                        if (execable_file(*argv)) {
  50                                puts(*argv);
  51                                continue;
  52                        }
  53                        status = EXIT_FAILURE;
  54                } else {
  55                        char *path2 = xstrdup(path);
  56                        char *tmp = path2;
  57
  58                        p = find_execable(*argv, &tmp);
  59                        if (!p)
  60                                status = EXIT_FAILURE;
  61                        else {
  62 print:
  63                                puts(p);
  64                                free(p);
  65                                if (opt) {
  66                                        /* -a: show matches in all PATH components */
  67                                        if (tmp) {
  68                                                p = find_execable(*argv, &tmp);
  69                                                if (p)
  70                                                        goto print;
  71                                        }
  72                                }
  73                        }
  74                        free(path2);
  75                }
  76#else
  77/* Just ignoring -a */
  78                if (strchr(*argv, '/')) {
  79                        if (execable_file(*argv)) {
  80                                puts(*argv);
  81                                continue;
  82                        }
  83                } else {
  84                        char *path2 = xstrdup(path);
  85                        char *tmp = path2;
  86                        p = find_execable(*argv, &tmp);
  87                        free(path2);
  88                        if (p) {
  89                                puts(p);
  90                                free(p);
  91                                continue;
  92                        }
  93                }
  94                status = EXIT_FAILURE;
  95#endif
  96        } while (*(++argv) != NULL);
  97
  98        fflush_stdout_and_exit(status);
  99}
 100