blob: 1558e5c6daa03760e5514f1a516e6da15151529a [file] [log] [blame]
Erik Andersen330fd2b2000-05-19 05:35:19 +00001/* vi: set sw=4 ts=4: */
2/*
3 * Which implementation for busybox
4 *
Eric Andersenc7bda1c2004-03-15 08:29:22 +00005 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
Denis Vlasenkof6f43df2006-10-11 22:16:56 +00006 * Copyright (C) 2006 Gabriel Somlo <somlo at cmu.edu>
Erik Andersen330fd2b2000-05-19 05:35:19 +00007 *
Bernhard Reutner-Fischer7fee0c42006-09-13 16:39:19 +00008 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
Erik Andersen330fd2b2000-05-19 05:35:19 +00009 *
Glenn L McGrathe84152e2004-03-01 08:32:49 +000010 * Based on which from debianutils
Erik Andersen330fd2b2000-05-19 05:35:19 +000011 */
12
Denis Vlasenkob6adbf12007-05-26 19:00:18 +000013#include "libbb.h"
Bernhard Reutner-Fischer66e3a222006-06-14 16:17:50 +000014
Denis Vlasenko9b49a5e2007-10-11 10:05:36 +000015int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denis Vlasenkoa60f84e2008-07-05 09:18:54 +000016int which_main(int argc UNUSED_PARAM, char **argv)
Erik Andersen330fd2b2000-05-19 05:35:19 +000017{
Denis Vlasenko5e34ff22009-04-21 11:09:40 +000018 IF_DESKTOP(int opt;)
Denis Vlasenkof6f43df2006-10-11 22:16:56 +000019 int status = EXIT_SUCCESS;
Denis Vlasenkof592aa32008-06-05 13:33:59 +000020 char *path;
Denis Vlasenkof6f43df2006-10-11 22:16:56 +000021 char *p;
Erik Andersen330fd2b2000-05-19 05:35:19 +000022
Denis Vlasenkof592aa32008-06-05 13:33:59 +000023 opt_complementary = "-1"; /* at least one argument */
Denis Vlasenko5e34ff22009-04-21 11:09:40 +000024 IF_DESKTOP(opt =) getopt32(argv, "a");
Denis Vlasenkof592aa32008-06-05 13:33:59 +000025 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=" */
Glenn L McGrathe84152e2004-03-01 08:32:49 +000034 }
Erik Andersen330fd2b2000-05-19 05:35:19 +000035
Denis Vlasenkof592aa32008-06-05 13:33:59 +000036 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;
Denis Vlasenko9d938732007-01-28 15:31:19 +000048
Denis Vlasenkof592aa32008-06-05 13:33:59 +000049 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 */
Denis Vlasenkof6f43df2006-10-11 22:16:56 +000069 if (strchr(*argv, '/')) {
70 if (execable_file(*argv)) {
71 puts(*argv);
72 continue;
Denis Vlasenko01c27fc2006-10-05 21:10:53 +000073 }
Eric Andersen514633b2003-10-22 10:38:22 +000074 } else {
Denis Vlasenkof592aa32008-06-05 13:33:59 +000075 char *path2 = xstrdup(path);
76 char *tmp = path2;
77 p = find_execable(*argv, &tmp);
78 free(path2);
Denis Vlasenkof6f43df2006-10-11 22:16:56 +000079 if (p) {
80 puts(p);
81 free(p);
82 continue;
Erik Andersen330fd2b2000-05-19 05:35:19 +000083 }
Erik Andersen330fd2b2000-05-19 05:35:19 +000084 }
Denis Vlasenko01c27fc2006-10-05 21:10:53 +000085 status = EXIT_FAILURE;
Denis Vlasenkof592aa32008-06-05 13:33:59 +000086#endif
87 } while (*(++argv) != NULL);
Denis Vlasenkof6f43df2006-10-11 22:16:56 +000088
Denis Vlasenkof0ed3762006-10-26 23:21:47 +000089 fflush_stdout_and_exit(status);
Erik Andersen330fd2b2000-05-19 05:35:19 +000090}