17aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley/* which.c - Find executable files in $PATH. 20a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley * 30a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley * Copyright 2006 Rob landley <rob@landley.net> 40a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley 559f490cb4e18960e7ddd003f9a66005eccc5ebd7Rob LandleyUSE_WHICH(NEWTOY(which, "<1a", TOYFLAG_USR|TOYFLAG_BIN)) 655928b1e0a08d84a5cbc50020f0a8c1024f5b6ceRob Landley 72896480c4918f2accccb8301bec457a7bff7377eRob Landleyconfig WHICH 87aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley bool "which" 97aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley default y 107aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley help 117aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley usage: which [-a] filename ... 122896480c4918f2accccb8301bec457a7bff7377eRob Landley 137aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley Search $PATH for executable files matching filename(s). 142896480c4918f2accccb8301bec457a7bff7377eRob Landley 157aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley -a Show all matches 162896480c4918f2accccb8301bec457a7bff7377eRob Landley*/ 170a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley#include "toys.h" 180a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley 190a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley// Find an exectuable file either at a path with a slash in it (absolute or 200a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley// relative to current directory), or in $PATH. Returns absolute path to file, 210a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley// or NULL if not found. 220a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley 230a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landleystatic int which_in_path(char *filename) 240a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley{ 257aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley struct string_list *list; 260a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley 277aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley // If they gave us a path, don't worry about $PATH or -a 280a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley 297aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley if (strchr(filename, '/')) { 307aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley // Confirm it has the executable bit set, and it's not a directory. 317aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley if (!access(filename, X_OK)) { 327aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley struct stat st; 330a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley 347aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley if (!stat(filename, &st) && S_ISREG(st.st_mode)) { 357aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley puts(filename); 367aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley return 0; 377aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley } 387aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley return 1; 397aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley } 407aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley } 410a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley 427aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley // Search $PATH for matches. 437aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley list = find_in_path(getenv("PATH"), filename); 447aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley if (!list) return 1; 450a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley 467aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley // Print out matches 477aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley while (list) { 487aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley if (!access(list->str, X_OK)) { 497aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley puts(list->str); 507aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley // If we should stop at one match, do so 517aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley if (!toys.optflags) { 527aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley llist_traverse(list, free); 537aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley break; 547aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley } 557aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley } 567aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley free(llist_pop(&list)); 577aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley } 580a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley 597aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley return 0; 600a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley} 610a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley 62efda21ca931766eed6cfc49d1b2122c53827d9fcRob Landleyvoid which_main(void) 630a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley{ 647aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley int i; 657aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley 667aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley for (i=0; toys.optargs[i]; i++) 677aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley toys.exitval |= which_in_path(toys.optargs[i]); 680a04b3ef850cd3d6f06b3c8d0036993adc9ba7b2Rob Landley} 69