OSDN Git Service

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