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