which.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Which implementation for busybox
  4. *
  5. * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
  6. * Copyright (C) 2006 Gabriel Somlo <somlo at cmu.edu>
  7. *
  8. * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
  9. *
  10. * Based on which from debianutils
  11. */
  12. #include "libbb.h"
  13. int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  14. int which_main(int argc UNUSED_PARAM, char **argv)
  15. {
  16. IF_DESKTOP(int opt;)
  17. int status = EXIT_SUCCESS;
  18. char *path;
  19. char *p;
  20. opt_complementary = "-1"; /* at least one argument */
  21. IF_DESKTOP(opt =) getopt32(argv, "a");
  22. argv += optind;
  23. /* This matches what is seen on e.g. ubuntu.
  24. * "which" there is a shell script. */
  25. path = getenv("PATH");
  26. if (!path) {
  27. path = (char*)bb_PATH_root_path;
  28. putenv(path);
  29. path += 5; /* skip "PATH=" */
  30. }
  31. do {
  32. #if ENABLE_DESKTOP
  33. /* Much bloat just to support -a */
  34. if (strchr(*argv, '/')) {
  35. if (execable_file(*argv)) {
  36. puts(*argv);
  37. continue;
  38. }
  39. status = EXIT_FAILURE;
  40. } else {
  41. char *path2 = xstrdup(path);
  42. char *tmp = path2;
  43. p = find_execable(*argv, &tmp);
  44. if (!p)
  45. status = EXIT_FAILURE;
  46. else {
  47. print:
  48. puts(p);
  49. free(p);
  50. if (opt) {
  51. /* -a: show matches in all PATH components */
  52. if (tmp) {
  53. p = find_execable(*argv, &tmp);
  54. if (p)
  55. goto print;
  56. }
  57. }
  58. }
  59. free(path2);
  60. }
  61. #else
  62. /* Just ignoring -a */
  63. if (strchr(*argv, '/')) {
  64. if (execable_file(*argv)) {
  65. puts(*argv);
  66. continue;
  67. }
  68. } else {
  69. char *path2 = xstrdup(path);
  70. char *tmp = path2;
  71. p = find_execable(*argv, &tmp);
  72. free(path2);
  73. if (p) {
  74. puts(p);
  75. free(p);
  76. continue;
  77. }
  78. }
  79. status = EXIT_FAILURE;
  80. #endif
  81. } while (*(++argv) != NULL);
  82. fflush_stdout_and_exit(status);
  83. }