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