[MKISOFS]
[reactos.git] / reactos / sdk / tools / mkisofs / schilytools / libschily / dirent.c
1 /* @(#)dirent.c 1.3 12/03/20 Copyright 2011 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)dirent.c 1.3 12/03/20 Copyright 2011 J. Schilling";
6 #endif
7 /*
8 * Copyright (c) 2011 J. Schilling
9 */
10 /*
11 * The contents of this file are subject to the terms of the
12 * Common Development and Distribution License, Version 1.0 only
13 * (the "License"). You may not use this file except in compliance
14 * with the License.
15 *
16 * See the file CDDL.Schily.txt in this distribution for details.
17 *
18 * When distributing Covered Code, include this CDDL HEADER in each
19 * file and include the License file CDDL.Schily.txt from this distribution.
20 */
21
22 #include <schily/dirent.h>
23 #include <schily/maxpath.h>
24 #include <schily/string.h>
25 #include <schily/errno.h>
26
27 #ifdef NEED_READDIR
28
29 #if defined(__MINGW32__) || defined(_MSC_VER)
30
31 #include <schily/windows.h>
32 #include <schily/utypes.h>
33 #include <schily/schily.h>
34
35 EXPORT DIR *opendir __PR((const char *));
36 EXPORT int closedir __PR((DIR *));
37 EXPORT struct dirent *readdir __PR((DIR *));
38
39 EXPORT DIR *
40 opendir(dname)
41 const char *dname;
42 {
43 char path[PATH_MAX];
44 size_t len;
45 uint32_t attr;
46 DIR *dp;
47
48 if (dname == NULL) {
49 seterrno(EFAULT);
50 return ((DIR *)0);
51 }
52 len = strlen(dname);
53 if (len > PATH_MAX) {
54 seterrno(ENAMETOOLONG);
55 return ((DIR *)0);
56 }
57 if (len == 0) {
58 seterrno(ENOENT);
59 return ((DIR *)0);
60 }
61
62 attr = GetFileAttributes(dname);
63 if (attr == INVALID_FILE_ATTRIBUTES ||
64 (attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
65 seterrno(ENOTDIR);
66 return ((DIR *)0);
67 }
68 path[0] = '\0';
69 _fullpath(path, dname, PATH_MAX);
70 len = strlen(path);
71 if (len == 0) {
72 seterrno(ENOENT);
73 return ((DIR *)0);
74 }
75
76 dp = malloc(sizeof (*dp) + len + 2); /* Add 2 for "/ *" */
77 if (dp == NULL) {
78 seterrno(ENOMEM);
79 return ((DIR *)0);
80 }
81 strcpy(dp->dd_dirname, path);
82 if (dp->dd_dirname[len-1] != '/' &&
83 dp->dd_dirname[len-1] != '\\') {
84 dp->dd_dirname[len] = '\\';
85 len++;
86 }
87 dp->dd_dirname[len] = '*';
88 dp->dd_handle = -1;
89 dp->dd_state = 0;
90
91 dp->dd_dir.d_ino = 0;
92 dp->dd_dir.d_reclen = 0;
93 dp->dd_dir.d_namlen = 0;
94 zerobytes(dp->dd_dir.d_name, sizeof (dp->dd_dir.d_name));
95
96 return (dp);
97 }
98
99 EXPORT int
100 closedir(dp)
101 DIR *dp;
102 {
103 int ret = 0;
104
105 if (dp == NULL) {
106 seterrno(EFAULT);
107 return (-1);
108 }
109 if (dp->dd_handle != -1) {
110 ret = _findclose(dp->dd_handle);
111 }
112 free(dp);
113
114 return (ret);
115 }
116
117 EXPORT struct dirent *
118 readdir(dp)
119 DIR *dp;
120 {
121 if (dp == NULL) {
122 seterrno(EFAULT);
123 return ((struct dirent *)0);
124 }
125 if (dp->dd_state == (char)-1) {
126 return ((struct dirent *)0);
127 } else if (dp->dd_state == (char)0) {
128 dp->dd_handle = _findfirst(dp->dd_dirname, &(dp->dd_data));
129 if (dp->dd_handle != -1)
130 dp->dd_state = 1;
131 else
132 dp->dd_state = -1;
133 } else {
134 if (_findnext(dp->dd_handle, &(dp->dd_data))) {
135 uint32_t werrno = GetLastError();
136
137 if (werrno == ERROR_NO_MORE_FILES)
138 seterrno(0);
139 _findclose(dp->dd_handle);
140 dp->dd_handle = -1;
141 dp->dd_state = -1;
142 } else {
143 dp->dd_state = 1; /* state++ to support seekdir */
144 }
145 }
146 if (dp->dd_state > 0) {
147 strlcpy(dp->dd_dir.d_name, dp->dd_data.name,
148 sizeof (dp->dd_dir.d_name));
149
150 return (&dp->dd_dir);
151 }
152 return ((struct dirent *)0);
153 }
154
155 #endif /* defined(__MINGW32__) || defined(_MSC_VER) */
156
157 #endif /* NEED_READDIR */