1 /* msd_dir.c - portable directory routines
2 Copyright (C) 1990 by Thorsten Ohl, td12@ddagsi3.bitnet
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details. */
13
14 /* Everything non trivial in this code is from: @(#)msd_dir.c 1.4
15 87/11/06. A public domain implementation of BSD directory routines
16 for MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield),
17 August 1897 */
18
19
20 #include <io.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26
27 #include <dos.h>
28
29 #include <ndir.h>
30
31 static void free_dircontents (struct _dircontents *);
32
33 /* find ALL files! */
34 #define ATTRIBUTES (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_SUBDIR)
35
36
37
38 DIR *
opendir(const char * name)39 opendir (const char *name)
40 {
41 struct _finddata_t find_buf;
42 DIR *dirp;
43 struct _dircontents *dp;
44 char name_buf[_MAX_PATH + 1];
45 char *slash = "";
46 long hFile;
47
48 if (!name)
49 name = "";
50 else if (*name)
51 {
52 const char *s;
53 int l = strlen (name);
54
55 s = name + l - 1;
56 if ( !(l == 2 && *s == ':') && *s != '\\' && *s != '/')
57 slash = "/"; /* save to insert slash between path and "*.*" */
58 }
59
60 strcat (strcat (strcpy (name_buf, name), slash), "*.*");
61
62 dirp = (DIR *) malloc (sizeof (DIR));
63 if (dirp == (DIR *)0)
64 return (DIR *)0;
65
66 dirp->dd_loc = 0;
67 dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) 0;
68
69 if ((hFile = _findfirst (name_buf, &find_buf)) < 0)
70 {
71 free (dirp);
72 return (DIR *)0;
73 }
74
75 do
76 {
77 dp = (struct _dircontents *) malloc (sizeof (struct _dircontents));
78 if (dp == (struct _dircontents *)0)
79 {
80 free_dircontents (dirp->dd_contents);
81 return (DIR *)0;
82 }
83
84 dp->_d_entry = malloc (strlen (find_buf.name) + 1);
85 if (dp->_d_entry == (char *)0)
86 {
87 free (dp);
88 free_dircontents (dirp->dd_contents);
89 return (DIR *)0;
90 }
91
92 if (dirp->dd_contents)
93 dirp->dd_cp = dirp->dd_cp->_d_next = dp;
94 else
95 dirp->dd_contents = dirp->dd_cp = dp;
96
97 strcpy (dp->_d_entry, find_buf.name);
98
99 dp->_d_next = (struct _dircontents *)0;
100
101 } while (!_findnext (hFile, &find_buf));
102
103 dirp->dd_cp = dirp->dd_contents;
104
105 _findclose(hFile);
106
107 return dirp;
108 }
109
110
111 void
closedir(DIR * dirp)112 closedir (DIR *dirp)
113 {
114 free_dircontents (dirp->dd_contents);
115 free ((char *) dirp);
116 }
117
118
119 struct direct *
readdir(DIR * dirp)120 readdir (DIR *dirp)
121 {
122 static struct direct dp;
123
124 if (dirp->dd_cp == (struct _dircontents *)0)
125 return (struct direct *)0;
126 dp.d_namlen = dp.d_reclen =
127 strlen (strcpy (dp.d_name, dirp->dd_cp->_d_entry));
128 #if 0 /* JB */
129 strlwr (dp.d_name); /* JF */
130 #endif
131 dp.d_ino = 0;
132 dirp->dd_cp = dirp->dd_cp->_d_next;
133 dirp->dd_loc++;
134
135 return &dp;
136 }
137
138
139 void
seekdir(DIR * dirp,long off)140 seekdir (DIR *dirp, long off)
141 {
142 long i = off;
143 struct _dircontents *dp;
144
145 if (off < 0)
146 return;
147 for (dp = dirp->dd_contents; --i >= 0 && dp; dp = dp->_d_next)
148 ;
149 dirp->dd_loc = off - (i + 1);
150 dirp->dd_cp = dp;
151 }
152
153
154 long
telldir(DIR * dirp)155 telldir (DIR *dirp)
156 {
157 return dirp->dd_loc;
158 }
159
160
161 /* Garbage collection */
162
163 static void
free_dircontents(struct _dircontents * dp)164 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 dp = (odp = dp)->_d_next;
173 free (odp);
174 }
175 }
176
177
178 #ifdef TEST
179
180 void main (int argc, char *argv[]);
181
182 void
main(int argc,char * argv[])183 main (int argc, char *argv[])
184 {
185 static DIR *directory;
186 struct direct *entry = (struct direct *)0;
187
188 char *name = "";
189
190 if (argc > 1)
191 name = argv[1];
192
193 directory = opendir (name);
194
195 if (!directory)
196 {
197 fprintf (stderr, "can't open directory `%s'.\n", name);
198 exit (2);
199 }
200
201 while (entry = readdir (directory))
202 printf ("> %s\n", entry->d_name);
203
204 printf ("done.\n");
205 }
206
207 #endif /* TEST */
208
209 /*
210 * Local Variables:
211 * mode:C
212 * ChangeLog:ChangeLog
213 * compile-command:make
214 * End:
215 */
216