xref: /openbsd/gnu/usr.bin/cvs/windows-NT/ndir.c (revision 3d8817e4)
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 *
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
112 closedir (DIR *dirp)
113 {
114   free_dircontents (dirp->dd_contents);
115   free ((char *) dirp);
116 }
117 
118 
119 struct direct *
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
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
155 telldir (DIR *dirp)
156 {
157   return dirp->dd_loc;
158 }
159 
160 
161 /* Garbage collection */
162 
163 static void
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
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