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#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 IF_DESKTOP(int opt;) 19 int status = EXIT_SUCCESS; 20 char *path; 21 char *p; 22 23 opt_complementary = "-1"; /* at least one argument */ 24 IF_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