source: MondoRescue/branches/stable/mindi-busybox/debianutils/which.c@ 821

Last change on this file since 821 was 821, checked in by Bruno Cornec, 18 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
RevLine 
[821]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.