1/******************************************************************************
2 *
3 * Module Name: oswindir - Windows directory access interfaces
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2016, 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
51typedef 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
77void *
78AcpiOsOpenDirectory (
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
155char *
156AcpiOsGetNextFilename (
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
240void
241AcpiOsCloseDirectory (
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