Commit | Line | Data |
39c3038c |
1 | /* |
2 | * @(#)dir.c 1.4 87/11/06 Public Domain. |
3 | * |
4 | * A public domain implementation of BSD directory routines for |
5 | * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), |
6 | * August 1897 |
7 | * Ported to OS/2 by Kai Uwe Rommel |
8 | * December 1989 |
9 | */ |
10 | |
11 | #include <sys/types.h> |
12 | #include <sys/stat.h> |
13 | #include <sys/dir.h> |
14 | |
15 | #include <stdio.h> |
16 | #include <malloc.h> |
17 | #include <string.h> |
18 | |
19 | #define INCL_NOPM |
20 | #include <os2.h> |
21 | |
22 | |
23 | int attributes = A_DIR | A_HIDDEN; |
24 | |
25 | |
26 | static char *getdirent(char *); |
27 | static void free_dircontents(struct _dircontents *); |
28 | |
29 | static HDIR hdir; |
30 | static USHORT count; |
31 | static FILEFINDBUF find; |
32 | |
33 | |
34 | DIR *opendir(char *name) |
35 | { |
36 | struct stat statb; |
37 | DIR *dirp; |
38 | char c; |
39 | char *s; |
40 | struct _dircontents *dp; |
41 | char nbuf[MAXPATHLEN + 1]; |
42 | |
43 | strcpy(nbuf, name); |
44 | |
45 | if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') && |
46 | (strlen(nbuf) > 1) ) |
47 | { |
48 | nbuf[strlen(nbuf) - 1] = 0; |
49 | |
50 | if ( nbuf[strlen(nbuf) - 1] == ':' ) |
51 | strcat(nbuf, "\\."); |
52 | } |
53 | else |
54 | if ( nbuf[strlen(nbuf) - 1] == ':' ) |
55 | strcat(nbuf, "."); |
56 | |
57 | if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR) |
58 | return NULL; |
59 | |
60 | if ( (dirp = malloc(sizeof(DIR))) == NULL ) |
61 | return NULL; |
62 | |
63 | if ( nbuf[strlen(nbuf) - 1] == '.' ) |
64 | strcpy(nbuf + strlen(nbuf) - 1, "*.*"); |
65 | else |
66 | if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') && |
67 | (strlen(nbuf) == 1) ) |
68 | strcat(nbuf, "*.*"); |
69 | else |
70 | strcat(nbuf, "\\*.*"); |
71 | |
72 | dirp -> dd_loc = 0; |
73 | dirp -> dd_contents = dirp -> dd_cp = NULL; |
74 | |
75 | if ((s = getdirent(nbuf)) == NULL) |
76 | return dirp; |
77 | |
78 | do |
79 | { |
80 | if (((dp = malloc(sizeof(struct _dircontents))) == NULL) || |
81 | ((dp -> _d_entry = malloc(strlen(s) + 1)) == NULL) ) |
82 | { |
83 | if (dp) |
84 | free(dp); |
85 | free_dircontents(dirp -> dd_contents); |
86 | |
87 | return NULL; |
88 | } |
89 | |
90 | if (dirp -> dd_contents) |
91 | dirp -> dd_cp = dirp -> dd_cp -> _d_next = dp; |
92 | else |
93 | dirp -> dd_contents = dirp -> dd_cp = dp; |
94 | |
95 | strcpy(dp -> _d_entry, s); |
96 | dp -> _d_next = NULL; |
97 | |
98 | dp -> _d_size = find.cbFile; |
99 | dp -> _d_mode = find.attrFile; |
100 | dp -> _d_time = *(unsigned *) &(find.ftimeLastWrite); |
101 | dp -> _d_date = *(unsigned *) &(find.fdateLastWrite); |
102 | } |
103 | while ((s = getdirent(NULL)) != NULL); |
104 | |
105 | dirp -> dd_cp = dirp -> dd_contents; |
106 | |
107 | return dirp; |
108 | } |
109 | |
110 | |
111 | void closedir(DIR * dirp) |
112 | { |
113 | free_dircontents(dirp -> dd_contents); |
114 | free(dirp); |
115 | } |
116 | |
117 | |
118 | struct direct *readdir(DIR * dirp) |
119 | { |
120 | static struct direct dp; |
121 | |
122 | if (dirp -> dd_cp == NULL) |
123 | return NULL; |
124 | |
125 | dp.d_namlen = dp.d_reclen = |
126 | strlen(strcpy(dp.d_name, dirp -> dd_cp -> _d_entry)); |
127 | |
128 | strlwr(dp.d_name); /* JF */ |
129 | dp.d_ino = 0; |
130 | |
131 | dp.d_size = dirp -> dd_cp -> _d_size; |
132 | dp.d_mode = dirp -> dd_cp -> _d_mode; |
133 | dp.d_time = dirp -> dd_cp -> _d_time; |
134 | dp.d_date = dirp -> dd_cp -> _d_date; |
135 | |
136 | dirp -> dd_cp = dirp -> dd_cp -> _d_next; |
137 | dirp -> dd_loc++; |
138 | |
139 | return &dp; |
140 | } |
141 | |
142 | |
143 | void seekdir(DIR * dirp, long off) |
144 | { |
145 | long i = off; |
146 | struct _dircontents *dp; |
147 | |
148 | if (off >= 0) |
149 | { |
150 | for (dp = dirp -> dd_contents; --i >= 0 && dp; dp = dp -> _d_next); |
151 | |
152 | dirp -> dd_loc = off - (i + 1); |
153 | dirp -> dd_cp = dp; |
154 | } |
155 | } |
156 | |
157 | |
158 | long telldir(DIR * dirp) |
159 | { |
160 | return dirp -> dd_loc; |
161 | } |
162 | |
163 | |
164 | static void free_dircontents(struct _dircontents * dp) |
165 | { |
166 | struct _dircontents *odp; |
167 | |
168 | while (dp) |
169 | { |
170 | if (dp -> _d_entry) |
171 | free(dp -> _d_entry); |
172 | |
173 | dp = (odp = dp) -> _d_next; |
174 | free(odp); |
175 | } |
176 | } |
177 | |
178 | |
179 | static char *getdirent(char *dir) |
180 | { |
181 | int done; |
182 | |
183 | if (dir != NULL) |
184 | { /* get first entry */ |
185 | hdir = HDIR_CREATE; |
186 | count = 1; |
187 | done = DosFindFirst(dir, &hdir, attributes, |
188 | &find, sizeof(find), &count, 0L); |
189 | } |
190 | else /* get next entry */ |
191 | done = DosFindNext(hdir, &find, sizeof(find), &count); |
192 | |
193 | if (done == 0) |
194 | return find.achName; |
195 | else |
196 | { |
197 | DosFindClose(hdir); |
198 | return NULL; |
199 | } |
200 | } |