|
|
1.1 root 1: #define MAXINO 2000
2: #define BITS 8
3: #define MAXXTR 60
4: #define NCACHE 3
5:
6: #include <stdio.h>
7: #include <sys/param.h>
8: #include <sys/inode.h>
9: #include <sys/ino.h>
10: #include <sys/fblk.h>
11: #include <sys/filsys.h>
12: #include <sys/dir.h>
13: #include <dumprestor.h>
14:
15: #define MWORD(m,i) (m[(unsigned)(i-1)/MLEN])
16: #define MBIT(i) (1<<((unsigned)(i-1)%MLEN))
17: #define BIS(i,w) (MWORD(w,i) |= MBIT(i))
18: #define BIC(i,w) (MWORD(w,i) &= ~MBIT(i))
19: #define BIT(i,w) (MWORD(w,i) & MBIT(i))
20:
21: int mt;
22: char tapename[] = "/dev/rmt1";
23: char *magtape = tapename;
24:
25: daddr_t seekpt;
26: int ofile;
27: FILE *df;
28: char dirfile[] = "rstXXXXXX";
29:
30: struct {
31: ino_t t_ino;
32: daddr_t t_seekpt;
33: } inotab[MAXINO];
34: int ipos;
35:
36: #define ONTAPE 1
37: #define XTRACTD 2
38: #define XINUSE 4
39:
40: short dumpmap[MSIZ];
41: short clrimap[MSIZ];
42:
43:
44: int bct = NTREC+1;
45: char tbf[NTREC*BSIZE];
46:
47: char prebuf[BUFSIZ];
48:
49: int volno;
50:
51: main(argc, argv)
52: char *argv[];
53: {
54: extern char *ctime();
55:
56: mktemp(dirfile);
57: argv++;
58: if (argc>=3 && *argv[0] == 'f')
59: magtape = *++argv;
60: df = fopen(dirfile, "w");
61: if (df == NULL) {
62: printf("dumpdir: %s - cannot create directory temporary\n", dirfile);
63: exit(1);
64: }
65:
66: if ((mt = open(magtape, 0)) < 0) {
67: printf("%s: cannot open tape\n", magtape);
68: exit(1);
69: }
70: if (readhdr(&spcl) == 0) {
71: printf("Tape is not a dump tape\n");
72: exit(1);
73: }
74: printf("Dump date: %s", ctime(&spcl.c_date));
75: printf("Dumped from: %s", ctime(&spcl.c_ddate));
76: if (checkvol(&spcl, 1) == 0) {
77: printf("Tape is not volume 1 of the dump\n");
78: exit(1);
79: }
80: pass1(); /* This sets the various maps on the way by */
81: freopen(dirfile, "r", df);
82: strcpy(prebuf, "/");
83: printem(prebuf, (ino_t) 2);
84: exit(0);
85: }
86: i = 0;
87: /*
88: * Read the tape, bulding up a directory structure for extraction
89: * by name
90: */
91: pass1()
92: {
93: register i;
94: struct dinode *ip;
95: int putdir(), null();
96:
97: while (gethead(&spcl) == 0) {
98: printf("Can't find directory header!\n");
99: }
100: for (;;) {
101: if (checktype(&spcl, TS_BITS) == 1) {
102: readbits(dumpmap);
103: continue;
104: }
105: if (checktype(&spcl, TS_CLRI) == 1) {
106: readbits(clrimap);
107: continue;
108: }
109: if (checktype(&spcl, TS_INODE) == 0) {
110: finish:
111: flsh();
112: close(mt);
113: return;
114: }
115: ip = &spcl.c_dinode;
116: i = ip->di_mode & IFMT;
117: if (i != IFDIR) {
118: goto finish;
119: }
120: inotab[ipos].t_ino = spcl.c_inumber;
121: inotab[ipos++].t_seekpt = seekpt;
122: getfile(spcl.c_inumber, putdir, null, spcl.c_dinode.di_size);
123: putent("\000\000/");
124: }
125: }
126:
127: printem(prefix, inum)
128: char *prefix;
129: ino_t inum;
130: {
131: struct direct dir;
132: register int i;
133:
134: for (i = 0; i < MAXINO; i++)
135: if (inotab[i].t_ino == inum) {
136: goto found;
137: }
138: printf("PANIC - can't find directory %d\n", inum);
139: return;
140: found:
141: mseek(inotab[i].t_seekpt);
142: for (;;) {
143: getent((char *) &dir);
144: if (direq(dir.d_name, "/"))
145: return;
146: if (search(dir.d_ino) != 0 && direq(dir.d_name, ".") == 0 && direq(dir.d_name, "..") == 0) {
147: int len;
148: FILE *tdf;
149:
150: tdf = df;
151: df = fopen(dirfile, "r");
152: len = strlen(prefix);
153: strncat(prefix, dir.d_name, sizeof(dir.d_name));
154: strcat(prefix, "/");
155: printem(prefix, dir.d_ino);
156: prefix[len] = '\0';
157: fclose(df);
158: df = tdf;
159: }
160: else
161: if (BIT(dir.d_ino, dumpmap))
162: printf("%5d %s%-.14s\n", dir.d_ino, prefix, dir.d_name);
163: }
164: }
165: /*
166: * Do the file extraction, calling the supplied functions
167: * with the blocks
168: */
169: getfile(n, f1, f2, size)
170: ino_t n;
171: int (*f2)(), (*f1)();
172: long size;
173: {
174: register i;
175: struct spcl addrblock;
176: char buf[BSIZE];
177:
178: addrblock = spcl;
179: goto start;
180: for (;;) {
181: if (gethead(&addrblock) == 0) {
182: printf("Missing address (header) block\n");
183: goto eloop;
184: }
185: if (checktype(&addrblock, TS_ADDR) == 0) {
186: spcl = addrblock;
187: return;
188: }
189: start:
190: for (i = 0; i < addrblock.c_count; i++) {
191: if (addrblock.c_addr[i]) {
192: readtape(buf);
193: (*f1)(buf, size > BSIZE ? (long) BSIZE : size);
194: }
195: else {
196: clearbuf(buf);
197: (*f2)(buf, size > BSIZE ? (long) BSIZE : size);
198: }
199: if ((size -= BSIZE) <= 0) {
200: eloop:
201: while (gethead(&spcl) == 0)
202: ;
203: if (checktype(&spcl, TS_ADDR) == 1)
204: goto eloop;
205: return;
206: }
207: }
208: }
209: }
210:
211: /*
212: * Do the tape i\/o, dealling with volume changes
213: * etc..
214: */
215: readtape(b)
216: char *b;
217: {
218: register i;
219: struct spcl tmpbuf;
220:
221: if (bct >= NTREC) {
222: for (i = 0; i < NTREC; i++)
223: ((struct spcl *)&tbf[i*BSIZE])->c_magic = 0;
224: bct = 0;
225: if ((i = read(mt, tbf, NTREC*BSIZE)) < 0) {
226: exit(1);
227: }
228: if (i == 0) {
229: bct = NTREC + 1;
230: volno++;
231: loop:
232: flsht();
233: close(mt);
234: printf("Mount volume %d\n", volno);
235: while (getchar() != '\n')
236: ;
237: if ((mt = open(magtape, 0)) == -1) {
238: printf("Cannot open tape!\n");
239: }
240: if (readhdr(&tmpbuf) == 0) {
241: printf("Not a dump tape.Try again\n");
242: goto loop;
243: }
244: if (checkvol(&tmpbuf, volno) == 0) {
245: printf("Wrong tape. Try again\n");
246: goto loop;
247: }
248: readtape(b);
249: return;
250: }
251: }
252: copy(&tbf[(bct++*BSIZE)], b, BSIZE);
253: }
254:
255: flsht()
256: {
257: bct = NTREC+1;
258: }
259:
260: copy(f, t, s)
261: register char *f, *t;
262: {
263: register i;
264:
265: i = s;
266: do
267: *t++ = *f++;
268: while (--i);
269: }
270:
271: clearbuf(cp)
272: register char *cp;
273: {
274: register i;
275:
276: i = BSIZE;
277: do
278: *cp++ = 0;
279: while (--i);
280: }
281:
282: /*
283: * Put and get the directory entries from the compressed
284: * directory file
285: */
286: putent(cp)
287: char *cp;
288: {
289: register i;
290:
291: for (i = 0; i < sizeof(ino_t); i++)
292: writec(*cp++);
293: for (i = 0; i < DIRSIZ; i++) {
294: writec(*cp);
295: if (*cp++ == 0)
296: return;
297: }
298: return;
299: }
300:
301: getent(bf)
302: register char *bf;
303: {
304: register i;
305:
306: for (i = 0; i < sizeof(ino_t); i++)
307: *bf++ = readc();
308: for (i = 0; i < DIRSIZ; i++)
309: if ((*bf++ = readc()) == 0)
310: return;
311: return;
312: }
313:
314: /*
315: * read/write te directory file
316: */
317: writec(c)
318: char c;
319: {
320: seekpt++;
321: fwrite(&c, 1, 1, df);
322: }
323:
324: readc()
325: {
326: char c;
327:
328: fread(&c, 1, 1, df);
329: return(c);
330: }
331:
332: mseek(pt)
333: daddr_t pt;
334: {
335: fseek(df, pt, 0);
336: }
337:
338: flsh()
339: {
340: fflush(df);
341: }
342:
343: /*
344: * search the directory inode ino
345: * looking for entry cp
346: */
347: search(inum)
348: ino_t inum;
349: {
350: register low, high, probe;
351:
352: low = 0;
353: high = ipos-1;
354:
355: while (low != high) {
356: probe = (high - low + 1)/2 + low;
357: /*
358: printf("low = %d, high = %d, probe = %d, ino = %d, inum = %d\n", low, high, probe, inum, inotab[probe].t_ino);
359: */
360: if (inum >= inotab[probe].t_ino)
361: low = probe;
362: else
363: high = probe - 1;
364: }
365: return(inum == inotab[low].t_ino);
366: }
367:
368: direq(s1, s2)
369: register char *s1, *s2;
370: {
371: register i;
372:
373: for (i = 0; i < DIRSIZ; i++)
374: if (*s1++ == *s2) {
375: if (*s2++ == 0)
376: return(1);
377: } else
378: return(0);
379: return(1);
380: }
381:
382: /*
383: * read the tape into buf, then return whether or
384: * or not it is a header block.
385: */
386: gethead(buf)
387: struct spcl *buf;
388: {
389: readtape((char *)buf);
390: if (buf->c_magic != MAGIC || checksum((int *) buf) == 0)
391: return(0);
392: return(1);
393: }
394:
395: /*
396: * return whether or not the buffer contains a header block
397: */
398: checktype(b, t)
399: struct spcl *b;
400: int t;
401: {
402: return(b->c_type == t);
403: }
404:
405:
406: checksum(b)
407: int *b;
408: {
409: register i, j;
410:
411: j = BSIZE/sizeof(int);
412: i = 0;
413: do
414: i += *b++;
415: while (--j);
416: if (i != CHECKSUM) {
417: printf("Checksum error %o\n", i);
418: return(0);
419: }
420: return(1);
421: }
422:
423: checkvol(b, t)
424: struct spcl *b;
425: int t;
426: {
427: if (b->c_volume == t)
428: return(1);
429: return(0);
430: }
431:
432: readhdr(b)
433: struct spcl *b;
434: {
435: if (gethead(b) == 0)
436: return(0);
437: if (checktype(b, TS_TAPE) == 0)
438: return(0);
439: return(1);
440: }
441:
442: putdir(b)
443: char *b;
444: {
445: register struct direct *dp;
446: register i;
447:
448: for (dp = (struct direct *) b, i = 0; i < BSIZE; dp++, i += sizeof(*dp)) {
449: if (dp->d_ino == 0)
450: continue;
451: putent((char *) dp);
452: }
453: }
454:
455: /*
456: * read a bit mask from the tape into m.
457: */
458: readbits(m)
459: short *m;
460: {
461: register i;
462:
463: i = spcl.c_count;
464:
465: while (i--) {
466: readtape((char *) m);
467: m += (BSIZE/(MLEN/BITS));
468: }
469: while (gethead(&spcl) == 0)
470: ;
471: }
472:
473: null() { ; }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.