]> 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 char d_buf[21];
48 char d_attribute;
49 unsigned short d_time;
50 unsigned short d_date;
51 long d_size;
52 char d_name[13];
53 } Dta_buf;
54
55 static char *getdirent();
56 static void mysetdta();
57 static void free_dircontents();
58
59 static Dta_buf dtabuf;
60 static Dta_buf *dtapnt = &dtabuf;
61 static union REGS reg, nreg;
62
63 #if defined(M_I86LM)
64 static struct SREGS sreg;
65 #endif
66
67 DIR *
68 opendir(name)
69 char *name;
70 {
71 struct stat statb;
72 DIR *dirp;
73 char c;
74 char *s;
75 struct _dircontents *dp;
76 char nbuf[MAXPATHLEN + 1];
77
78 if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
79 return (DIR *) NULL;
80 if (Newisnull(dirp, DIR))
81 return (DIR *) NULL;
82 if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
83 (void) strcat(strcpy(nbuf, name), "\\*.*");
84 else
85 (void) strcat(strcpy(nbuf, name), "*.*");
86 dirp->dd_loc = 0;
87 mysetdta();
88 dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
89 if ((s = getdirent(nbuf)) == (char *) NULL)
90 return dirp;
91 do {
92 if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
93 malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
94 {
95 if (dp)
96 free((char *) dp);
97 free_dircontents(dirp->dd_contents);
98 return (DIR *) NULL;
99 }
100 if (dirp->dd_contents)
101 dirp->dd_cp = dirp->dd_cp->_d_next = dp;
102 else
103 dirp->dd_contents = dirp->dd_cp = dp;
104 (void) strcpy(dp->_d_entry, s);
105 dp->_d_next = (struct _dircontents *) NULL;
106 } while ((s = getdirent((char *) NULL)) != (char *) NULL);
107 dirp->dd_cp = dirp->dd_contents;
108
109 return dirp;
110 }
111
112 void
113 closedir(dirp)
114 DIR *dirp;
115 {
116 free_dircontents(dirp->dd_contents);
117 free((char *) dirp);
118 }
119
120 struct dirent *
121 readdir(dirp)
122 DIR *dirp;
123 {
124 static struct dirent dp;
125
126 if (dirp->dd_cp == (struct _dircontents *) NULL)
127 return (struct dirent *) NULL;
128 dp.d_namlen = dp.d_reclen =
129 strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
130 strlwr(dp.d_name); /* JF */
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 void
139 seekdir(dirp, off)
140 DIR *dirp;
141 long off;
142 {
143 long i = off;
144 struct _dircontents *dp;
145
146 if (off < 0)
147 return;
148 for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
149 ;
150 dirp->dd_loc = off - (i + 1);
151 dirp->dd_cp = dp;
152 }
153
154 long
155 telldir(dirp)
156 DIR *dirp;
157 {
158 return dirp->dd_loc;
159 }
160
161 static void
162 free_dircontents(dp)
163 struct _dircontents *dp;
164 {
165 struct _dircontents *odp;
166
167 while (dp) {
168 if (dp->_d_entry)
169 free(dp->_d_entry);
170 dp = (odp = dp)->_d_next;
171 free((char *) odp);
172 }
173 }
174
175 static char *
176 getdirent(dir)
177 char *dir;
178 {
179 if (dir != (char *) NULL) { /* get first entry */
180 reg.h.ah = DOSI_FINDF;
181 reg.h.cl = ATTRIBUTES;
182 #if defined(M_I86LM)
183 reg.x.dx = FP_OFF(dir);
184 sreg.ds = FP_SEG(dir);
185 #else
186 reg.x.dx = (unsigned) dir;
187 #endif
188 } else { /* get next entry */
189 reg.h.ah = DOSI_FINDN;
190 #if defined(M_I86LM)
191 reg.x.dx = FP_OFF(dtapnt);
192 sreg.ds = FP_SEG(dtapnt);
193 #else
194 reg.x.dx = (unsigned) dtapnt;
195 #endif
196 }
197 #if defined(M_I86LM)
198 intdosx(&reg, &nreg, &sreg);
199 #else
200 intdos(&reg, &nreg);
201 #endif
202 if (nreg.x.cflag)
203 return (char *) NULL;
204
205 return dtabuf.d_name;
206 }
207
208 static void
209 mysetdta()
210 {
211 reg.h.ah = DOSI_SDTA;
212 #if defined(M_I86LM)
213 reg.x.dx = FP_OFF(dtapnt);
214 sreg.ds = FP_SEG(dtapnt);
215 intdosx(&reg, &nreg, &sreg);
216 #else
217 reg.x.dx = (int) dtapnt;
218 intdos(&reg, &nreg);
219 #endif
220 }
This page took 0.043582 seconds and 4 git commands to generate.