1 /*
2 * Author: Bob Withers
3 * Copyright (c) 1993, All Rights Reserved
4 *
5 * NOTICE
6 *
7 * Permission to use, copy, modify, and distribute this software and
8 * its documentation for any purpose and without fee is hereby granted
9 * provided that the above copyright notice appears in all copies and
10 * that both the copyright notice and this permission notice appear in
11 * supporting documentation.
12 *
13 * The author makes no representations about the suitability of this
14 * software for any purpose. This software is provided ``as is''
15 * without express or implied warranty.
16 */
17
18 #include <stdlib.h>
19 #include <string.h>
20
21 #define INCL_DOSFILEMGR
22 #define INCL_DOSERRORS
23 #include <os2.h>
24
25 #include "dirent.h"
26
27
28 #define DIRENT_INCR 25
29
30
opendir(char * filename)31 DIR *opendir(char *filename)
32 {
33 auto size_t len;
34 auto DIR *dirp;
35 auto char *p;
36 auto HDIR hdir;
37
38 #ifdef OS2_16
39 auto USHORT rc; /* for 16 bit OS/2 */
40 auto FILEFINDBUF ff;
41 auto USHORT cnt;
42 #else
43 auto APIRET rc; /* for 32 bit OS/2 */
44 auto FILEFINDBUF3 ff;
45 auto ULONG cnt;
46 #endif /* OS2_16 */
47
48 if (NULL == filename || '\0' == filename[0])
49 filename = ".";
50
51 dirp = malloc(sizeof(*dirp));
52 if (NULL == dirp)
53 return(NULL);
54
55 len = strlen(filename);
56 dirp->dirname = malloc(len + 5);
57 if (NULL == dirp->dirname)
58 {
59 free(dirp);
60 return(NULL);
61 }
62
63 dirp->max_ent = 0;
64 dirp->tot_ent = 0;
65 dirp->cur_ent = 0;
66 dirp->entp = NULL;
67 strcpy(dirp->dirname, filename);
68 for (p = dirp->dirname; *p; ++p)
69 {
70 if ('/' == *p)
71 *p = '\\';
72 }
73
74 if ('\\' != dirp->dirname[len - 1])
75 strcat(dirp->dirname, "\\");
76
77 strcat(dirp->dirname, "*.*");
78
79 hdir = HDIR_SYSTEM;
80 cnt = 1;
81 rc = DosFindFirst(dirp->dirname, &hdir,
82 FILE_NORMAL | FILE_READONLY | FILE_HIDDEN |
83 FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED,
84 &ff, sizeof(ff), &cnt, FIL_STANDARD);
85
86 while (NO_ERROR == rc)
87 {
88 auto struct dirent *entp;
89
90 if (dirp->tot_ent >= dirp->max_ent)
91 {
92 auto struct dirent **p;
93
94 dirp->max_ent += DIRENT_INCR;
95 p = realloc(dirp->entp, dirp->max_ent * sizeof(entp));
96 if (NULL == p)
97 {
98 rc = ERROR_NOT_ENOUGH_MEMORY;
99 break;
100 }
101
102 dirp->entp = p;
103 }
104
105 entp = malloc(sizeof(*entp) + (size_t) ff.cchName);
106 if (NULL == entp)
107 {
108 rc = ERROR_NOT_ENOUGH_MEMORY;
109 break;
110 }
111
112 entp->d_ino = 0;
113 entp->d_off = dirp->tot_ent;
114 entp->d_namlen = (unsigned short) ff.cchName;
115 memcpy(entp->d_name, ff.achName, entp->d_namlen);
116 entp->d_name[entp->d_namlen] = '\0';
117 dirp->entp[dirp->tot_ent++] = entp;
118
119 cnt = 1;
120 rc = DosFindNext(hdir, &ff, sizeof(ff), &cnt);
121 }
122
123 DosFindClose(hdir);
124 if (ERROR_NO_MORE_FILES == rc)
125 return(dirp);
126
127 closedir(dirp);
128 return(NULL);
129 }
130
131
readdir(DIR * dirp)132 struct dirent *readdir(DIR *dirp)
133 {
134 if (dirp->cur_ent < 0 || dirp->cur_ent >= dirp->tot_ent)
135 return(NULL);
136
137 return(dirp->entp[dirp->cur_ent++]);
138 }
139
140
telldir(DIR * dirp)141 long telldir(DIR *dirp)
142 {
143 return((long) dirp->cur_ent);
144 }
145
146
seekdir(DIR * dirp,long loc)147 void seekdir(DIR *dirp, long loc)
148 {
149 dirp->cur_ent = (int) loc;
150 return;
151 }
152
153
rewinddir(DIR * dirp)154 void rewinddir(DIR *dirp)
155 {
156 dirp->cur_ent = 0;
157 return;
158 }
159
160
closedir(DIR * dirp)161 void closedir(DIR *dirp)
162 {
163 if (dirp)
164 {
165 if (dirp->dirname)
166 free(dirp->dirname);
167
168 if (dirp->entp)
169 {
170 register int i;
171
172 for (i = 0; i < dirp->tot_ent; ++i)
173 free(dirp->entp[i]);
174
175 free(dirp->entp);
176 }
177 }
178
179 return;
180 }
181