Resolve warnings on Windows
[heimdal.git] / lib / roken / dirent.c
bloba0301e20730723073592e48af53ddaf4b1942b57
1 /***********************************************************************
2 * Copyright (c) 2009, Secure Endpoints Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 **********************************************************************/
32 #ifdef HAVE_CONFIG_H
33 #include<config.h>
34 #endif
36 #include <stdlib.h>
37 #include <io.h>
38 #include <string.h>
39 #include <errno.h>
40 #include "dirent.h"
42 #ifndef _WIN32
43 #error Only implemented for Win32
44 #endif
46 struct _dirent_dirinfo {
47 int magic;
48 long n_entries;
49 long nc_entries;
50 long cursor;
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
58 ROKEN_LIB_FUNCTION DIR * ROKEN_LIB_CALL
59 opendir(const char * filespec)
61 DIR * dp;
62 struct _finddata_t fd;
63 intptr_t fd_handle;
65 memset(&fd, 0, sizeof(fd));
67 fd_handle = _findfirst(filespec, &fd);
69 if (fd_handle == -1)
70 return NULL;
72 dp = malloc(sizeof(*dp));
73 if (dp == NULL)
74 goto done;
76 memset(dp, 0, sizeof(*dp));
77 dp->magic = DIRINFO_MAGIC;
78 dp->cursor = 0;
79 dp->n_entries = 0;
80 dp->nc_entries = INITIAL_ENTRIES;
81 dp->entries = calloc(dp->nc_entries, sizeof(dp->entries[0]));
83 if (dp->entries == NULL) {
84 closedir(dp);
85 dp = NULL;
86 goto done;
89 do {
90 size_t len = strlen(fd.name);
91 struct dirent * e;
93 if (dp->n_entries == dp->nc_entries) {
94 struct dirent ** ne;
96 dp->nc_entries *= 2;
97 ne = realloc(dp->entries, sizeof(dp->entries[0]) * dp->nc_entries);
99 if (ne == NULL) {
100 closedir(dp);
101 dp = NULL;
102 goto done;
105 dp->entries = ne;
108 e = malloc(sizeof(*e) + len * sizeof(char));
109 if (e == NULL) {
110 closedir(dp);
111 dp = NULL;
112 goto done;
115 e->d_ino = 0; /* no inodes :( */
116 strcpy_s(e->d_name, len + 1, fd.name);
118 dp->entries[dp->n_entries++] = e;
120 } while (_findnext(fd_handle, &fd) == 0);
122 done:
123 if (fd_handle != -1)
124 _findclose(fd_handle);
126 return dp;
129 ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
130 closedir(DIR * dp)
132 if (!IS_DP(dp))
133 return EINVAL;
135 if (dp->entries) {
136 long i;
138 for (i=0; i < dp->n_entries; i++) {
139 free(dp->entries[i]);
142 free(dp->entries);
145 free(dp);
147 return 0;
150 ROKEN_LIB_FUNCTION struct dirent * ROKEN_LIB_CALL
151 readdir(DIR * dp)
153 if (!IS_DP(dp) ||
154 dp->cursor < 0 ||
155 dp->cursor >= dp->n_entries)
157 return NULL;
159 return dp->entries[dp->cursor++];
162 ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
163 rewinddir(DIR * dp)
165 if (IS_DP(dp))
166 dp->cursor = 0;
169 ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
170 seekdir(DIR * dp, long offset)
172 if (IS_DP(dp) && offset >= 0 && offset < dp->n_entries)
173 dp->cursor = offset;
176 ROKEN_LIB_FUNCTION long ROKEN_LIB_CALL
177 telldir(DIR * dp)
179 return dp->cursor;