home *** CD-ROM | disk | FTP | other *** search
- #define MAXINO 3000
- #define BITS 8
- #define MAXXTR 60
- #define NCACHE 3
-
- #include <stdio.h>
- #include <sys/param.h>
- #include <sys/inode.h>
- #include <sys/ino.h>
- #include <sys/fblk.h>
- #include <sys/filsys.h>
- #include <sys/dir.h>
- #include <dumprestor.h>
-
- #define MWORD(m,i) (m[(unsigned)(i-1)/MLEN])
- #define MBIT(i) (1<<((unsigned)(i-1)%MLEN))
- #define BIS(i,w) (MWORD(w,i) |= MBIT(i))
- #define BIC(i,w) (MWORD(w,i) &= ~MBIT(i))
- #define BIT(i,w) (MWORD(w,i) & MBIT(i))
-
- int mt;
- char tapename[] = "/dev/rmt1";
- char *magtape = tapename;
-
- daddr_t seekpt;
- int ofile;
- FILE *df;
- char dirfile[] = "rstXXXXXX";
-
- struct {
- ino_t t_ino;
- daddr_t t_seekpt;
- } inotab[MAXINO];
- int ipos;
-
- #define ONTAPE 1
- #define XTRACTD 2
- #define XINUSE 4
-
- short dumpmap[MSIZ];
- short clrimap[MSIZ];
-
-
- int bct = NTREC+1;
- char tbf[NTREC*BSIZE];
-
- char prebuf[512];
-
- int volno;
-
- main(argc, argv)
- char *argv[];
- {
- extern char *ctime();
-
- mktemp(dirfile);
- argv++;
- if (argc>=3 && *argv[0] == 'f')
- magtape = *++argv;
- df = fopen(dirfile, "w");
- if (df == NULL) {
- printf("dumpdir: %s - cannot create directory temporary\n", dirfile);
- exit(1);
- }
-
- if ((mt = open(magtape, 0)) < 0) {
- printf("%s: cannot open tape\n", magtape);
- exit(1);
- }
- if (readhdr(&spcl) == 0) {
- printf("Tape is not a dump tape\n");
- exit(1);
- }
- printf("Dump date: %s", ctime(&spcl.c_date));
- printf("Dumped from: %s", ctime(&spcl.c_ddate));
- if (checkvol(&spcl, 1) == 0) {
- printf("Tape is not volume 1 of the dump\n");
- exit(1);
- }
- pass1(); /* This sets the various maps on the way by */
- freopen(dirfile, "r", df);
- strcpy(prebuf, "/");
- printem(prebuf, (ino_t) 2);
- exit(0);
- }
- i = 0;
- /*
- * Read the tape, bulding up a directory structure for extraction
- * by name
- */
- pass1()
- {
- register i;
- struct dinode *ip;
- int putdir(), null();
-
- while (gethead(&spcl) == 0) {
- printf("Can't find directory header!\n");
- }
- for (;;) {
- if (checktype(&spcl, TS_BITS) == 1) {
- readbits(dumpmap);
- continue;
- }
- if (checktype(&spcl, TS_CLRI) == 1) {
- readbits(clrimap);
- continue;
- }
- if (checktype(&spcl, TS_INODE) == 0) {
- finish:
- flsh();
- close(mt);
- return;
- }
- ip = &spcl.c_dinode;
- i = ip->di_mode & IFMT;
- if (i != IFDIR) {
- goto finish;
- }
- inotab[ipos].t_ino = spcl.c_inumber;
- inotab[ipos++].t_seekpt = seekpt;
- getfile(spcl.c_inumber, putdir, null, spcl.c_dinode.di_size);
- putent("\000\000/");
- }
- }
-
- printem(prefix, inum)
- char *prefix;
- ino_t inum;
- {
- struct direct dir;
- register int i;
-
- for (i = 0; i < MAXINO; i++)
- if (inotab[i].t_ino == inum) {
- goto found;
- }
- printf("PANIC - can't find directory %d\n", inum);
- return;
- found:
- mseek(inotab[i].t_seekpt);
- for (;;) {
- getent((char *) &dir);
- if (direq(dir.d_name, "/"))
- return;
- if (search(dir.d_ino) != 0 && direq(dir.d_name, ".") == 0 && direq(dir.d_name, "..") == 0) {
- int len;
- FILE *tdf;
-
- tdf = df;
- df = fopen(dirfile, "r");
- len = strlen(prefix);
- strncat(prefix, dir.d_name, sizeof(dir.d_name));
- strcat(prefix, "/");
- printem(prefix, dir.d_ino);
- prefix[len] = '\0';
- fclose(df);
- df = tdf;
- }
- else
- if (BIT(dir.d_ino, dumpmap))
- printf("%5d %s%-.14s\n", dir.d_ino, prefix, dir.d_name);
- }
- }
- /*
- * Do the file extraction, calling the supplied functions
- * with the blocks
- */
- getfile(n, f1, f2, size)
- ino_t n;
- int (*f2)(), (*f1)();
- long size;
- {
- register i;
- struct spcl addrblock;
- char buf[BSIZE];
-
- addrblock = spcl;
- goto start;
- for (;;) {
- if (gethead(&addrblock) == 0) {
- printf("Missing address (header) block\n");
- goto eloop;
- }
- if (checktype(&addrblock, TS_ADDR) == 0) {
- spcl = addrblock;
- return;
- }
- start:
- for (i = 0; i < addrblock.c_count; i++) {
- if (addrblock.c_addr[i]) {
- readtape(buf);
- (*f1)(buf, size > BSIZE ? (long) BSIZE : size);
- }
- else {
- clearbuf(buf);
- (*f2)(buf, size > BSIZE ? (long) BSIZE : size);
- }
- if ((size -= BSIZE) <= 0) {
- eloop:
- while (gethead(&spcl) == 0)
- ;
- if (checktype(&spcl, TS_ADDR) == 1)
- goto eloop;
- return;
- }
- }
- }
- }
-
- /*
- * Do the tape i\/o, dealling with volume changes
- * etc..
- */
- readtape(b)
- char *b;
- {
- register i;
- struct spcl tmpbuf;
-
- if (bct >= NTREC) {
- for (i = 0; i < NTREC; i++)
- ((struct spcl *)&tbf[i*BSIZE])->c_magic = 0;
- bct = 0;
- if ((i = read(mt, tbf, NTREC*BSIZE)) < 0) {
- exit(1);
- }
- if (i == 0) {
- bct = NTREC + 1;
- volno++;
- loop:
- flsht();
- close(mt);
- printf("Mount volume %d\n", volno);
- while (getchar() != '\n')
- ;
- if ((mt = open(magtape, 0)) == -1) {
- printf("Cannot open tape!\n");
- }
- if (readhdr(&tmpbuf) == 0) {
- printf("Not a dump tape.Try again\n");
- goto loop;
- }
- if (checkvol(&tmpbuf, volno) == 0) {
- printf("Wrong tape. Try again\n");
- goto loop;
- }
- readtape(b);
- return;
- }
- }
- copy(&tbf[(bct++*BSIZE)], b, BSIZE);
- }
-
- flsht()
- {
- bct = NTREC+1;
- }
-
- copy(f, t, s)
- register char *f, *t;
- {
- register i;
-
- i = s;
- do
- *t++ = *f++;
- while (--i);
- }
-
- clearbuf(cp)
- register char *cp;
- {
- register i;
-
- i = BSIZE;
- do
- *cp++ = 0;
- while (--i);
- }
-
- /*
- * Put and get the directory entries from the compressed
- * directory file
- */
- putent(cp)
- char *cp;
- {
- register i;
-
- for (i = 0; i < sizeof(ino_t); i++)
- writec(*cp++);
- for (i = 0; i < DIRSIZ; i++) {
- writec(*cp);
- if (*cp++ == 0)
- return;
- }
- return;
- }
-
- getent(bf)
- register char *bf;
- {
- register i;
-
- for (i = 0; i < sizeof(ino_t); i++)
- *bf++ = readc();
- for (i = 0; i < DIRSIZ; i++)
- if ((*bf++ = readc()) == 0)
- return;
- return;
- }
-
- /*
- * read/write te directory file
- */
- writec(c)
- char c;
- {
- seekpt++;
- fwrite(&c, 1, 1, df);
- }
-
- readc()
- {
- char c;
-
- fread(&c, 1, 1, df);
- return(c);
- }
-
- mseek(pt)
- daddr_t pt;
- {
- fseek(df, pt, 0);
- }
-
- flsh()
- {
- fflush(df);
- }
-
- /*
- * search the directory inode ino
- * looking for entry cp
- */
- search(inum)
- ino_t inum;
- {
- register low, high, probe;
-
- low = 0;
- high = ipos-1;
-
- while (low != high) {
- probe = (high - low + 1)/2 + low;
- /*
- printf("low = %d, high = %d, probe = %d, ino = %d, inum = %d\n", low, high, probe, inum, inotab[probe].t_ino);
- */
- if (inum >= inotab[probe].t_ino)
- low = probe;
- else
- high = probe - 1;
- }
- return(inum == inotab[low].t_ino);
- }
-
- direq(s1, s2)
- register char *s1, *s2;
- {
- register i;
-
- for (i = 0; i < DIRSIZ; i++)
- if (*s1++ == *s2) {
- if (*s2++ == 0)
- return(1);
- } else
- return(0);
- return(1);
- }
-
- /*
- * read the tape into buf, then return whether or
- * or not it is a header block.
- */
- gethead(buf)
- struct spcl *buf;
- {
- readtape((char *)buf);
- if (buf->c_magic != MAGIC || checksum((int *) buf) == 0)
- return(0);
- return(1);
- }
-
- /*
- * return whether or not the buffer contains a header block
- */
- checktype(b, t)
- struct spcl *b;
- int t;
- {
- return(b->c_type == t);
- }
-
-
- checksum(b)
- int *b;
- {
- register i, j;
-
- j = BSIZE/sizeof(int);
- i = 0;
- do
- i += *b++;
- while (--j);
- if (i != CHECKSUM) {
- printf("Checksum error %o\n", i);
- return(0);
- }
- return(1);
- }
-
- checkvol(b, t)
- struct spcl *b;
- int t;
- {
- if (b->c_volume == t)
- return(1);
- return(0);
- }
-
- readhdr(b)
- struct spcl *b;
- {
- if (gethead(b) == 0)
- return(0);
- if (checktype(b, TS_TAPE) == 0)
- return(0);
- return(1);
- }
-
- putdir(b)
- char *b;
- {
- register struct direct *dp;
- register i;
-
- for (dp = (struct direct *) b, i = 0; i < BSIZE; dp++, i += sizeof(*dp)) {
- if (dp->d_ino == 0)
- continue;
- putent((char *) dp);
- }
- }
-
- /*
- * read a bit mask from the tape into m.
- */
- readbits(m)
- short *m;
- {
- register i;
-
- i = spcl.c_count;
-
- while (i--) {
- readtape((char *) m);
- m += (BSIZE/(MLEN/BITS));
- }
- while (gethead(&spcl) == 0)
- ;
- }
-
- null() { ; }
-