blob: 15fd598b782f7076ab59dbf27730518affaf3d0c [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 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +02008 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
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
Pere Orga6a3e01d2011-04-01 22:56:30 +020013//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
Denis Vlasenkob6adbf12007-05-26 19:00:18 +000022#include "libbb.h"
Bernhard Reutner-Fischer66e3a222006-06-14 16:17:50 +000023
Denis Vlasenko9b49a5e2007-10-11 10:05:36 +000024int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denis Vlasenkoa60f84e2008-07-05 09:18:54 +000025int which_main(int argc UNUSED_PARAM, char **argv)
Erik Andersen330fd2b2000-05-19 05:35:19 +000026{
Denis Vlasenko5e34ff22009-04-21 11:09:40 +000027 IF_DESKTOP(int opt;)
Denis Vlasenkof6f43df2006-10-11 22:16:56 +000028 int status = EXIT_SUCCESS;
Denis Vlasenkof592aa32008-06-05 13:33:59 +000029 char *path;
Denis Vlasenkof6f43df2006-10-11 22:16:56 +000030 char *p;
Erik Andersen330fd2b2000-05-19 05:35:19 +000031
Denis Vlasenkof592aa32008-06-05 13:33:59 +000032 opt_complementary = "-1"; /* at least one argument */
Denis Vlasenko5e34ff22009-04-21 11:09:40 +000033 IF_DESKTOP(opt =) getopt32(argv, "a");
Denis Vlasenkof592aa32008-06-05 13:33:59 +000034 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=" */
Glenn L McGrathe84152e2004-03-01 08:32:49 +000043 }
Erik Andersen330fd2b2000-05-19 05:35:19 +000044
Denis Vlasenkof592aa32008-06-05 13:33:59 +000045 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;
Denis Vlasenko9d938732007-01-28 15:31:19 +000057
Denis Vlasenkof592aa32008-06-05 13:33:59 +000058 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 */
Denis Vlasenkof6f43df2006-10-11 22:16:56 +000078 if (strchr(*argv, '/')) {
79 if (execable_file(*argv)) {
80 puts(*argv);
81 continue;
Denis Vlasenko01c27fc2006-10-05 21:10:53 +000082 }
Eric Andersen514633b2003-10-22 10:38:22 +000083 } else {
Denis Vlasenkof592aa32008-06-05 13:33:59 +000084 char *path2 = xstrdup(path);
85 char *tmp = path2;
86 p = find_execable(*argv, &tmp);
87 free(path2);
Denis Vlasenkof6f43df2006-10-11 22:16:56 +000088 if (p) {
89 puts(p);
90 free(p);
91 continue;
Erik Andersen330fd2b2000-05-19 05:35:19 +000092 }
Erik Andersen330fd2b2000-05-19 05:35:19 +000093 }
Denis Vlasenko01c27fc2006-10-05 21:10:53 +000094 status = EXIT_FAILURE;
Denis Vlasenkof592aa32008-06-05 13:33:59 +000095#endif
96 } while (*(++argv) != NULL);
Denis Vlasenkof6f43df2006-10-11 22:16:56 +000097
Denis Vlasenkof0ed3762006-10-26 23:21:47 +000098 fflush_stdout_and_exit(status);
Erik Andersen330fd2b2000-05-19 05:35:19 +000099}