]> Dogcows Code - chaz/tar/blob - src/msd_dir.c
*** empty log message ***
[chaz/tar] / src / msd_dir.c
1 /*
2 * @(#)msd_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 */
8
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include "msd_dir.h"
12 #ifndef __TURBOC__
13 #include <malloc.h>
14 #else
15 #include <stdlib.h>
16 #endif
17 #include <string.h>
18 #include <dos.h>
19
20 #ifndef NULL
21 # define NULL 0
22 #endif /* NULL */
23
24 #ifndef MAXPATHLEN
25 # define MAXPATHLEN 255
26 #endif /* MAXPATHLEN */
27
28 /* attribute stuff */
29 #define A_RONLY 0x01
30 #define A_HIDDEN 0x02
31 #define A_SYSTEM 0x04
32 #define A_LABEL 0x08
33 #define A_DIR 0x10
34 #define A_ARCHIVE 0x20
35
36 /* dos call values */
37 #define DOSI_FINDF 0x4e
38 #define DOSI_FINDN 0x4f
39 #define DOSI_SDTA 0x1a
40
41 #define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
42 /* #define ATTRIBUTES (A_DIR | A_HIDDEN | A_SYSTEM) */
43 #define ATTRIBUTES (A_RONLY | A_SYSTEM | A_DIR)
44
45 /* what find first/next calls look use */
46 typedef struct
47 {
48 char d_buf[21];
49 char d_attribute;
50 unsigned short d_time;
51 unsigned short d_date;
52 long d_size;
53 char d_name[13];
54 }
55
56 Dta_buf;
57
58 static char *getdirent ();
59 static void mysetdta ();
60 static void free_dircontents ();
61
62 static Dta_buf dtabuf;
63 static Dta_buf *dtapnt = &dtabuf;
64 static union REGS reg, nreg;
65
66 #if defined(M_I86LM)
67 static struct SREGS sreg;
68 #endif
69
70 DIR *
71 opendir (name)
72 char *name;
73 {
74 struct stat statb;
75 DIR *dirp;
76 char c;
77 char *s;
78 struct _dircontents *dp;
79 char nbuf[MAXPATHLEN + 1];
80
81 if (stat (name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
82 return (DIR *) NULL;
83 if (Newisnull (dirp, DIR))
84 return (DIR *) NULL;
85 if (*name && (c = name[strlen (name) - 1]) != '\\' && c != '/')
86 (void) strcat (strcpy (nbuf, name), "\\*.*");
87 else
88 (void) strcat (strcpy (nbuf, name), "*.*");
89 dirp->dd_loc = 0;
90 mysetdta ();
91 dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
92 if ((s = getdirent (nbuf)) == (char *) NULL)
93 return dirp;
94 do
95 {
96 if (Newisnull (dp, struct _dircontents) || (dp->_d_entry =
97 malloc ((unsigned) (strlen (s) + 1))) == (char *) NULL)
98 {
99 if (dp)
100 free ((char *) dp);
101 free_dircontents (dirp->dd_contents);
102 return (DIR *) NULL;
103 }
104 if (dirp->dd_contents)
105 dirp->dd_cp = dirp->dd_cp->_d_next = dp;
106 else
107 dirp->dd_contents = dirp->dd_cp = dp;
108 (void) strcpy (dp->_d_entry, s);
109 dp->_d_next = (struct _dircontents *) NULL;
110 }
111 while ((s = getdirent ((char *) NULL)) != (char *) NULL);
112 dirp->dd_cp = dirp->dd_contents;
113
114 return dirp;
115 }
116
117 void
118 closedir (dirp)
119 DIR *dirp;
120 {
121 free_dircontents (dirp->dd_contents);
122 free ((char *) dirp);
123 }
124
125 struct dirent *
126 readdir (dirp)
127 DIR *dirp;
128 {
129 static struct dirent dp;
130
131 if (dirp->dd_cp == (struct _dircontents *) NULL)
132 return (struct dirent *) NULL;
133 dp.d_namlen = dp.d_reclen =
134 strlen (strcpy (dp.d_name, dirp->dd_cp->_d_entry));
135 strlwr (dp.d_name); /* JF */
136 dp.d_ino = 0;
137 dirp->dd_cp = dirp->dd_cp->_d_next;
138 dirp->dd_loc++;
139
140 return &dp;
141 }
142
143 void
144 seekdir (dirp, off)
145 DIR *dirp;
146 long off;
147 {
148 long i = off;
149 struct _dircontents *dp;
150
151 if (off < 0)
152 return;
153 for (dp = dirp->dd_contents; --i >= 0 && dp; dp = dp->_d_next)
154 ;
155 dirp->dd_loc = off - (i + 1);
156 dirp->dd_cp = dp;
157 }
158
159 long
160 telldir (dirp)
161 DIR *dirp;
162 {
163 return dirp->dd_loc;
164 }
165
166 static void
167 free_dircontents (dp)
168 struct _dircontents *dp;
169 {
170 struct _dircontents *odp;
171
172 while (dp)
173 {
174 if (dp->_d_entry)
175 free (dp->_d_entry);
176 dp = (odp = dp)->_d_next;
177 free ((char *) odp);
178 }
179 }
180
181 static char *
182 getdirent (dir)
183 char *dir;
184 {
185 if (dir != (char *) NULL)
186 { /* get first entry */
187 reg.h.ah = DOSI_FINDF;
188 reg.h.cl = ATTRIBUTES;
189 #if defined(M_I86LM)
190 reg.x.dx = FP_OFF (dir);
191 sreg.ds = FP_SEG (dir);
192 #else
193 reg.x.dx = (unsigned) dir;
194 #endif
195 }
196 else
197 { /* get next entry */
198 reg.h.ah = DOSI_FINDN;
199 #if defined(M_I86LM)
200 reg.x.dx = FP_OFF (dtapnt);
201 sreg.ds = FP_SEG (dtapnt);
202 #else
203 reg.x.dx = (unsigned) dtapnt;
204 #endif
205 }
206 #if defined(M_I86LM)
207 intdosx (&reg, &nreg, &sreg);
208 #else
209 intdos (&reg, &nreg);
210 #endif
211 if (nreg.x.cflag)
212 return (char *) NULL;
213
214 return dtabuf.d_name;
215 }
216
217 static void
218 mysetdta ()
219 {
220 reg.h.ah = DOSI_SDTA;
221 #if defined(M_I86LM)
222 reg.x.dx = FP_OFF (dtapnt);
223 sreg.ds = FP_SEG (dtapnt);
224 intdosx (&reg, &nreg, &sreg);
225 #else
226 reg.x.dx = (int) dtapnt;
227 intdos (&reg, &nreg);
228 #endif
229 }
This page took 0.040584 seconds and 4 git commands to generate.