aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debianutils/which.c71
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
33extern int which_main(int argc, char **argv) 19extern 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/*