You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
1.8 KiB

  1. /* LINTLIBRARY */
  2. #include <stdio.h>
  3. #include "util.h"
  4. static int check_file (char const *, char const *);
  5. char *
  6. util_path_search(char const *prog)
  7. {
  8. #ifdef UNIX
  9. return util_file_search(prog, getenv("PATH"), (char *) "x");
  10. #else
  11. return util_file_search(prog, NIL(char), (char *) "x");
  12. #endif
  13. }
  14. char *
  15. util_file_search(
  16. char const *file, /* file we're looking for */
  17. char *path, /* search path, colon separated */
  18. char const *mode /* "r", "w", or "x" */)
  19. {
  20. int quit;
  21. char *buffer, *filename, *save_path, *cp;
  22. if (path == 0 || strcmp(path, "") == 0) {
  23. path = (char *) "."; /* just look in the current directory */
  24. }
  25. save_path = path = strsav(path);
  26. quit = 0;
  27. do {
  28. cp = strchr(path, ':');
  29. if (cp != 0) {
  30. *cp = '\0';
  31. } else {
  32. quit = 1;
  33. }
  34. /* cons up the filename out of the path and file name */
  35. if (strcmp(path, ".") == 0) {
  36. buffer = strsav(file);
  37. } else {
  38. buffer = ALLOC(char, strlen(path) + strlen(file) + 4);
  39. (void) sprintf(buffer, "%s/%s", path, file);
  40. }
  41. filename = util_tilde_expand(buffer);
  42. FREE(buffer);
  43. /* see if we can access it */
  44. if (check_file(filename, mode)) {
  45. FREE(save_path);
  46. return filename;
  47. }
  48. FREE(filename);
  49. path = ++cp;
  50. } while (! quit);
  51. FREE(save_path);
  52. return 0;
  53. }
  54. static int
  55. check_file(char const *filename, char const *mode)
  56. {
  57. #ifdef UNIX
  58. int access_mode = /*F_OK*/ 0;
  59. if (strcmp(mode, "r") == 0) {
  60. access_mode = /*R_OK*/ 4;
  61. } else if (strcmp(mode, "w") == 0) {
  62. access_mode = /*W_OK*/ 2;
  63. } else if (strcmp(mode, "x") == 0) {
  64. access_mode = /*X_OK*/ 1;
  65. }
  66. return access(filename, access_mode) == 0;
  67. #else
  68. FILE *fp;
  69. int got_file;
  70. if (strcmp(mode, "x") == 0) {
  71. mode = "r";
  72. }
  73. fp = fopen(filename, mode);
  74. got_file = (fp != 0);
  75. if (fp != 0) {
  76. (void) fclose(fp);
  77. }
  78. return got_file;
  79. #endif
  80. }