source: branches/2.2.2/mindi-busybox/debianutils/which.c @ 1247

Last change on this file since 1247 was 821, checked in by Bruno Cornec, 14 years ago

Addition of busybox 1.2.1 as a mindi-busybox new package
This should avoid delivering binary files in mindi not built there (Fedora and Debian are quite serious about that)

File size: 2.3 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * Which implementation for busybox
4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6 *
7 * Licensed under the GPL v2, see the file LICENSE in this tarball.
8 *
9 * Based on which from debianutils
10 */
11
12#include "busybox.h"
13#include <string.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include <unistd.h>
17#include <sys/stat.h>
18
19
20static int is_executable_file(const char const * a, struct stat *b)
21{
22    return (!access(a,X_OK) && !stat(a, b) && S_ISREG(b->st_mode));
23}
24
25int which_main(int argc, char **argv)
26{
27    int status;
28    size_t i, count;
29    char *path_list;
30
31    if (argc <= 1 || **(argv + 1) == '-') {
32        bb_show_usage();
33    }
34    argc--;
35
36    path_list = getenv("PATH");
37    if (path_list != NULL) {
38        size_t path_len = strlen(path_list);
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;
51                count++;
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                }
65            }
66        }
67    } else {
68        path_list = "/bin\0/sbin\0/usr/bin\0/usr/sbin\0/usr/local/bin";
69        count = 5;
70    }
71
72    status = EXIT_SUCCESS;
73    while (argc-- > 0) {
74        struct stat stat_b;
75        char *buf;
76        char *path_n;
77        int found = 0;
78
79        argv++;
80        path_n = path_list;
81        buf = *argv;
82
83        /* if filename is either absolute or contains slashes,
84         * stat it */
85        if (strchr(buf, '/') != NULL && is_executable_file(buf, &stat_b)) {
86            found++;
87        } else {
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)) {
92                    found++;
93                    break;
94                }
95                free(buf);
96                path_n += (strlen(path_n) + 1);
97            }
98        }
99        if (found) {
100            puts(buf);
101        } else {
102            status = EXIT_FAILURE;
103        }
104    }
105    bb_fflush_stdout_and_exit(status);
106}
Note: See TracBrowser for help on using the repository browser.