1 /******************************************************************************
   2  *
   3  * Module Name: osunixdir - Unix directory access interfaces
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, 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.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 OsOpenDirectory
  56  */
  57 typedef struct ExternalFindInfo
  58 {
  59     char                        *DirPathname;
  60     DIR                         *DirPtr;
  61     char                        temp_buffer[256];
  62     char                        *WildcardSpec;
  63     char                        RequestedFileType;
  64 
  65 } EXTERNAL_FIND_INFO;
  66 
  67 
  68 /*******************************************************************************
  69  *
  70  * FUNCTION:    AcpiOsOpenDirectory
  71  *
  72  * PARAMETERS:  DirPathname         - Full pathname to the directory
  73  *              WildcardSpec        - string of the form "*.c", etc.
  74  *
  75  * RETURN:      A directory "handle" to be used in subsequent search operations.
  76  *              NULL returned on failure.
  77  *
  78  * DESCRIPTION: Open a directory in preparation for a wildcard search
  79  *
  80  ******************************************************************************/
  81 
  82 void *
  83 AcpiOsOpenDirectory (
  84     char                    *DirPathname,
  85     char                    *WildcardSpec,
  86     char                    RequestedFileType)
  87 {
  88     EXTERNAL_FIND_INFO      *ExternalInfo;
  89     DIR                     *dir;
  90 
  91 
  92     /* Allocate the info struct that will be returned to the caller */
  93 
  94     ExternalInfo = calloc (1, sizeof (EXTERNAL_FIND_INFO));
  95     if (!ExternalInfo)
  96     {
  97         return (NULL);
  98     }
  99 
 100     /* Get the directory stream */
 101 
 102     dir = opendir (DirPathname);
 103     if (!dir)
 104     {
 105         fprintf (stderr, "Cannot open directory - %s\n", DirPathname);
 106         free (ExternalInfo);
 107         return (NULL);
 108     }
 109 
 110     /* Save the info in the return structure */
 111 
 112     ExternalInfo->WildcardSpec = WildcardSpec;
 113     ExternalInfo->RequestedFileType = RequestedFileType;
 114     ExternalInfo->DirPathname = DirPathname;
 115     ExternalInfo->DirPtr = dir;
 116     return (ExternalInfo);
 117 }
 118 
 119 
 120 /*******************************************************************************
 121  *
 122  * FUNCTION:    AcpiOsGetNextFilename
 123  *
 124  * PARAMETERS:  DirHandle           - Created via AcpiOsOpenDirectory
 125  *
 126  * RETURN:      Next filename matched. NULL if no more matches.
 127  *
 128  * DESCRIPTION: Get the next file in the directory that matches the wildcard
 129  *              specification.
 130  *
 131  ******************************************************************************/
 132 
 133 char *
 134 AcpiOsGetNextFilename (
 135     void                    *DirHandle)
 136 {
 137     EXTERNAL_FIND_INFO      *ExternalInfo = DirHandle;
 138     struct dirent           *dir_entry;
 139     char                    *temp_str;
 140     int                     str_len;
 141     struct stat             temp_stat;
 142     int                     err;
 143 
 144 
 145     while ((dir_entry = readdir (ExternalInfo->DirPtr)))
 146     {
 147         if (!fnmatch (ExternalInfo->WildcardSpec, dir_entry->d_name, 0))
 148         {
 149             if (dir_entry->d_name[0] == '.')
 150             {
 151                 continue;
 152             }
 153 
 154             str_len = strlen (dir_entry->d_name) +
 155                         strlen (ExternalInfo->DirPathname) + 2;
 156 
 157             temp_str = calloc (str_len, 1);
 158             if (!temp_str)
 159             {
 160                 fprintf (stderr,
 161                     "Could not allocate buffer for temporary string\n");
 162                 return (NULL);
 163             }
 164 
 165             strcpy (temp_str, ExternalInfo->DirPathname);
 166             strcat (temp_str, "/");
 167             strcat (temp_str, dir_entry->d_name);
 168 
 169             err = stat (temp_str, &temp_stat);
 170             if (err == -1)
 171             {
 172                 fprintf (stderr,
 173                     "Cannot stat file (should not happen) - %s\n",
 174                     temp_str);
 175                 free (temp_str);
 176                 return (NULL);
 177             }
 178 
 179             free (temp_str);
 180 
 181             if ((S_ISDIR (temp_stat.st_mode)
 182                 && (ExternalInfo->RequestedFileType == REQUEST_DIR_ONLY))
 183                ||
 184                ((!S_ISDIR (temp_stat.st_mode)
 185                 && ExternalInfo->RequestedFileType == REQUEST_FILE_ONLY)))
 186             {
 187                 /* copy to a temp buffer because dir_entry struct is on the stack */
 188 
 189                 strcpy (ExternalInfo->temp_buffer, dir_entry->d_name);
 190                 return (ExternalInfo->temp_buffer);
 191             }
 192         }
 193     }
 194 
 195     return (NULL);
 196 }
 197 
 198 
 199 /*******************************************************************************
 200  *
 201  * FUNCTION:    AcpiOsCloseDirectory
 202  *
 203  * PARAMETERS:  DirHandle           - Created via AcpiOsOpenDirectory
 204  *
 205  * RETURN:      None.
 206  *
 207  * DESCRIPTION: Close the open directory and cleanup.
 208  *
 209  ******************************************************************************/
 210 
 211 void
 212 AcpiOsCloseDirectory (
 213     void                    *DirHandle)
 214 {
 215     EXTERNAL_FIND_INFO      *ExternalInfo = DirHandle;
 216 
 217 
 218     /* Close the directory and free allocations */
 219 
 220     closedir (ExternalInfo->DirPtr);
 221     free (DirHandle);
 222 }