diff options
author | pgf <pgf@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2005-09-14 14:08:38 +0000 |
---|---|---|
committer | pgf <pgf@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2005-09-14 14:08:38 +0000 |
commit | 95c3a626123192c85c93ef171ea2ab40b57079c3 (patch) | |
tree | d3a11bf9e36b0992fbe9dd3a1ca5b03a64f4db87 | |
parent | 3531b6175a75641927d1659b3397a62d9fced60f (diff) | |
download | busybox-w32-95c3a626123192c85c93ef171ea2ab40b57079c3.tar.gz busybox-w32-95c3a626123192c85c93ef171ea2ab40b57079c3.tar.bz2 busybox-w32-95c3a626123192c85c93ef171ea2ab40b57079c3.zip |
committing bug #7:
0000007: which and wd-located files
which doesn't search $PATH when there's a file in the WD with
the same name of the 'filename' parameter...
git-svn-id: svn://busybox.net/trunk/busybox@11454 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r-- | debianutils/which.c | 71 |
1 files changed, 42 insertions, 29 deletions
diff --git a/debianutils/which.c b/debianutils/which.c index 999dded36..deb036aa0 100644 --- a/debianutils/which.c +++ b/debianutils/which.c | |||
@@ -4,36 +4,23 @@ | |||
4 | * | 4 | * |
5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> | 5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * Licensed under the GPL v2, see the file LICENSE in this tarball. |
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | 8 | * |
21 | * Based on which from debianutils | 9 | * Based on which from debianutils |
22 | */ | 10 | */ |
23 | 11 | ||
24 | |||
25 | #include <string.h> | 12 | #include <string.h> |
26 | #include <stdio.h> | 13 | #include <stdio.h> |
27 | #include <stdlib.h> | 14 | #include <stdlib.h> |
28 | #include <unistd.h> | 15 | #include <unistd.h> |
29 | 16 | #include <sys/stat.h> | |
30 | #include "busybox.h" | 17 | #include "busybox.h" |
31 | 18 | ||
32 | |||
33 | extern int which_main(int argc, char **argv) | 19 | extern int which_main(int argc, char **argv) |
34 | { | 20 | { |
21 | int status = EXIT_SUCCESS; | ||
22 | size_t i, count; | ||
35 | char *path_list; | 23 | char *path_list; |
36 | int i, count=1, status = EXIT_SUCCESS; | ||
37 | 24 | ||
38 | if (argc <= 1 || **(argv + 1) == '-') { | 25 | if (argc <= 1 || **(argv + 1) == '-') { |
39 | bb_show_usage(); | 26 | bb_show_usage(); |
@@ -42,10 +29,33 @@ extern int which_main(int argc, char **argv) | |||
42 | 29 | ||
43 | path_list = getenv("PATH"); | 30 | path_list = getenv("PATH"); |
44 | if (path_list != NULL) { | 31 | if (path_list != NULL) { |
45 | for (i=strlen(path_list); i > 0; i--) { | 32 | size_t path_len = bb_strlen(path_list); |
46 | if (path_list[i]==':') { | 33 | char *new_list = NULL; |
47 | path_list[i]=0; | 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; | ||
48 | count++; | 45 | count++; |
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 | } | ||
49 | } | 59 | } |
50 | } | 60 | } |
51 | } else { | 61 | } else { |
@@ -54,28 +64,31 @@ extern int which_main(int argc, char **argv) | |||
54 | } | 64 | } |
55 | 65 | ||
56 | while (argc-- > 0) { | 66 | while (argc-- > 0) { |
67 | struct stat stat_b; | ||
57 | char *buf; | 68 | char *buf; |
58 | char *path_n; | 69 | char *path_n; |
59 | char found = 0; | 70 | char found = 0; |
60 | argv++; | 71 | #define is_executable_file(a, b) (!access(a,X_OK) && !stat(a, &b) && \ |
72 | S_ISREG(b.st_mode)) | ||
61 | 73 | ||
62 | /* | 74 | argv++; |
63 | * Check if we were given the full path, first. | ||
64 | * Otherwise see if the file exists in our $PATH. | ||
65 | */ | ||
66 | path_n = path_list; | 75 | path_n = path_list; |
67 | buf = *argv; | 76 | buf = *argv; |
68 | if (access(buf, X_OK) == 0) { | 77 | |
78 | /* if filename is either absolute or contains slashes, | ||
79 | * stat it */ | ||
80 | if (strchr(buf, '/') != NULL && is_executable_file(buf, stat_b)) { | ||
69 | found = 1; | 81 | found = 1; |
70 | } else { | 82 | } else { |
83 | /* Couldn't access file and file doesn't contain slashes */ | ||
71 | for (i = 0; i < count; i++) { | 84 | for (i = 0; i < count; i++) { |
72 | buf = concat_path_file(path_n, *argv); | 85 | buf = concat_path_file(path_n, *argv); |
73 | if (access(buf, X_OK) == 0) { | 86 | if (is_executable_file(buf, stat_b)) { |
74 | found = 1; | 87 | found = 1; |
75 | break; | 88 | break; |
76 | } | 89 | } |
77 | free(buf); | 90 | free(buf); |
78 | path_n += (strlen(path_n) + 1); | 91 | path_n += (bb_strlen(path_n) + 1); |
79 | } | 92 | } |
80 | } | 93 | } |
81 | if (found) { | 94 | if (found) { |
@@ -84,7 +97,7 @@ extern int which_main(int argc, char **argv) | |||
84 | status = EXIT_FAILURE; | 97 | status = EXIT_FAILURE; |
85 | } | 98 | } |
86 | } | 99 | } |
87 | return status; | 100 | bb_fflush_stdout_and_exit(status); |
88 | } | 101 | } |
89 | 102 | ||
90 | /* | 103 | /* |