1 /* ====================================================================
2 * The Apache Software License, Version 1.1
3 *
4 * Copyright (c) 2000 The Apache Software Foundation. All rights
5 * reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. The end-user documentation included with the redistribution,
20 * if any, must include the following acknowledgment:
21 * "This product includes software developed by the
22 * Apache Software Foundation (http://www.apache.org/)."
23 * Alternately, this acknowledgment may appear in the software itself,
24 * if and wherever such third-party acknowledgments normally appear.
25 *
26 * 4. The names "Apache" and "Apache Software Foundation" must
27 * not be used to endorse or promote products derived from this
28 * software without prior written permission. For written
29 * permission, please contact apache@apache.org.
30 *
31 * 5. Products derived from this software may not be called "Apache",
32 * nor may "Apache" appear in their name, without prior written
33 * permission of the Apache Software Foundation.
34 *
35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 * SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This software consists of voluntary contributions made by many
50 * individuals on behalf of the Apache Software Foundation. For more
51 * information on the Apache Software Foundation, please see
52 * <http://www.apache.org/>.
53 *
54 * Portions of this software are based upon public domain software
55 * originally written at the National Center for Supercomputing Applications,
56 * University of Illinois, Urbana-Champaign.
57 */
58
59 #ifdef WIN32
60
61 #include <malloc.h>
62 #include <string.h>
63 #include <errno.h>
64
65 #include "readdir.h"
66
67 /**********************************************************************
68 * Implement dirent-style opendir/readdir/closedir on Window 95/NT
69 *
70 * Functions defined are opendir(), readdir() and closedir() with the
71 * same prototypes as the normal dirent.h implementation.
72 *
73 * Does not implement telldir(), seekdir(), rewinddir() or scandir().
74 * The dirent struct is compatible with Unix, except that d_ino is
75 * always 1 and d_off is made up as we go along.
76 *
77 * The DIR typedef is not compatible with Unix.
78 **********************************************************************/
79
opendir(const char * dir)80 DIR * opendir(const char *dir)
81 {
82 DIR *dp;
83 char *filespec;
84 long handle;
85 int index;
86
87 filespec = malloc(strlen(dir) + 2 + 1);
88 strcpy(filespec, dir);
89 index = strlen(filespec) - 1;
90 if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
91 filespec[index] = '\0';
92 strcat(filespec, "/*");
93
94 dp = (DIR *)malloc(sizeof(DIR));
95 dp->offset = 0;
96 dp->finished = 0;
97 dp->dir = strdup(dir);
98
99 if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) {
100 if (errno == ENOENT)
101 dp->finished = 1;
102 else
103 return NULL;
104 }
105
106 dp->handle = handle;
107 free(filespec);
108
109 return dp;
110 }
111
readdir(DIR * dp)112 struct dirent * readdir(DIR *dp)
113 {
114 if (!dp || dp->finished) return NULL;
115
116 if (dp->offset != 0) {
117 if (_findnext(dp->handle, &(dp->fileinfo)) < 0) {
118 dp->finished = 1;
119 return NULL;
120 }
121 }
122 dp->offset++;
123
124 strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME);
125 dp->dent.d_ino = 1;
126 dp->dent.d_reclen = (unsigned short)strlen(dp->dent.d_name);
127 dp->dent.d_off = dp->offset;
128
129 return &(dp->dent);
130 }
131
closedir(DIR * dp)132 int closedir(DIR *dp)
133 {
134 if (!dp) return 0;
135 _findclose(dp->handle);
136 if (dp->dir) free(dp->dir);
137 if (dp) free(dp);
138
139 return 0;
140 }
141
142 #endif /* WIN32 */
143