1 /******************************************************************************
   2  *
   3  * Module Name: oswindir - Windows 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 <io.h>
  50 
  51 typedef struct ExternalFindInfo
  52 {
  53     struct _finddata_t          DosInfo;
  54     char                        *FullWildcardSpec;
  55     long                        FindHandle;
  56     char                        State;
  57     char                        RequestedFileType;
  58 
  59 } EXTERNAL_FIND_INFO;
  60 
  61 
  62 /*******************************************************************************
  63  *
  64  * FUNCTION:    AcpiOsOpenDirectory
  65  *
  66  * PARAMETERS:  DirPathname         - Full pathname to the directory
  67  *              WildcardSpec        - string of the form "*.c", etc.
  68  *              RequestedFileType   - Either a directory or normal file
  69  *
  70  * RETURN:      A directory "handle" to be used in subsequent search operations.
  71  *              NULL returned on failure.
  72  *
  73  * DESCRIPTION: Open a directory in preparation for a wildcard search
  74  *
  75  ******************************************************************************/
  76 
  77 void *
  78 AcpiOsOpenDirectory (
  79     char                    *DirPathname,
  80     char                    *WildcardSpec,
  81     char                    RequestedFileType)
  82 {
  83     long                    FindHandle;
  84     char                    *FullWildcardSpec;
  85     EXTERNAL_FIND_INFO      *SearchInfo;
  86 
  87 
  88     /* No directory path means "use current directory" - use a dot */
  89 
  90     if (!DirPathname || strlen (DirPathname) == 0)
  91     {
  92         DirPathname = ".";
  93     }
  94 
  95     /* Allocate the info struct that will be returned to the caller */
  96 
  97     SearchInfo = calloc (sizeof (EXTERNAL_FIND_INFO), 1);
  98     if (!SearchInfo)
  99     {
 100         return (NULL);
 101     }
 102 
 103     /* Allocate space for the full wildcard path */
 104 
 105     FullWildcardSpec = calloc (strlen (DirPathname) + strlen (WildcardSpec) + 2, 1);
 106     if (!FullWildcardSpec)
 107     {
 108         printf ("Could not allocate buffer for wildcard pathname\n");
 109         return (NULL);
 110     }
 111 
 112     /* Create the full wildcard path */
 113 
 114     strcpy (FullWildcardSpec, DirPathname);
 115     strcat (FullWildcardSpec, "/");
 116     strcat (FullWildcardSpec, WildcardSpec);
 117 
 118     /* Initialize the find functions, get first match */
 119 
 120     FindHandle = _findfirst (FullWildcardSpec, &SearchInfo->DosInfo);
 121     if (FindHandle == -1)
 122     {
 123         /* Failure means that no match was found */
 124 
 125         free (FullWildcardSpec);
 126         free (SearchInfo);
 127         return (NULL);
 128     }
 129 
 130     /* Save the info in the return structure */
 131 
 132     SearchInfo->RequestedFileType = RequestedFileType;
 133     SearchInfo->FullWildcardSpec = FullWildcardSpec;
 134     SearchInfo->FindHandle = FindHandle;
 135     SearchInfo->State = 0;
 136     return (SearchInfo);
 137 }
 138 
 139 
 140 /*******************************************************************************
 141  *
 142  * FUNCTION:    AcpiOsGetNextFilename
 143  *
 144  * PARAMETERS:  DirHandle           - Created via AcpiOsOpenDirectory
 145  *
 146  * RETURN:      Next filename matched. NULL if no more matches.
 147  *
 148  * DESCRIPTION: Get the next file in the directory that matches the wildcard
 149  *              specification.
 150  *
 151  ******************************************************************************/
 152 
 153 char *
 154 AcpiOsGetNextFilename (
 155     void                    *DirHandle)
 156 {
 157     EXTERNAL_FIND_INFO      *SearchInfo = DirHandle;
 158     int                     Status;
 159     char                    FileTypeNotMatched = 1;
 160 
 161 
 162     /*
 163      * Loop while we have matched files but not found any files of
 164      * the requested type.
 165      */
 166     while (FileTypeNotMatched)
 167     {
 168         /* On the first call, we already have the first match */
 169 
 170         if (SearchInfo->State == 0)
 171         {
 172             /* No longer the first match */
 173 
 174             SearchInfo->State = 1;
 175         }
 176         else
 177         {
 178             /* Get the next match */
 179 
 180             Status = _findnext (SearchInfo->FindHandle, &SearchInfo->DosInfo);
 181             if (Status != 0)
 182             {
 183                 return (NULL);
 184             }
 185         }
 186 
 187         /*
 188          * Found a match, now check to make sure that the file type
 189          * matches the requested file type (directory or normal file)
 190          *
 191          * NOTE: use of the attrib field saves us from doing a very
 192          * expensive stat() on the file!
 193          */
 194         switch (SearchInfo->RequestedFileType)
 195         {
 196         case REQUEST_FILE_ONLY:
 197 
 198             /* Anything other than A_SUBDIR is OK */
 199 
 200             if (!(SearchInfo->DosInfo.attrib & _A_SUBDIR))
 201             {
 202                 FileTypeNotMatched = 0;
 203             }
 204             break;
 205 
 206         case REQUEST_DIR_ONLY:
 207 
 208             /* Must have A_SUBDIR bit set */
 209 
 210             if (SearchInfo->DosInfo.attrib & _A_SUBDIR)
 211             {
 212                 FileTypeNotMatched = 0;
 213             }
 214             break;
 215 
 216         default:
 217 
 218             return (NULL);
 219         }
 220     }
 221 
 222     return (SearchInfo->DosInfo.name);
 223 }
 224 
 225 
 226 /*******************************************************************************
 227  *
 228  * FUNCTION:    AcpiOsCloseDirectory
 229  *
 230  * PARAMETERS:  DirHandle           - Created via AcpiOsOpenDirectory
 231  *
 232  * RETURN:      None
 233  *
 234  * DESCRIPTION: Close the open directory and cleanup.
 235  *
 236  ******************************************************************************/
 237 
 238 void
 239 AcpiOsCloseDirectory (
 240     void                    *DirHandle)
 241 {
 242     EXTERNAL_FIND_INFO      *SearchInfo = DirHandle;
 243 
 244 
 245     /* Close the directory and free allocations */
 246 
 247     _findclose (SearchInfo->FindHandle);
 248     free (SearchInfo->FullWildcardSpec);
 249     free (DirHandle);
 250 }