which.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /* vim: tabstop=4 shiftwidth=4 noexpandtab
  2. * This file is part of ToaruOS and is released under the terms
  3. * of the NCSA / University of Illinois License - see LICENSE.md
  4. * Copyright (C) 2013-2014 K. Lange
  5. *
  6. * which - Figure out which binary will be used
  7. *
  8. * Searches through $PATH to find a matching binary, just like
  9. * how execp* family does it. (Except does our execp actually
  10. * bother checking permissions? Look into this...)
  11. */
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <sys/stat.h>
  16. #define DEFAULT_PATH "/bin:/usr/bin"
  17. int main(int argc, char * argv[]) {
  18. if (argc < 2) {
  19. return 1;
  20. }
  21. if (strstr(argv[1], "/")) {
  22. struct stat t;
  23. if (!stat(argv[1], &t)) {
  24. if ((t.st_mode & 0111)) {
  25. printf("%s\n", argv[1]);
  26. return 0;
  27. }
  28. }
  29. } else {
  30. char * file = argv[1];
  31. char * path = getenv("PATH");
  32. if (!path) {
  33. path = DEFAULT_PATH;
  34. }
  35. char * xpath = strdup(path);
  36. char * p, * last;
  37. for ((p = strtok_r(xpath, ":", &last)); p; p = strtok_r(NULL, ":", &last)) {
  38. int r;
  39. struct stat stat_buf;
  40. char * exe = malloc(strlen(p) + strlen(file) + 2);
  41. strcpy(exe, p);
  42. strcat(exe, "/");
  43. strcat(exe, file);
  44. r = stat(exe, &stat_buf);
  45. if (r != 0) {
  46. continue;
  47. }
  48. if (!(stat_buf.st_mode & 0111)) {
  49. continue; /* XXX not technically correct; need to test perms */
  50. }
  51. printf("%s\n", exe);
  52. return 0;
  53. }
  54. free(xpath);
  55. return 1;
  56. }
  57. return 1;
  58. }