brintos

brintos / linux-shallow public Read only

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