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 | * |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 7 | * Licensed under the GPL v2, 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 | |
Eric Andersen | ed3ef50 | 2001-01-27 08:24:39 +0000 | [diff] [blame] | 12 | #include <string.h> |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 13 | #include <stdio.h> |
Eric Andersen | ed3ef50 | 2001-01-27 08:24:39 +0000 | [diff] [blame] | 14 | #include <stdlib.h> |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 15 | #include <unistd.h> |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 16 | #include <sys/stat.h> |
Eric Andersen | cbe31da | 2001-02-20 06:14:08 +0000 | [diff] [blame] | 17 | #include "busybox.h" |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 18 | |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 19 | extern int which_main(int argc, char **argv) |
| 20 | { |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 21 | int status = EXIT_SUCCESS; |
| 22 | size_t i, count; |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 23 | char *path_list; |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 24 | |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 25 | if (argc <= 1 || **(argv + 1) == '-') { |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 26 | bb_show_usage(); |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 27 | } |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 28 | argc--; |
| 29 | |
| 30 | path_list = getenv("PATH"); |
Matt Kraai | a3181dd | 2002-01-14 18:30:10 +0000 | [diff] [blame] | 31 | if (path_list != NULL) { |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 32 | size_t path_len = bb_strlen(path_list); |
| 33 | char *new_list = NULL; |
| 34 | count = 1; |
| 35 | |
| 36 | for (i = 0; i <= path_len; i++) { |
| 37 | char *this_i = &path_list[i]; |
| 38 | if (*this_i == ':') { |
| 39 | /* ^::[^:] == \.: */ |
| 40 | if (!i && (*(this_i + 1) == ':')) { |
| 41 | *this_i = '.'; |
| 42 | continue; |
| 43 | } |
| 44 | *this_i = 0; |
Matt Kraai | a3181dd | 2002-01-14 18:30:10 +0000 | [diff] [blame] | 45 | count++; |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 46 | /* ^:[^:] == \.0 and [^:]::[^:] == 0\.0 and [^:]:$ == 0\.0 */ |
| 47 | if (!i || (*(this_i + 1) == ':') || (i == path_len-1)) { |
| 48 | new_list = xrealloc(new_list, path_len += 1); |
| 49 | if (i) { |
| 50 | memmove(&new_list[i+2], &path_list[i+1], path_len-i); |
| 51 | new_list[i+1] = '.'; |
| 52 | memmove(new_list, path_list, i); |
| 53 | } else { |
| 54 | memmove(&new_list[i+1], &path_list[i], path_len-i); |
| 55 | new_list[i] = '.'; |
| 56 | } |
| 57 | path_list = new_list; |
| 58 | } |
Matt Kraai | a3181dd | 2002-01-14 18:30:10 +0000 | [diff] [blame] | 59 | } |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 60 | } |
Matt Kraai | a3181dd | 2002-01-14 18:30:10 +0000 | [diff] [blame] | 61 | } else { |
| 62 | path_list = "/bin\0/sbin\0/usr/bin\0/usr/sbin\0/usr/local/bin"; |
| 63 | count = 5; |
| 64 | } |
Pavel Roskin | c389d91 | 2000-06-05 23:41:27 +0000 | [diff] [blame] | 65 | |
Eric Andersen | c7bda1c | 2004-03-15 08:29:22 +0000 | [diff] [blame] | 66 | while (argc-- > 0) { |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 67 | struct stat stat_b; |
Eric Andersen | e78fe24 | 2003-10-22 11:36:55 +0000 | [diff] [blame] | 68 | char *buf; |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 69 | char *path_n; |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 70 | char found = 0; |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 71 | #define is_executable_file(a, b) (!access(a,X_OK) && !stat(a, &b) && \ |
| 72 | S_ISREG(b.st_mode)) |
Eric Andersen | 514633b | 2003-10-22 10:38:22 +0000 | [diff] [blame] | 73 | |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 74 | argv++; |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 75 | path_n = path_list; |
Eric Andersen | 514633b | 2003-10-22 10:38:22 +0000 | [diff] [blame] | 76 | buf = *argv; |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 77 | |
| 78 | /* if filename is either absolute or contains slashes, |
| 79 | * stat it */ |
| 80 | if (strchr(buf, '/') != NULL && is_executable_file(buf, stat_b)) { |
Eric Andersen | 514633b | 2003-10-22 10:38:22 +0000 | [diff] [blame] | 81 | found = 1; |
| 82 | } else { |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 83 | /* Couldn't access file and file doesn't contain slashes */ |
Eric Andersen | 514633b | 2003-10-22 10:38:22 +0000 | [diff] [blame] | 84 | for (i = 0; i < count; i++) { |
| 85 | buf = concat_path_file(path_n, *argv); |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 86 | if (is_executable_file(buf, stat_b)) { |
Eric Andersen | 514633b | 2003-10-22 10:38:22 +0000 | [diff] [blame] | 87 | found = 1; |
| 88 | break; |
| 89 | } |
| 90 | free(buf); |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 91 | path_n += (bb_strlen(path_n) + 1); |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 92 | } |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 93 | } |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 94 | if (found) { |
| 95 | puts(buf); |
| 96 | } else { |
Matt Kraai | 768a234 | 2000-11-18 01:16:43 +0000 | [diff] [blame] | 97 | status = EXIT_FAILURE; |
Glenn L McGrath | e84152e | 2004-03-01 08:32:49 +0000 | [diff] [blame] | 98 | } |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 99 | } |
Paul Fox | db485cf | 2005-09-14 14:08:38 +0000 | [diff] [blame] | 100 | bb_fflush_stdout_and_exit(status); |
Erik Andersen | 330fd2b | 2000-05-19 05:35:19 +0000 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | /* |
| 104 | Local Variables: |
| 105 | c-file-style: "linux" |
| 106 | c-basic-offset: 4 |
| 107 | tab-width: 4 |
| 108 | End: |
| 109 | */ |