which: rewrite
[oweals/busybox.git] / debianutils / which.c
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
9 //usage:#define which_trivial_usage
10 //usage:       "[COMMAND]..."
11 //usage:#define which_full_usage "\n\n"
12 //usage:       "Locate a COMMAND"
13 //usage:
14 //usage:#define which_example_usage
15 //usage:       "$ which login\n"
16 //usage:       "/bin/login\n"
17
18 #include "libbb.h"
19
20 int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
21 int which_main(int argc UNUSED_PARAM, char **argv)
22 {
23         const char *env_path;
24         int status = 0;
25
26         env_path = getenv("PATH");
27         if (!env_path)
28                 env_path = bb_default_root_path;
29
30         opt_complementary = "-1"; /* at least one argument */
31         getopt32(argv, "a");
32         argv += optind;
33
34         do {
35                 int missing = 1;
36
37                 /* If file contains a slash don't use PATH */
38                 if (strchr(*argv, '/')) {
39                         if (file_is_executable(*argv)) {
40                                 missing = 0;
41                                 puts(*argv);
42                         }
43                 } else {
44                         char *path;
45                         char *tmp;
46                         char *p;
47
48                         path = tmp = xstrdup(env_path);
49                         while ((p = find_executable(*argv, &tmp)) != NULL) {
50                                 missing = 0;
51                                 puts(p);
52                                 free(p);
53                                 if (!option_mask32) /* -a not set */
54                                         break;
55                         }
56                         free(path);
57                 }
58                 status |= missing;
59         } while (*++argv);
60
61         return status;
62 }