Home | History | Annotate | Download | only in other
      1 /* which.c - Find executable files in $PATH.
      2  *
      3  * Copyright 2006 Rob landley <rob (at) 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 
     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 
     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