osunixdir.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /******************************************************************************
  2. *
  3. * Module Name: osunixdir - Unix directory access interfaces
  4. *
  5. *****************************************************************************/
  6. /*
  7. * Copyright (C) 2000 - 2015, Intel Corp.
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions, and the following disclaimer,
  15. * without modification.
  16. * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  17. * substantially similar to the "NO WARRANTY" disclaimer below
  18. * ("Disclaimer") and any redistribution must be conditioned upon
  19. * including a substantially similar Disclaimer requirement for further
  20. * binary redistribution.
  21. * 3. Neither the names of the above-listed copyright holders nor the names
  22. * of any contributors may be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * Alternatively, this software may be distributed under the terms of the
  26. * GNU General Public License ("GPL") version 2 as published by the Free
  27. * Software Foundation.
  28. *
  29. * NO WARRANTY
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  33. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  34. * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  38. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  39. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  40. * POSSIBILITY OF SUCH DAMAGES.
  41. */
  42. #include <acpi/acpi.h>
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include <dirent.h>
  47. #include <fnmatch.h>
  48. #include <ctype.h>
  49. #include <sys/stat.h>
  50. /*
  51. * Allocated structure returned from os_open_directory
  52. */
  53. typedef struct external_find_info {
  54. char *dir_pathname;
  55. DIR *dir_ptr;
  56. char temp_buffer[256];
  57. char *wildcard_spec;
  58. char requested_file_type;
  59. } external_find_info;
  60. /*******************************************************************************
  61. *
  62. * FUNCTION: acpi_os_open_directory
  63. *
  64. * PARAMETERS: dir_pathname - Full pathname to the directory
  65. * wildcard_spec - string of the form "*.c", etc.
  66. *
  67. * RETURN: A directory "handle" to be used in subsequent search operations.
  68. * NULL returned on failure.
  69. *
  70. * DESCRIPTION: Open a directory in preparation for a wildcard search
  71. *
  72. ******************************************************************************/
  73. void *acpi_os_open_directory(char *dir_pathname,
  74. char *wildcard_spec, char requested_file_type)
  75. {
  76. struct external_find_info *external_info;
  77. DIR *dir;
  78. /* Allocate the info struct that will be returned to the caller */
  79. external_info = calloc(1, sizeof(struct external_find_info));
  80. if (!external_info) {
  81. return (NULL);
  82. }
  83. /* Get the directory stream */
  84. dir = opendir(dir_pathname);
  85. if (!dir) {
  86. fprintf(stderr, "Cannot open directory - %s\n", dir_pathname);
  87. free(external_info);
  88. return (NULL);
  89. }
  90. /* Save the info in the return structure */
  91. external_info->wildcard_spec = wildcard_spec;
  92. external_info->requested_file_type = requested_file_type;
  93. external_info->dir_pathname = dir_pathname;
  94. external_info->dir_ptr = dir;
  95. return (external_info);
  96. }
  97. /*******************************************************************************
  98. *
  99. * FUNCTION: acpi_os_get_next_filename
  100. *
  101. * PARAMETERS: dir_handle - Created via acpi_os_open_directory
  102. *
  103. * RETURN: Next filename matched. NULL if no more matches.
  104. *
  105. * DESCRIPTION: Get the next file in the directory that matches the wildcard
  106. * specification.
  107. *
  108. ******************************************************************************/
  109. char *acpi_os_get_next_filename(void *dir_handle)
  110. {
  111. struct external_find_info *external_info = dir_handle;
  112. struct dirent *dir_entry;
  113. char *temp_str;
  114. int str_len;
  115. struct stat temp_stat;
  116. int err;
  117. while ((dir_entry = readdir(external_info->dir_ptr))) {
  118. if (!fnmatch
  119. (external_info->wildcard_spec, dir_entry->d_name, 0)) {
  120. if (dir_entry->d_name[0] == '.') {
  121. continue;
  122. }
  123. str_len = strlen(dir_entry->d_name) +
  124. strlen(external_info->dir_pathname) + 2;
  125. temp_str = calloc(str_len, 1);
  126. if (!temp_str) {
  127. fprintf(stderr,
  128. "Could not allocate buffer for temporary string\n");
  129. return (NULL);
  130. }
  131. strcpy(temp_str, external_info->dir_pathname);
  132. strcat(temp_str, "/");
  133. strcat(temp_str, dir_entry->d_name);
  134. err = stat(temp_str, &temp_stat);
  135. if (err == -1) {
  136. fprintf(stderr,
  137. "Cannot stat file (should not happen) - %s\n",
  138. temp_str);
  139. free(temp_str);
  140. return (NULL);
  141. }
  142. free(temp_str);
  143. if ((S_ISDIR(temp_stat.st_mode)
  144. && (external_info->requested_file_type ==
  145. REQUEST_DIR_ONLY))
  146. || ((!S_ISDIR(temp_stat.st_mode)
  147. && external_info->requested_file_type ==
  148. REQUEST_FILE_ONLY))) {
  149. /* copy to a temp buffer because dir_entry struct is on the stack */
  150. strcpy(external_info->temp_buffer,
  151. dir_entry->d_name);
  152. return (external_info->temp_buffer);
  153. }
  154. }
  155. }
  156. return (NULL);
  157. }
  158. /*******************************************************************************
  159. *
  160. * FUNCTION: acpi_os_close_directory
  161. *
  162. * PARAMETERS: dir_handle - Created via acpi_os_open_directory
  163. *
  164. * RETURN: None.
  165. *
  166. * DESCRIPTION: Close the open directory and cleanup.
  167. *
  168. ******************************************************************************/
  169. void acpi_os_close_directory(void *dir_handle)
  170. {
  171. struct external_find_info *external_info = dir_handle;
  172. /* Close the directory and free allocations */
  173. closedir(external_info->dir_ptr);
  174. free(dir_handle);
  175. }