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