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