|
|
1.1 root 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: } else
126: printf("\7\7\7Warning: cannot read prototype boot block.\n");
127: dptr = &dir[0];
128: count = ndirent;
129: for (;;) {
130: twrite();
131: if (count == 0) return;
132: tp = &tpentry[0];
133: do {
134: dp = dptr++; /* dptr set to next entry */
135: if (dp->d_namep) {
136: decode(tp->pathnam,dp);
137: tp->mode = dp->d_mode;
138: tp->uid = dp->d_uid;
139: tp->gid = dp->d_gid;
140: tp->time = dp->d_time;
141: tp->size0 = dp->d_size >> 16;
142: tp->size1 = dp->d_size;
143: tp->tapea = dp->d_tapea;
144: if(flags & fls) {
145: swabdir(tp);
146: swab((char *)tp, (char *)tp, sizeof(*tp));
147: }
148: reg = 0;
149: sp = (short *)tp;
150: for(i=0;i<sizeof(struct tent)/sizeof(short)-1;i++)
151: reg -= *sp++;
152: *sp = reg;
153: if(flags & fls)
154: swab((char *)tp, (char *)tp, sizeof(*tp));
155: } else {
156: sp = (short *)tp;
157: for(i=0;i<sizeof(struct tent)/sizeof(short);i++)
158: *sp++ = 0;
159: }
160: tp++;
161: } while (--count % TPB);
162: }
163: }
164:
165: tread()
166: {
167: register j, *ptr;
168:
169: if (read(fio,(char *)tapeb,BSIZE) != BSIZE) {
170: printf("Tape read error\n");
171: if ((flags & fli) == 0) done();
172: ptr = (int *)tapeb;
173: j = BSIZE/sizeof(int);
174: while(j--) *ptr++ = 0;
175: }
176: rseeka++;
177: }
178:
179: twrite()
180: {
181: if (write(fio, (char *)tapeb,BSIZE) != BSIZE) {
182: printf("Tape write error\n");
183: done();
184: }
185: ++wseeka;
186: }
187:
188: rseek(blk)
189: {
190: rseeka = blk;
191: if (lseek(fio,(long)blk*BSIZE,0) < 0) seekerr();
192: }
193:
194: wseek(blk)
195: {
196: register amt, b;
197:
198: amt = b = blk;
199: if ((amt -= wseeka) < 0) amt = -amt;
200: if (amt > 25 && b) {
201: lseek(fio, (long)(b-1)*BSIZE, 0); /* seek previous block */
202: read(fio, (char *)&wseeka, 1); /* read next block */
203: }
204: wseeka = b;
205: if (lseek(fio, (long)b*BSIZE, 0) < 0) seekerr();
206: }
207:
208: seekerr()
209: {
210: printf("Tape seek error\n");
211: done();
212: }
213:
214: verify(key)
215: {
216: register c;
217:
218: if ((flags & (flw | flv)) == 0)
219: return(0);
220: repeat: printf("%c %s ", key, name);
221: if ((flags & flw) == 0) {
222: printf("\n");
223: return(0);
224: }
225: c = getchar();
226: if (c == 'n' && getchar() == '\n')
227: done();
228: if (c == '\n')
229: return(-1);
230: if (c == 'y' && getchar() == '\n')
231: return(0);
232: while (getchar() != '\n');
233: goto repeat;
234: }
235:
236: getfiles()
237: {
238:
239: if ((narg -= 2) == 0) {
240: strcpy(name, ".");
241: callout();
242: } else while (--narg >= 0) {
243: strcpy(name, *parg++);
244: callout();
245: }
246: }
247:
248:
249: expand()
250: {
251: register char *p0, *save0;
252: int n, fid;
253:
254: if ((fid = open(name,0)) < 0) fserr();
255: for (;;) {
256: if ((n = read(fid, (char *)&direct, sizeof(direct))) != sizeof(direct)) {
257: if (n == 0) {
258: close(fid);
259: return;
260: }
261: fserr();
262: }
263: if (direct.d_ino == 0) /* null entry */
264: continue;
265: p0 = name;
266: if (direct.d_name[0] == '.') /* don't save .xxxx */
267: continue;
268: while (*p0++);
269: save0 = --p0; /* save loc of \0 */
270: if (p0[-1] != '/')
271: *p0++ = '/';
272: strcpy(p0, direct.d_name);
273: callout();
274: *save0 = 0; /* restore */
275: }
276: }
277:
278: fserr()
279: {
280: printf("%s -- Cannot open file\n", name);
281: done();
282: }
283:
284: callout()
285: {
286: register struct dent *d;
287: register char *ptr1, *ptr0;
288: struct dent *empty;
289: int mode;
290:
291: if (stat(name,&statb) < 0) fserr();
292: mode = statb.st_mode;
293: if ((mode &= S_IFMT) != 0) {
294: if (mode == S_IFDIR) /* directory */
295: expand();
296: if(mode != S_IFREG) return;
297: }
298: /* when we reach here we have recursed until we found
299: * an ordinary file. Now we look for it in "dir".
300: */
301: empty = 0;
302: d = &dir[0];
303: do {
304: if (d->d_namep == 0) { /* empty directory slot */
305: if (empty == 0) /* remember the first one */
306: empty = d;
307: continue;
308: }
309: decode(name1,d);
310: ptr0 = name;
311: ptr1 = name1;
312: do if (*ptr0++ != *ptr1) goto cont;
313: while (*ptr1++);
314: /* veritably the same name */
315: if (flags & flu) { /* check the times */
316: if (d->d_time >= statb.st_mtime)
317: return;
318: }
319: if (verify('r') < 0) return;
320: goto copydir;
321: cont: continue;
322: } while (++d <= lastd);
323: /* name not found in directory */
324: if ((d = empty) == 0) {
325: d = lastd +1;
326: if (d >= edir) {
327: printf("Directory overflow\n");
328: done();
329: }
330: }
331: if (verify('a') < 0) return;
332: if (d > lastd) lastd = d;
333: encode(name,d);
334: copydir:
335: d->d_mode = statb.st_mode | OK;
336: d->d_uid = statb.st_uid;
337: d->d_gid = statb.st_gid;
338: d->d_size = statb.st_size;
339: d->d_time = statb.st_mtime;
340: }
341:
342: swabdir(tp)
343: register struct tent *tp;
344: {
345: swab((char *)tp, (char *)tp, sizeof(*tp));
346: swab(tp->pathnam, tp->pathnam, NAMELEN);
347: swab((char *)&tp->uid, (char *)&tp->uid, 4); /* uid,gid,spare,size0 */
348: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.