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