which.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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. int ret_val = 0;
  19. int i = 1;
  20. int print_all = 0;
  21. if (i < argc && !strcmp(argv[i],"-a")) {
  22. print_all = 1;
  23. i++;
  24. }
  25. if (i == argc) {
  26. return 1;
  27. }
  28. for (; i < argc; ++i) {
  29. if (strstr(argv[i], "/")) {
  30. struct stat t;
  31. if (!stat(argv[i], &t)) {
  32. if ((t.st_mode & 0111)) {
  33. printf("%s\n", argv[1]);
  34. }
  35. }
  36. } else {
  37. char * file = argv[i];
  38. char * path = getenv("PATH");
  39. if (!path) {
  40. path = DEFAULT_PATH;
  41. }
  42. char * xpath = strdup(path);
  43. char * p, * last;
  44. int found = 0;
  45. for ((p = strtok_r(xpath, ":", &last)); p; p = strtok_r(NULL, ":", &last)) {
  46. int r;
  47. struct stat stat_buf;
  48. char * exe = malloc(strlen(p) + strlen(file) + 2);
  49. strcpy(exe, p);
  50. strcat(exe, "/");
  51. strcat(exe, file);
  52. r = stat(exe, &stat_buf);
  53. if (r != 0) {
  54. continue;
  55. }
  56. if (!(stat_buf.st_mode & 0111)) {
  57. continue; /* XXX not technically correct; need to test perms */
  58. }
  59. found = 1;
  60. printf("%s\n", exe);
  61. if (print_all) continue;
  62. break;
  63. }
  64. free(xpath);
  65. if (!found) ret_val = 1;
  66. }
  67. }
  68. return ret_val;
  69. }