xref: /openbsd-src/gnu/usr.bin/cvs/os2/dirent.c (revision 13571821e83933f3c1d7fd1ab5ff9cd54f0eea7f)
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