1 /******************************************************************************
2  *
3  * Module Name: oswindir - Windows directory access interfaces
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2015, 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 (
106         strlen (DirPathname) + strlen (WildcardSpec) + 2, 1);
107     if (!FullWildcardSpec)
108     {
109         printf ("Could not allocate buffer for wildcard pathname\n");
110         free (SearchInfo);
111         return (NULL);
112     }
113 
114     /* Create the full wildcard path */
115 
116     strcpy (FullWildcardSpec, DirPathname);
117     strcat (FullWildcardSpec, "/");
118     strcat (FullWildcardSpec, WildcardSpec);
119 
120     /* Initialize the find functions, get first match */
121 
122     FindHandle = _findfirst (FullWildcardSpec, &SearchInfo->DosInfo);
123     if (FindHandle == -1)
124     {
125         /* Failure means that no match was found */
126 
127         free (FullWildcardSpec);
128         free (SearchInfo);
129         return (NULL);
130     }
131 
132     /* Save the info in the return structure */
133 
134     SearchInfo->RequestedFileType = RequestedFileType;
135     SearchInfo->FullWildcardSpec = FullWildcardSpec;
136     SearchInfo->FindHandle = FindHandle;
137     SearchInfo->State = 0;
138     return (SearchInfo);
139 }
140 
141 
142 /*******************************************************************************
143  *
144  * FUNCTION:    AcpiOsGetNextFilename
145  *
146  * PARAMETERS:  DirHandle           - Created via AcpiOsOpenDirectory
147  *
148  * RETURN:      Next filename matched. NULL if no more matches.
149  *
150  * DESCRIPTION: Get the next file in the directory that matches the wildcard
151  *              specification.
152  *
153  ******************************************************************************/
154 
155 char *
156 AcpiOsGetNextFilename (
157     void                    *DirHandle)
158 {
159     EXTERNAL_FIND_INFO      *SearchInfo = DirHandle;
160     int                     Status;
161     char                    FileTypeNotMatched = 1;
162 
163 
164     /*
165      * Loop while we have matched files but not found any files of
166      * the requested type.
167      */
168     while (FileTypeNotMatched)
169     {
170         /* On the first call, we already have the first match */
171 
172         if (SearchInfo->State == 0)
173         {
174             /* No longer the first match */
175 
176             SearchInfo->State = 1;
177         }
178         else
179         {
180             /* Get the next match */
181 
182             Status = _findnext (SearchInfo->FindHandle, &SearchInfo->DosInfo);
183             if (Status != 0)
184             {
185                 return (NULL);
186             }
187         }
188 
189         /*
190          * Found a match, now check to make sure that the file type
191          * matches the requested file type (directory or normal file)
192          *
193          * NOTE: use of the attrib field saves us from doing a very
194          * expensive stat() on the file!
195          */
196         switch (SearchInfo->RequestedFileType)
197         {
198         case REQUEST_FILE_ONLY:
199 
200             /* Anything other than A_SUBDIR is OK */
201 
202             if (!(SearchInfo->DosInfo.attrib & _A_SUBDIR))
203             {
204                 FileTypeNotMatched = 0;
205             }
206             break;
207 
208         case REQUEST_DIR_ONLY:
209 
210             /* Must have A_SUBDIR bit set */
211 
212             if (SearchInfo->DosInfo.attrib & _A_SUBDIR)
213             {
214                 FileTypeNotMatched = 0;
215             }
216             break;
217 
218         default:
219 
220             return (NULL);
221         }
222     }
223 
224     return (SearchInfo->DosInfo.name);
225 }
226 
227 
228 /*******************************************************************************
229  *
230  * FUNCTION:    AcpiOsCloseDirectory
231  *
232  * PARAMETERS:  DirHandle           - Created via AcpiOsOpenDirectory
233  *
234  * RETURN:      None
235  *
236  * DESCRIPTION: Close the open directory and cleanup.
237  *
238  ******************************************************************************/
239 
240 void
241 AcpiOsCloseDirectory (
242     void                    *DirHandle)
243 {
244     EXTERNAL_FIND_INFO      *SearchInfo = DirHandle;
245 
246 
247     /* Close the directory and free allocations */
248 
249     _findclose (SearchInfo->FindHandle);
250     free (SearchInfo->FullWildcardSpec);
251     free (DirHandle);
252 }
253