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