osunixdir.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: osunixdir - Unix directory access interfaces
  5. *
  6. * Copyright (C) 2000 - 2018, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. #include <acpi/acpi.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <dirent.h>
  14. #include <fnmatch.h>
  15. #include <ctype.h>
  16. #include <sys/stat.h>
  17. /*
  18. * Allocated structure returned from os_open_directory
  19. */
  20. typedef struct external_find_info {
  21. char *dir_pathname;
  22. DIR *dir_ptr;
  23. char temp_buffer[256];
  24. char *wildcard_spec;
  25. char requested_file_type;
  26. } external_find_info;
  27. /*******************************************************************************
  28. *
  29. * FUNCTION: acpi_os_open_directory
  30. *
  31. * PARAMETERS: dir_pathname - Full pathname to the directory
  32. * wildcard_spec - string of the form "*.c", etc.
  33. *
  34. * RETURN: A directory "handle" to be used in subsequent search operations.
  35. * NULL returned on failure.
  36. *
  37. * DESCRIPTION: Open a directory in preparation for a wildcard search
  38. *
  39. ******************************************************************************/
  40. void *acpi_os_open_directory(char *dir_pathname,
  41. char *wildcard_spec, char requested_file_type)
  42. {
  43. struct external_find_info *external_info;
  44. DIR *dir;
  45. /* Allocate the info struct that will be returned to the caller */
  46. external_info = calloc(1, sizeof(struct external_find_info));
  47. if (!external_info) {
  48. return (NULL);
  49. }
  50. /* Get the directory stream */
  51. dir = opendir(dir_pathname);
  52. if (!dir) {
  53. fprintf(stderr, "Cannot open directory - %s\n", dir_pathname);
  54. free(external_info);
  55. return (NULL);
  56. }
  57. /* Save the info in the return structure */
  58. external_info->wildcard_spec = wildcard_spec;
  59. external_info->requested_file_type = requested_file_type;
  60. external_info->dir_pathname = dir_pathname;
  61. external_info->dir_ptr = dir;
  62. return (external_info);
  63. }
  64. /*******************************************************************************
  65. *
  66. * FUNCTION: acpi_os_get_next_filename
  67. *
  68. * PARAMETERS: dir_handle - Created via acpi_os_open_directory
  69. *
  70. * RETURN: Next filename matched. NULL if no more matches.
  71. *
  72. * DESCRIPTION: Get the next file in the directory that matches the wildcard
  73. * specification.
  74. *
  75. ******************************************************************************/
  76. char *acpi_os_get_next_filename(void *dir_handle)
  77. {
  78. struct external_find_info *external_info = dir_handle;
  79. struct dirent *dir_entry;
  80. char *temp_str;
  81. int str_len;
  82. struct stat temp_stat;
  83. int err;
  84. while ((dir_entry = readdir(external_info->dir_ptr))) {
  85. if (!fnmatch
  86. (external_info->wildcard_spec, dir_entry->d_name, 0)) {
  87. if (dir_entry->d_name[0] == '.') {
  88. continue;
  89. }
  90. str_len = strlen(dir_entry->d_name) +
  91. strlen(external_info->dir_pathname) + 2;
  92. temp_str = calloc(str_len, 1);
  93. if (!temp_str) {
  94. fprintf(stderr,
  95. "Could not allocate buffer for temporary string\n");
  96. return (NULL);
  97. }
  98. strcpy(temp_str, external_info->dir_pathname);
  99. strcat(temp_str, "/");
  100. strcat(temp_str, dir_entry->d_name);
  101. err = stat(temp_str, &temp_stat);
  102. if (err == -1) {
  103. fprintf(stderr,
  104. "Cannot stat file (should not happen) - %s\n",
  105. temp_str);
  106. free(temp_str);
  107. return (NULL);
  108. }
  109. free(temp_str);
  110. if ((S_ISDIR(temp_stat.st_mode)
  111. && (external_info->requested_file_type ==
  112. REQUEST_DIR_ONLY))
  113. || ((!S_ISDIR(temp_stat.st_mode)
  114. && external_info->requested_file_type ==
  115. REQUEST_FILE_ONLY))) {
  116. /* copy to a temp buffer because dir_entry struct is on the stack */
  117. strcpy(external_info->temp_buffer,
  118. dir_entry->d_name);
  119. return (external_info->temp_buffer);
  120. }
  121. }
  122. }
  123. return (NULL);
  124. }
  125. /*******************************************************************************
  126. *
  127. * FUNCTION: acpi_os_close_directory
  128. *
  129. * PARAMETERS: dir_handle - Created via acpi_os_open_directory
  130. *
  131. * RETURN: None.
  132. *
  133. * DESCRIPTION: Close the open directory and cleanup.
  134. *
  135. ******************************************************************************/
  136. void acpi_os_close_directory(void *dir_handle)
  137. {
  138. struct external_find_info *external_info = dir_handle;
  139. /* Close the directory and free allocations */
  140. closedir(external_info->dir_ptr);
  141. free(dir_handle);
  142. }