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