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 the GPL v2 or later, see the file LICENSE in this tarball.
   9 *
  10 * Based on which from debianutils
  11 */
  12
  13#include "libbb.h"
  14
  15int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  16int which_main(int argc UNUSED_PARAM, char **argv)
  17{
  18        USE_DESKTOP(int opt;)
  19        int status = EXIT_SUCCESS;
  20        char *path;
  21        char *p;
  22
  23        opt_complementary = "-1"; /* at least one argument */
  24        USE_DESKTOP(opt =) getopt32(argv, "a");
  25        argv += optind;
  26
  27        /* This matches what is seen on e.g. ubuntu.
  28         * "which" there is a shell script. */
  29        path = getenv("PATH");
  30        if (!path) {
  31                path = (char*)bb_PATH_root_path;
  32                putenv(path);
  33                path += 5; /* skip "PATH=" */
  34        }
  35
  36        do {
  37#if ENABLE_DESKTOP
  38/* Much bloat just to support -a */
  39                if (strchr(*argv, '/')) {
  40                        if (execable_file(*argv)) {
  41                                puts(*argv);
  42                                continue;
  43                        }
  44                        status = EXIT_FAILURE;
  45                } else {
  46                        char *path2 = xstrdup(path);
  47                        char *tmp = path2;
  48
  49                        p = find_execable(*argv, &tmp);
  50                        if (!p)
  51                                status = EXIT_FAILURE;
  52                        else {
  53 print:
  54                                puts(p);
  55                                free(p);
  56                                if (opt) {
  57                                        /* -a: show matches in all PATH components */
  58                                        if (tmp) {
  59                                                p = find_execable(*argv, &tmp);
  60                                                if (p)
  61                                                        goto print;
  62                                        }
  63                                }
  64                        }
  65                        free(path2);
  66                }
  67#else
  68/* Just ignoring -a */
  69                if (strchr(*argv, '/')) {
  70                        if (execable_file(*argv)) {
  71                                puts(*argv);
  72                                continue;
  73                        }
  74                } else {
  75                        char *path2 = xstrdup(path);
  76                        char *tmp = path2;
  77                        p = find_execable(*argv, &tmp);
  78                        free(path2);
  79                        if (p) {
  80                                puts(p);
  81                                free(p);
  82                                continue;
  83                        }
  84                }
  85                status = EXIT_FAILURE;
  86#endif
  87        } while (*(++argv) != NULL);
  88
  89        fflush_stdout_and_exit(status);
  90}
  91