BSD 3 development
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Sun, 30 Dec 1979 04:18:20 +0000 (20:18 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Sun, 30 Dec 1979 04:18:20 +0000 (20:18 -0800)
Work on file usr/src/cmd/dumpdir.c

Synthesized-from: 3bsd

usr/src/cmd/dumpdir.c [new file with mode: 0644]

diff --git a/usr/src/cmd/dumpdir.c b/usr/src/cmd/dumpdir.c
new file mode 100644 (file)
index 0000000..8a5bb99
--- /dev/null
@@ -0,0 +1,473 @@
+#define MAXINO 2000
+#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[BUFSIZ];
+
+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() { ; }