Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 1 | /* vi: set sw=4 ts=4: */ |
| 2 | /* |
| 3 | * Which implementation for busybox |
| 4 | * |
Eric Andersen | c7bda1c | 2004-03-15 08:29:22 +0000 | [diff] [blame] | 5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 6 | * |
Bernhard Reutner-Fischer | 7fee0c4 | 2006-09-13 16:39:19 +0000 | [diff] [blame] | 7 | * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 8 | * |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 9 | * Based on which from debianutils |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 10 | */ |
| 11 | |
Bernhard Reutner-Fischer | e15d757 | 2006-06-02 20:56:16 +0000 | [diff] [blame] | 12 | #include "busybox.h" |
Eric Andersen | ed3ef50 | 2001-01-27 08:24:39 +0000 | [diff] [blame] | 13 | #include <string.h> |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 14 | #include <stdio.h> |
Eric Andersen | ed3ef50 | 2001-01-27 08:24:39 +0000 | [diff] [blame] | 15 | #include <stdlib.h> |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 16 | #include <unistd.h> |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 17 | #include <sys/stat.h> |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 18 | |
Bernhard Reutner-Fischer | 66e3a22 | 2006-06-14 16:17:50 +0000 | [diff] [blame] | 19 | |
Rob Landley | f86a5ba | 2006-07-19 21:45:30 +0000 | [diff] [blame] | 20 | static int is_executable_file(char *a, struct stat *b) |
Bernhard Reutner-Fischer | 66e3a22 | 2006-06-14 16:17:50 +0000 | [diff] [blame] | 21 | { |
| 22 | return (!access(a,X_OK) && !stat(a, b) && S_ISREG(b->st_mode)); |
| 23 | } |
| 24 | |
Rob Landley | dfba741 | 2006-03-06 20:47:33 +0000 | [diff] [blame] | 25 | int which_main(int argc, char **argv) |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 26 | { |
Bernhard Reutner-Fischer | 66e3a22 | 2006-06-14 16:17:50 +0000 | [diff] [blame] | 27 | int status; |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 28 | size_t i, count; |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 29 | char *path_list; |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 30 | |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 31 | if (argc <= 1 || **(argv + 1) == '-') { |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 32 | bb_show_usage(); |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 33 | } |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 34 | argc--; |
| 35 | |
| 36 | path_list = getenv("PATH"); |
Matt Kraai | a3181dd | 2002-01-14 18:30:10 +0000 | [diff] [blame] | 37 | if (path_list != NULL) { |
Rob Landley | a389651 | 2006-05-07 20:20:34 +0000 | [diff] [blame] | 38 | size_t path_len = strlen(path_list); |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 39 | char *new_list = NULL; |
| 40 | count = 1; |
| 41 | |
| 42 | for (i = 0; i <= path_len; i++) { |
| 43 | char *this_i = &path_list[i]; |
| 44 | if (*this_i == ':') { |
| 45 | /* ^::[^:] == \.: */ |
| 46 | if (!i && (*(this_i + 1) == ':')) { |
| 47 | *this_i = '.'; |
| 48 | continue; |
| 49 | } |
| 50 | *this_i = 0; |
Matt Kraai | a3181dd | 2002-01-14 18:30:10 +0000 | [diff] [blame] | 51 | count++; |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 52 | /* ^:[^:] == \.0 and [^:]::[^:] == 0\.0 and [^:]:$ == 0\.0 */ |
| 53 | if (!i || (*(this_i + 1) == ':') || (i == path_len-1)) { |
| 54 | new_list = xrealloc(new_list, path_len += 1); |
| 55 | if (i) { |
| 56 | memmove(&new_list[i+2], &path_list[i+1], path_len-i); |
| 57 | new_list[i+1] = '.'; |
| 58 | memmove(new_list, path_list, i); |
| 59 | } else { |
| 60 | memmove(&new_list[i+1], &path_list[i], path_len-i); |
| 61 | new_list[i] = '.'; |
| 62 | } |
| 63 | path_list = new_list; |
| 64 | } |
Matt Kraai | a3181dd | 2002-01-14 18:30:10 +0000 | [diff] [blame] | 65 | } |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 66 | } |
Matt Kraai | a3181dd | 2002-01-14 18:30:10 +0000 | [diff] [blame] | 67 | } else { |
| 68 | path_list = "/bin\0/sbin\0/usr/bin\0/usr/sbin\0/usr/local/bin"; |
| 69 | count = 5; |
| 70 | } |
Pavel Roskin | c389d91 | 2000-06-05 23:41:27 +0000 | [diff] [blame] | 71 | |
Bernhard Reutner-Fischer | 66e3a22 | 2006-06-14 16:17:50 +0000 | [diff] [blame] | 72 | status = EXIT_SUCCESS; |
Eric Andersen | c7bda1c | 2004-03-15 08:29:22 +0000 | [diff] [blame] | 73 | while (argc-- > 0) { |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 74 | struct stat stat_b; |
Eric Andersen | e78fe24 | 2003-10-22 11:36:55 +0000 | [diff] [blame] | 75 | char *buf; |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 76 | char *path_n; |
Bernhard Reutner-Fischer | 66e3a22 | 2006-06-14 16:17:50 +0000 | [diff] [blame] | 77 | int found = 0; |
Eric Andersen | 514633b | 2003-10-22 10:38:22 +0000 | [diff] [blame] | 78 | |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 79 | argv++; |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 80 | path_n = path_list; |
Eric Andersen | 514633b | 2003-10-22 10:38:22 +0000 | [diff] [blame] | 81 | buf = *argv; |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 82 | |
| 83 | /* if filename is either absolute or contains slashes, |
| 84 | * stat it */ |
Bernhard Reutner-Fischer | 66e3a22 | 2006-06-14 16:17:50 +0000 | [diff] [blame] | 85 | if (strchr(buf, '/') != NULL && is_executable_file(buf, &stat_b)) { |
| 86 | found++; |
Eric Andersen | 514633b | 2003-10-22 10:38:22 +0000 | [diff] [blame] | 87 | } else { |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 88 | /* Couldn't access file and file doesn't contain slashes */ |
Eric Andersen | 514633b | 2003-10-22 10:38:22 +0000 | [diff] [blame] | 89 | for (i = 0; i < count; i++) { |
| 90 | buf = concat_path_file(path_n, *argv); |
Bernhard Reutner-Fischer | 66e3a22 | 2006-06-14 16:17:50 +0000 | [diff] [blame] | 91 | if (is_executable_file(buf, &stat_b)) { |
| 92 | found++; |
Eric Andersen | 514633b | 2003-10-22 10:38:22 +0000 | [diff] [blame] | 93 | break; |
| 94 | } |
| 95 | free(buf); |
Rob Landley | a389651 | 2006-05-07 20:20:34 +0000 | [diff] [blame] | 96 | path_n += (strlen(path_n) + 1); |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 97 | } |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 98 | } |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 99 | if (found) { |
| 100 | puts(buf); |
| 101 | } else { |
Matt Kraai | 768a234 | 2000-11-18 01:16:43 +0000 | [diff] [blame] | 102 | status = EXIT_FAILURE; |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 103 | } |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 104 | } |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 105 | bb_fflush_stdout_and_exit(status); |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 106 | } |