|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)tp2.c 4.1 12/18/82";
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.