Commit | Line | Data |
---|---|---|
88f62f26 KT |
1 | #include "tp.h" |
2 | #include <stdio.h> | |
3 | #include <sys/types.h> | |
4 | #include <sys/stat.h> | |
5 | #include <sys/dir.h> | |
6 | ||
7 | struct direct direct; | |
8 | struct stat statb; | |
9 | ||
10 | clrdir() | |
11 | { | |
12 | register j, *p; | |
13 | ||
14 | j = ndirent * (DIRSZ/sizeof(int)); | |
15 | p = (int *)dir; | |
16 | do (*p++ = 0); while (--j); | |
17 | lastd = 0; | |
18 | } | |
19 | ||
20 | clrent(ptr) | |
21 | struct dent *ptr; | |
22 | { | |
23 | register *p, j; | |
24 | ||
25 | p = (int *)ptr; | |
26 | j = DIRSZ/sizeof(int); | |
27 | do *p++ = 0; | |
28 | while (--j); | |
29 | if (++ptr == lastd) do { | |
30 | if (--lastd < dir) { | |
31 | lastd = 0; | |
32 | return; | |
33 | } | |
34 | } while (lastd->d_namep == 0); | |
35 | } | |
36 | ||
37 | ||
38 | rddir() | |
39 | { | |
40 | register struct tent *tp; | |
41 | register struct dent *p1; | |
42 | struct dent *dptr; | |
43 | struct tent *tptr; | |
44 | int count, i, sum; | |
45 | short reg, *sp; | |
46 | ||
47 | sum = 0; | |
48 | clrdir(); | |
49 | rseek(0); | |
50 | tread(); /* Read the bootstrap block */ | |
51 | if ((tpentry[TPB-1].cksum != 0) && (flags & flm)) { | |
52 | ndirent = tpentry[TPB-1].cksum; | |
53 | if(flags & fls) swab((char *)&ndirent, (char *)&ndirent, sizeof(ndirent)); | |
54 | if(ndirent < 0 || ndirent > MDIRENT) ndirent = MDIRENT; | |
55 | ndentb = ndirent/TPB; | |
56 | } | |
57 | dptr = &dir[0]; | |
58 | count = ndirent; | |
59 | do { | |
60 | if ((count % TPB) == 0) { /* next block */ | |
61 | tread(); | |
62 | tptr = &tpentry[0]; | |
63 | } | |
64 | if(flags & fls) | |
65 | swab((char *)tptr, (char *)tptr, sizeof(*tptr)); | |
66 | sp = (short *)tptr; | |
67 | reg = 0; | |
68 | for(i=0;i<sizeof(struct tent)/sizeof(short);i++) | |
69 | reg += *sp++; | |
70 | if(flags & fls) { | |
71 | swab((char *)tptr, (char *)tptr, sizeof(*tptr)); | |
72 | swabdir(tptr); | |
73 | } | |
74 | sum |= reg; | |
75 | p1 = dptr; | |
76 | if (reg == 0) { | |
77 | tp = tptr; | |
78 | if(tp->pathnam[0] != '\0') { | |
79 | lastd = p1; | |
80 | encode(tp->pathnam,p1); | |
81 | p1->d_mode = tp->mode; | |
82 | p1->d_uid = tp->uid; | |
83 | p1->d_gid = tp->gid; | |
84 | p1->d_size = (((long)tp->size0&0377L)<<16)+(tp->size1&0177777L); | |
85 | p1->d_time = tp->time; | |
86 | p1->d_tapea = tp->tapea; | |
87 | } | |
88 | } | |
89 | ++tptr; /* bump to next tent */ | |
90 | (dptr++)->d_mode &= ~OK; | |
91 | } while (--count); | |
92 | if(sum != 0) | |
93 | if(flags & (fls|fli)) { | |
94 | printf("Directory checksum\n"); | |
95 | if ((flags & fli) == 0) done(); | |
96 | } else { | |
97 | flags |= fls; | |
98 | rddir(); | |
99 | printf("Warning: swabbing required\n"); | |
100 | return; | |
101 | } | |
102 | bitmap(); | |
103 | } | |
104 | ||
105 | ||
106 | wrdir() | |
107 | { | |
108 | register struct tent *tp; | |
109 | register struct dent *dp; | |
110 | struct dent *dptr; | |
111 | int count, i; | |
112 | short reg, *sp; | |
113 | ||
114 | wseek(0); | |
115 | if (flags & flm) | |
116 | reg = open(mheader,0); | |
117 | else reg = open(theader,0); | |
118 | if (reg >= 0) { | |
119 | read(reg,(char *)tapeb,BSIZE); | |
120 | close(reg); | |
121 | if(flags & fls) | |
122 | swab((char *)&ndirent, (char *)&tpentry[TPB-1].cksum, sizeof(ndirent)); | |
123 | else | |
124 | tpentry[TPB-1].cksum = ndirent; | |
125 | } | |
126 | dptr = &dir[0]; | |
127 | count = ndirent; | |
128 | for (;;) { | |
129 | twrite(); | |
130 | if (count == 0) return; | |
131 | tp = &tpentry[0]; | |
132 | do { | |
133 | dp = dptr++; /* dptr set to next entry */ | |
134 | if (dp->d_namep) { | |
135 | decode(tp->pathnam,dp); | |
136 | tp->mode = dp->d_mode; | |
137 | tp->uid = dp->d_uid; | |
138 | tp->gid = dp->d_gid; | |
139 | tp->time = dp->d_time; | |
140 | tp->size0 = dp->d_size >> 16; | |
141 | tp->size1 = dp->d_size; | |
142 | tp->tapea = dp->d_tapea; | |
143 | if(flags & fls) { | |
144 | swabdir(tp); | |
145 | swab((char *)tp, (char *)tp, sizeof(*tp)); | |
146 | } | |
147 | reg = 0; | |
148 | sp = (short *)tp; | |
149 | for(i=0;i<sizeof(struct tent)/sizeof(short)-1;i++) | |
150 | reg -= *sp++; | |
151 | *sp = reg; | |
152 | if(flags & fls) | |
153 | swab((char *)tp, (char *)tp, sizeof(*tp)); | |
154 | } else { | |
155 | sp = (short *)tp; | |
156 | for(i=0;i<sizeof(struct tent)/sizeof(short);i++) | |
157 | *sp++ = 0; | |
158 | } | |
159 | tp++; | |
160 | } while (--count % TPB); | |
161 | } | |
162 | } | |
163 | ||
164 | tread() | |
165 | { | |
166 | register j, *ptr; | |
167 | ||
168 | if (read(fio,(char *)tapeb,BSIZE) != BSIZE) { | |
169 | printf("Tape read error\n"); | |
170 | if ((flags & fli) == 0) done(); | |
171 | ptr = (int *)tapeb; | |
172 | j = BSIZE/sizeof(int); | |
173 | while(j--) *ptr++ = 0; | |
174 | } | |
175 | rseeka++; | |
176 | } | |
177 | ||
178 | twrite() | |
179 | { | |
180 | if (write(fio, (char *)tapeb,BSIZE) != BSIZE) { | |
181 | printf("Tape write error\n"); | |
182 | done(); | |
183 | } | |
184 | ++wseeka; | |
185 | } | |
186 | ||
187 | rseek(blk) | |
188 | { | |
189 | rseeka = blk; | |
190 | if (lseek(fio,(long)blk*BSIZE,0) < 0) seekerr(); | |
191 | } | |
192 | ||
193 | wseek(blk) | |
194 | { | |
195 | register amt, b; | |
196 | ||
197 | amt = b = blk; | |
198 | if ((amt -= wseeka) < 0) amt = -amt; | |
199 | if (amt > 25 && b) { | |
200 | lseek(fio, (long)(b-1)*BSIZE, 0); /* seek previous block */ | |
201 | read(fio, (char *)&wseeka, 1); /* read next block */ | |
202 | } | |
203 | wseeka = b; | |
204 | if (lseek(fio, (long)b*BSIZE, 0) < 0) seekerr(); | |
205 | } | |
206 | ||
207 | seekerr() | |
208 | { | |
209 | printf("Tape seek error\n"); | |
210 | done(); | |
211 | } | |
212 | ||
213 | verify(key) | |
214 | { | |
215 | register c; | |
216 | ||
217 | if ((flags & (flw | flv)) == 0) | |
218 | return(0); | |
219 | repeat: printf("%c %s ", key, name); | |
220 | if ((flags & flw) == 0) { | |
221 | printf("\n"); | |
222 | return(0); | |
223 | } | |
224 | c = getchar(); | |
225 | if (c == 'n' && getchar() == '\n') | |
226 | done(); | |
227 | if (c == '\n') | |
228 | return(-1); | |
229 | if (c == 'y' && getchar() == '\n') | |
230 | return(0); | |
231 | while (getchar() != '\n'); | |
232 | goto repeat; | |
233 | } | |
234 | ||
235 | getfiles() | |
236 | { | |
237 | ||
238 | if ((narg -= 2) == 0) { | |
239 | strcpy(name, "."); | |
240 | callout(); | |
241 | } else while (--narg >= 0) { | |
242 | strcpy(name, *parg++); | |
243 | callout(); | |
244 | } | |
245 | } | |
246 | ||
247 | ||
248 | expand() | |
249 | { | |
250 | register char *p0, *save0; | |
251 | int n, fid; | |
252 | ||
253 | if ((fid = open(name,0)) < 0) fserr(); | |
254 | for (;;) { | |
255 | if ((n = read(fid, (char *)&direct, sizeof(direct))) != sizeof(direct)) { | |
256 | if (n == 0) { | |
257 | close(fid); | |
258 | return; | |
259 | } | |
260 | fserr(); | |
261 | } | |
262 | if (direct.d_ino == 0) /* null entry */ | |
263 | continue; | |
264 | p0 = name; | |
265 | if (direct.d_name[0] == '.') /* don't save .xxxx */ | |
266 | continue; | |
267 | while (*p0++); | |
268 | save0 = --p0; /* save loc of \0 */ | |
269 | if (p0[-1] != '/') | |
270 | *p0++ = '/'; | |
271 | strcpy(p0, direct.d_name); | |
272 | callout(); | |
273 | *save0 = 0; /* restore */ | |
274 | } | |
275 | } | |
276 | ||
277 | fserr() | |
278 | { | |
279 | printf("%s -- Cannot open file\n", name); | |
280 | done(); | |
281 | } | |
282 | ||
283 | callout() | |
284 | { | |
285 | register struct dent *d; | |
286 | register char *ptr1, *ptr0; | |
287 | struct dent *empty; | |
288 | int mode; | |
289 | ||
290 | if (stat(name,&statb) < 0) fserr(); | |
291 | mode = statb.st_mode; | |
292 | if ((mode &= S_IFMT) != 0) { | |
293 | if (mode == S_IFDIR) /* directory */ | |
294 | expand(); | |
295 | if(mode != S_IFREG) return; | |
296 | } | |
297 | /* when we reach here we have recursed until we found | |
298 | * an ordinary file. Now we look for it in "dir". | |
299 | */ | |
300 | empty = 0; | |
301 | d = &dir[0]; | |
302 | do { | |
303 | if (d->d_namep == 0) { /* empty directory slot */ | |
304 | if (empty == 0) /* remember the first one */ | |
305 | empty = d; | |
306 | continue; | |
307 | } | |
308 | decode(name1,d); | |
309 | ptr0 = name; | |
310 | ptr1 = name1; | |
311 | do if (*ptr0++ != *ptr1) goto cont; | |
312 | while (*ptr1++); | |
313 | /* veritably the same name */ | |
314 | if (flags & flu) { /* check the times */ | |
315 | if (d->d_time >= statb.st_mtime) | |
316 | return; | |
317 | } | |
318 | if (verify('r') < 0) return; | |
319 | goto copydir; | |
320 | cont: continue; | |
321 | } while (++d <= lastd); | |
322 | /* name not found in directory */ | |
323 | if ((d = empty) == 0) { | |
324 | d = lastd +1; | |
325 | if (d >= edir) { | |
326 | printf("Directory overflow\n"); | |
327 | done(); | |
328 | } | |
329 | } | |
330 | if (verify('a') < 0) return; | |
331 | if (d > lastd) lastd = d; | |
332 | encode(name,d); | |
333 | copydir: | |
334 | d->d_mode = statb.st_mode | OK; | |
335 | d->d_uid = statb.st_uid; | |
336 | d->d_gid = statb.st_gid; | |
337 | d->d_size = statb.st_size; | |
338 | d->d_time = statb.st_mtime; | |
339 | } | |
340 | ||
341 | swabdir(tp) | |
342 | register struct tent *tp; | |
343 | { | |
344 | swab((char *)tp, (char *)tp, sizeof(*tp)); | |
345 | swab(tp->pathnam, tp->pathnam, NAMELEN); | |
346 | swab((char *)&tp->uid, (char *)&tp->uid, 4); /* uid,gid,spare,size0 */ | |
347 | } |