home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / dumpdir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-05-05  |  7.4 KB  |  474 lines

  1. #define MAXINO    3000
  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[512];
  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() { ; }
  474.