1*cf5a6c84SAndroid Build Coastguard Worker /* which.c - Find executable files in $PATH.
2*cf5a6c84SAndroid Build Coastguard Worker *
3*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2006 Rob landley <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker
5*cf5a6c84SAndroid Build Coastguard Worker USE_WHICH(NEWTOY(which, "<1a", TOYFLAG_USR|TOYFLAG_BIN))
6*cf5a6c84SAndroid Build Coastguard Worker
7*cf5a6c84SAndroid Build Coastguard Worker config WHICH
8*cf5a6c84SAndroid Build Coastguard Worker bool "which"
9*cf5a6c84SAndroid Build Coastguard Worker default y
10*cf5a6c84SAndroid Build Coastguard Worker help
11*cf5a6c84SAndroid Build Coastguard Worker usage: which [-a] filename ...
12*cf5a6c84SAndroid Build Coastguard Worker
13*cf5a6c84SAndroid Build Coastguard Worker Search $PATH for executable files matching filename(s).
14*cf5a6c84SAndroid Build Coastguard Worker
15*cf5a6c84SAndroid Build Coastguard Worker -a Show all matches
16*cf5a6c84SAndroid Build Coastguard Worker */
17*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
18*cf5a6c84SAndroid Build Coastguard Worker
19*cf5a6c84SAndroid Build Coastguard Worker // Find an exectuable file either at a path with a slash in it (absolute or
20*cf5a6c84SAndroid Build Coastguard Worker // relative to current directory), or in $PATH. Returns absolute path to file,
21*cf5a6c84SAndroid Build Coastguard Worker // or NULL if not found.
22*cf5a6c84SAndroid Build Coastguard Worker
which_in_path(char * filename)23*cf5a6c84SAndroid Build Coastguard Worker static int which_in_path(char *filename)
24*cf5a6c84SAndroid Build Coastguard Worker {
25*cf5a6c84SAndroid Build Coastguard Worker struct string_list *list;
26*cf5a6c84SAndroid Build Coastguard Worker
27*cf5a6c84SAndroid Build Coastguard Worker // If they gave us a path, don't worry about $PATH or -a
28*cf5a6c84SAndroid Build Coastguard Worker
29*cf5a6c84SAndroid Build Coastguard Worker if (strchr(filename, '/')) {
30*cf5a6c84SAndroid Build Coastguard Worker // Confirm it has the executable bit set, and it's not a directory.
31*cf5a6c84SAndroid Build Coastguard Worker if (!access(filename, X_OK)) {
32*cf5a6c84SAndroid Build Coastguard Worker struct stat st;
33*cf5a6c84SAndroid Build Coastguard Worker
34*cf5a6c84SAndroid Build Coastguard Worker if (!stat(filename, &st) && S_ISREG(st.st_mode)) {
35*cf5a6c84SAndroid Build Coastguard Worker puts(filename);
36*cf5a6c84SAndroid Build Coastguard Worker return 0;
37*cf5a6c84SAndroid Build Coastguard Worker }
38*cf5a6c84SAndroid Build Coastguard Worker return 1;
39*cf5a6c84SAndroid Build Coastguard Worker }
40*cf5a6c84SAndroid Build Coastguard Worker }
41*cf5a6c84SAndroid Build Coastguard Worker
42*cf5a6c84SAndroid Build Coastguard Worker // Search $PATH for matches.
43*cf5a6c84SAndroid Build Coastguard Worker list = find_in_path(getenv("PATH"), filename);
44*cf5a6c84SAndroid Build Coastguard Worker if (!list) return 1;
45*cf5a6c84SAndroid Build Coastguard Worker
46*cf5a6c84SAndroid Build Coastguard Worker // Print out matches
47*cf5a6c84SAndroid Build Coastguard Worker while (list) {
48*cf5a6c84SAndroid Build Coastguard Worker if (!access(list->str, X_OK)) {
49*cf5a6c84SAndroid Build Coastguard Worker puts(list->str);
50*cf5a6c84SAndroid Build Coastguard Worker // If we should stop at one match, do so
51*cf5a6c84SAndroid Build Coastguard Worker if (!toys.optflags) {
52*cf5a6c84SAndroid Build Coastguard Worker llist_traverse(list, free);
53*cf5a6c84SAndroid Build Coastguard Worker break;
54*cf5a6c84SAndroid Build Coastguard Worker }
55*cf5a6c84SAndroid Build Coastguard Worker }
56*cf5a6c84SAndroid Build Coastguard Worker free(llist_pop(&list));
57*cf5a6c84SAndroid Build Coastguard Worker }
58*cf5a6c84SAndroid Build Coastguard Worker
59*cf5a6c84SAndroid Build Coastguard Worker return 0;
60*cf5a6c84SAndroid Build Coastguard Worker }
61*cf5a6c84SAndroid Build Coastguard Worker
which_main(void)62*cf5a6c84SAndroid Build Coastguard Worker void which_main(void)
63*cf5a6c84SAndroid Build Coastguard Worker {
64*cf5a6c84SAndroid Build Coastguard Worker int i;
65*cf5a6c84SAndroid Build Coastguard Worker
66*cf5a6c84SAndroid Build Coastguard Worker for (i=0; toys.optargs[i]; i++)
67*cf5a6c84SAndroid Build Coastguard Worker toys.exitval |= which_in_path(toys.optargs[i]);
68*cf5a6c84SAndroid Build Coastguard Worker }
69