run-parts: stop providing incompatible short options
[platform/upstream/busybox.git] / debianutils / which.c
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
24 int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
25 int 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 }