which.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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 GPLv2 or later, see file LICENSE in this source tree.
  9. *
  10. * Based on which from debianutils
  11. */
  12. //usage:#define which_trivial_usage
  13. //usage: "[COMMAND]..."
  14. //usage:#define which_full_usage "\n\n"
  15. //usage: "Locate a COMMAND"
  16. //usage:
  17. //usage:#define which_example_usage
  18. //usage: "$ which login\n"
  19. //usage: "/bin/login\n"
  20. #include "libbb.h"
  21. int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  22. int which_main(int argc UNUSED_PARAM, char **argv)
  23. {
  24. IF_DESKTOP(int opt;)
  25. int status = EXIT_SUCCESS;
  26. char *path;
  27. char *p;
  28. opt_complementary = "-1"; /* at least one argument */
  29. IF_DESKTOP(opt =) getopt32(argv, "a");
  30. argv += optind;
  31. /* This matches what is seen on e.g. ubuntu.
  32. * "which" there is a shell script. */
  33. path = getenv("PATH");
  34. if (!path) {
  35. path = (char*)bb_PATH_root_path;
  36. putenv(path);
  37. path += 5; /* skip "PATH=" */
  38. }
  39. do {
  40. #if ENABLE_DESKTOP
  41. /* Much bloat just to support -a */
  42. if (strchr(*argv, '/')) {
  43. if (execable_file(*argv)) {
  44. puts(*argv);
  45. continue;
  46. }
  47. status = EXIT_FAILURE;
  48. } else {
  49. char *path2 = xstrdup(path);
  50. char *tmp = path2;
  51. p = find_execable(*argv, &tmp);
  52. if (!p)
  53. status = EXIT_FAILURE;
  54. else {
  55. print:
  56. puts(p);
  57. free(p);
  58. if (opt) {
  59. /* -a: show matches in all PATH components */
  60. if (tmp) {
  61. p = find_execable(*argv, &tmp);
  62. if (p)
  63. goto print;
  64. }
  65. }
  66. }
  67. free(path2);
  68. }
  69. #else
  70. /* Just ignoring -a */
  71. if (strchr(*argv, '/')) {
  72. if (execable_file(*argv)) {
  73. puts(*argv);
  74. continue;
  75. }
  76. } else {
  77. char *path2 = xstrdup(path);
  78. char *tmp = path2;
  79. p = find_execable(*argv, &tmp);
  80. free(path2);
  81. if (p) {
  82. puts(p);
  83. free(p);
  84. continue;
  85. }
  86. }
  87. status = EXIT_FAILURE;
  88. #endif
  89. } while (*(++argv) != NULL);
  90. fflush_stdout_and_exit(status);
  91. }