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