Merge branch 'mirbsd'
[alioth/cvs.git] / windows-NT / ndir.c
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 \f
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 #include "xalloc.h"
31
32 static void free_dircontents (struct _dircontents *);
33
34 /* find ALL files! */
35 #define ATTRIBUTES      (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_SUBDIR)
36
37
38
39 DIR *
40 opendir (const char *name)
41 {
42   struct _finddata_t find_buf;
43   DIR *dirp;
44   struct _dircontents *dp;
45   char name_buf[_MAX_PATH + 1];
46   char *slash = "";
47   long hFile;
48
49   if (!name)
50     name = "";
51   else if (*name)
52     {
53       const char *s;
54       int l = strlen (name);
55
56       s = name + l - 1;
57       if ( !(l == 2 && *s == ':') && *s != '\\' && *s != '/')
58         slash = "/";    /* save to insert slash between path and "*.*" */
59     }
60
61   strcat (strcat (strcpy (name_buf, name), slash), "*.*");
62
63   dirp = xmalloc (sizeof (DIR));
64   if (!dirp) return NULL;
65
66   dirp->dd_loc = 0;
67   dirp->dd_contents = dirp->dd_cp = NULL;
68
69   if ((hFile = _findfirst (name_buf, &find_buf)) < 0)
70     {
71       free (dirp);
72       return NULL;
73     }
74
75   do
76     {
77       dp = xmalloc (sizeof (struct _dircontents));
78       if (!dp)
79         {
80           free_dircontents (dirp->dd_contents);
81           return NULL;
82         }
83
84       dp->_d_entry = xmalloc (strlen (find_buf.name) + 1);
85       if (!dp->_d_entry)
86         {
87           free (dp);
88           free_dircontents (dirp->dd_contents);
89           return NULL;
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 = NULL;
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 (dirp);
116 }
117
118
119 struct direct *
120 readdir (DIR *dirp)
121 {
122   static struct direct dp;
123
124   if (!dirp->dd_cp) return NULL;
125   dp.d_namlen = dp.d_reclen =
126     strlen (strcpy (dp.d_name, dirp->dd_cp->_d_entry));
127 #if 0 /* JB */
128   strlwr (dp.d_name);           /* JF */
129 #endif
130   dp.d_ino = 0;
131   dirp->dd_cp = dirp->dd_cp->_d_next;
132   dirp->dd_loc++;
133
134   return &dp;
135 }
136
137
138 void
139 seekdir (DIR *dirp, long off)
140 {
141   long i = off;
142   struct _dircontents *dp;
143
144   if (off < 0)
145     return;
146   for (dp = dirp->dd_contents; --i >= 0 && dp; dp = dp->_d_next)
147     ;
148   dirp->dd_loc = off - (i + 1);
149   dirp->dd_cp = dp;
150 }
151
152
153 long
154 telldir (DIR *dirp)
155 {
156   return dirp->dd_loc;
157 }
158
159
160 /* Garbage collection */
161
162 static void
163 free_dircontents (struct _dircontents *dp)
164 {
165   struct _dircontents *odp;
166
167   while (dp)
168     {
169       if (dp->_d_entry)
170         free (dp->_d_entry);
171       dp = (odp = dp)->_d_next;
172       free (odp);
173     }
174 }
175
176
177 #ifdef TEST
178
179 void main (int argc, char *argv[]);
180
181 void
182 main (int argc, char *argv[])
183 {
184   static DIR *directory;
185   struct direct *entry = NULL;
186
187   char *name = "";
188
189   if (argc > 1)
190     name = argv[1];
191
192   directory = opendir (name);
193
194   if (!directory)
195     {
196       fprintf (stderr, "can't open directory `%s'.\n", name);
197       exit (2);
198     }
199
200   while (entry = readdir (directory))
201     printf ("> %s\n", entry->d_name);
202
203   printf ("done.\n");
204 }
205
206 #endif /* TEST */
207 \f
208 /* 
209  * Local Variables:
210  * mode:C
211  * ChangeLog:ChangeLog
212  * compile-command:make
213  * End:
214  */