1 /* vi: set sw=4 ts=4: */
3 * Which implementation for busybox
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
9 * Based on which from debianutils
20 static int is_executable_file(char *a, struct stat *b)
22 return (!access(a,X_OK) && !stat(a, b) && S_ISREG(b->st_mode));
25 int which_main(int argc, char **argv)
31 if (argc <= 1 || **(argv + 1) == '-') {
36 path_list = getenv("PATH");
37 if (path_list != NULL) {
38 size_t path_len = strlen(path_list);
39 char *new_list = NULL;
42 for (i = 0; i <= path_len; i++) {
43 char *this_i = &path_list[i];
46 if (!i && (*(this_i + 1) == ':')) {
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);
56 memmove(&new_list[i+2], &path_list[i+1], path_len-i);
58 memmove(new_list, path_list, i);
60 memmove(&new_list[i+1], &path_list[i], path_len-i);
68 path_list = "/bin\0/sbin\0/usr/bin\0/usr/sbin\0/usr/local/bin";
72 status = EXIT_SUCCESS;
83 /* if filename is either absolute or contains slashes,
85 if (strchr(buf, '/') != NULL && is_executable_file(buf, &stat_b)) {
88 /* Couldn't access file and file doesn't contain slashes */
89 for (i = 0; i < count; i++) {
90 buf = concat_path_file(path_n, *argv);
91 if (is_executable_file(buf, &stat_b)) {
96 path_n += (strlen(path_n) + 1);
102 status = EXIT_FAILURE;
105 bb_fflush_stdout_and_exit(status);