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