1 /* $NetBSD: dirent.c,v 1.1.1.2 2014/04/24 12:45:52 pettai Exp $ */
3 /***********************************************************************
4 * Copyright (c) 2009, Secure Endpoints Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * - 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
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
32 **********************************************************************/
43 #error Only implemented for Win32
46 struct _dirent_dirinfo
{
51 struct dirent
**entries
;
53 #define DIRINFO_MAGIC 0xf8c0639d
54 #define IS_DP(p) ((p) && ((DIR *)(p))->magic == DIRINFO_MAGIC)
56 #define INITIAL_ENTRIES 16
59 * Create a filespec for use with _findfirst() using a path spec
61 * If the last component of the path spec contains wildcards, we let
62 * it be. If the last component doesn't end with a slash, we add one.
65 filespec_from_dir_path(const char * path
, char * buffer
, size_t cch_buffer
)
71 if (strcpy_s(buffer
, cch_buffer
, path
) != 0)
74 comp
= strrchr(buffer
, '\\');
80 t
= strrchr(comp
, '/');
89 pos
= strcspn(comp
, "*?");
90 if (comp
[pos
] != '\0')
93 /* We don't append a slash if pos == 0 because that changes the
96 * "*.*" is all files in the current directory.
97 * "\*.*" is all files in the root directory of the current drive.
99 if (pos
> 0 && comp
[pos
- 1] != '\\' &&
100 comp
[pos
- 1] != '/') {
101 strcat_s(comp
, cch_buffer
- (comp
- buffer
), "\\");
104 strcat_s(comp
, cch_buffer
- (comp
- buffer
), "*.*");
109 ROKEN_LIB_FUNCTION
DIR * ROKEN_LIB_CALL
110 opendir(const char * path
)
113 struct _finddata_t fd
;
115 const char *filespec
;
116 char path_buffer
[1024];
118 memset(&fd
, 0, sizeof(fd
));
120 filespec
= filespec_from_dir_path(path
, path_buffer
, sizeof(path_buffer
)/sizeof(char));
121 if (filespec
== NULL
)
124 fd_handle
= _findfirst(filespec
, &fd
);
129 dp
= malloc(sizeof(*dp
));
133 memset(dp
, 0, sizeof(*dp
));
134 dp
->magic
= DIRINFO_MAGIC
;
137 dp
->nc_entries
= INITIAL_ENTRIES
;
138 dp
->entries
= calloc(dp
->nc_entries
, sizeof(dp
->entries
[0]));
140 if (dp
->entries
== NULL
) {
147 size_t len
= strlen(fd
.name
);
150 if (dp
->n_entries
== dp
->nc_entries
) {
154 ne
= realloc(dp
->entries
, sizeof(dp
->entries
[0]) * dp
->nc_entries
);
165 e
= malloc(sizeof(*e
) + len
* sizeof(char));
172 e
->d_ino
= 0; /* no inodes :( */
173 strcpy_s(e
->d_name
, len
+ 1, fd
.name
);
175 dp
->entries
[dp
->n_entries
++] = e
;
177 } while (_findnext(fd_handle
, &fd
) == 0);
181 _findclose(fd_handle
);
186 ROKEN_LIB_FUNCTION
int ROKEN_LIB_CALL
195 for (i
=0; i
< dp
->n_entries
; i
++) {
196 free(dp
->entries
[i
]);
207 ROKEN_LIB_FUNCTION
struct dirent
* ROKEN_LIB_CALL
212 dp
->cursor
>= dp
->n_entries
)
216 return dp
->entries
[dp
->cursor
++];
219 ROKEN_LIB_FUNCTION
void ROKEN_LIB_CALL
226 ROKEN_LIB_FUNCTION
void ROKEN_LIB_CALL
227 seekdir(DIR * dp
, long offset
)
229 if (IS_DP(dp
) && offset
>= 0 && offset
< dp
->n_entries
)
233 ROKEN_LIB_FUNCTION
long ROKEN_LIB_CALL