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

  1. #define    NI    16
  2. #define    DIRPB    (BSIZE/sizeof(struct direct))
  3.  
  4. #include <stdio.h>
  5. #include <sys/param.h>
  6. #include <sys/inode.h>
  7. #include <sys/ino.h>
  8. #include <sys/fblk.h>
  9. #include <sys/filsys.h>
  10. #include <sys/dir.h>
  11. #include <dumprestor.h>
  12.  
  13. #define    MWORD(m,i) (m[(unsigned)(i-1)/MLEN])
  14. #define    MBIT(i)    (1<<((unsigned)(i-1)%MLEN))
  15. #define    BIS(i,w)    (MWORD(w,i) |=  MBIT(i))
  16. #define    BIC(i,w)    (MWORD(w,i) &= ~MBIT(i))
  17. #define    BIT(i,w)    (MWORD(w,i) & MBIT(i))
  18.  
  19. struct    filsys    sblock;
  20. struct    dinode    itab[INOPB*NI];
  21. short    clrmap[MSIZ];
  22. short    dirmap[MSIZ];
  23. short    nodmap[MSIZ];
  24.  
  25. char    *disk;
  26. char    *tape;
  27. char    *increm;
  28. char    incno;
  29. int    uflag;
  30. int    fi;
  31. int    to;
  32. ino_t    ino;
  33. int    nsubdir;
  34. int    ntape;
  35. int    nadded;
  36. int    dadded;
  37. int    density = 160;
  38.  
  39. char    *ctime();
  40. char    *prdate();
  41. long    atol();
  42. int    fi;
  43. long    tsize;
  44. long    esize;
  45. long    asize;
  46. int    mark();
  47. int    add();
  48. int    dump();
  49. int    tapsrec();
  50. int    dmpspc();
  51. int    dsrch();
  52. int    nullf();
  53.  
  54. #define    HOUR    (60L*60L)
  55. #define    DAY    (24L*HOUR)
  56. #define    YEAR    (365L*DAY)
  57.  
  58. main(argc, argv)
  59. char *argv[];
  60. {
  61.     char *arg;
  62.     register i;
  63.  
  64.     time(&spcl.c_date);
  65.  
  66.     tsize = 2300L*12L*10L;
  67.     tape = "/dev/rmt1";
  68.     disk = "/dev/rrp3";
  69.     increm = "/etc/ddate";
  70.     incno = '9';
  71.     uflag = 0;
  72.     arg = "u";
  73.     if(argc > 1) {
  74.         argv++;
  75.         argc--;
  76.         arg = *argv;
  77.     }
  78.     while(*arg)
  79.     switch (*arg++) {
  80.  
  81.     case 'f':
  82.         if(argc > 1) {
  83.             argv++;
  84.             argc--;
  85.             tape = *argv;
  86.         }
  87.         break;
  88.  
  89.     case 'd':
  90.         if (argc > 1) {
  91.             argv++;
  92.             argc--;
  93.             density = atoi(*argv)/10;
  94.         }
  95.         break;
  96.  
  97.     case 's':
  98.         if(argc > 1) {
  99.             argv++;
  100.             argc--;
  101.             tsize = atol(*argv);
  102.             tsize *= 12L*10L;
  103.         }
  104.         break;
  105.  
  106.     case '0':
  107.     case '1':
  108.     case '2':
  109.     case '3':
  110.     case '4':
  111.     case '5':
  112.     case '6':
  113.     case '7':
  114.     case '8':
  115.     case '9':
  116.         incno = arg[-1];
  117.         break;
  118.  
  119.     case 'u':
  120.         uflag++;
  121.         break;
  122.  
  123.     default:
  124.         printf("bad key '%c%'\n", arg[-1]);
  125.         exit(1);
  126.     }
  127.     if(argc > 1) {
  128.         argv++;
  129.         argc--;
  130.         disk = *argv;
  131.     }
  132.  
  133.     getitime();
  134.     printf("     date = %s\n", prdate(spcl.c_date));
  135.     printf("dump date = %s\n", prdate(spcl.c_ddate));
  136.     printf("dumping %s to %s\n", disk, tape);
  137.     fi = open(disk, 0);
  138.     if(fi < 0) {
  139.         printf("dump: cannot open %s\n", disk);
  140.         exit(1);
  141.     }
  142.     otape();
  143.     printf("I\n");
  144.     esize = 0;
  145.     CLR(clrmap);
  146.     CLR(dirmap);
  147.     CLR(nodmap);
  148.  
  149.     pass(mark, (short *)NULL);
  150.     do {
  151.         printf("II\n");
  152.         nadded = 0;
  153.         pass(add, dirmap);
  154.     } while(nadded);
  155.  
  156.     bmapest(clrmap);
  157.     bmapest(nodmap);
  158.     printf("estimated %ld tape blocks on %d tape(s)\n",
  159.         esize, 0);
  160.  
  161.     printf("III\n");
  162.     bitmap(clrmap, TS_CLRI);
  163.     pass(dump, dirmap);
  164.     printf("IV\n");
  165.     pass(dump, nodmap);
  166.     putitime();
  167.     printf("DONE\n");
  168.     spcl.c_type = TS_END;
  169.     for(i=0; i<NTREC; i++)
  170.         spclrec();
  171.     printf("%ld tape blocks on %d tape(s)\n",
  172.         spcl.c_tapea, spcl.c_volume);
  173. }
  174.  
  175. pass(fn, map)
  176. int (*fn)();
  177. short *map;
  178. {
  179.     register i, j;
  180.     int bits;
  181.     ino_t mino;
  182.     daddr_t d;
  183.  
  184.     sync();
  185.     bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
  186.     mino = (sblock.s_isize-2) * INOPB;
  187.     ino = 0;
  188.     for(i=2;; i+=NI) {
  189.         if(ino >= mino)
  190.             break;
  191.         d = (unsigned)i;
  192.         for(j=0; j<INOPB*NI; j++) {
  193.             if(ino >= mino)
  194.                 break;
  195.             if((ino % MLEN) == 0) {
  196.                 bits = ~0;
  197.                 if(map != NULL)
  198.                     bits = *map++;
  199.             }
  200.             ino++;
  201.             if(bits & 1) {
  202.                 if(d != 0) {
  203.                     bread(d, (char *)itab, sizeof(itab));
  204.                     d = 0;
  205.                 }
  206.                 (*fn)(&itab[j]);
  207.             }
  208.             bits >>= 1;
  209.         }
  210.     }
  211. }
  212.  
  213. icat(ip, fn1, fn2)
  214. struct    dinode    *ip;
  215. int (*fn1)(), (*fn2)();
  216. {
  217.     register i;
  218.     daddr_t d[NADDR];
  219.  
  220.     l3tol(&d[0], &ip->di_addr[0], NADDR);
  221.     (*fn2)(d, NADDR-3);
  222.     for(i=0; i<NADDR; i++) {
  223.         if(d[i] != 0) {
  224.             if(i < NADDR-3)
  225.                 (*fn1)(d[i]); else
  226.                 indir(d[i], fn1, fn2, i-(NADDR-3));
  227.         }
  228.     }
  229. }
  230.  
  231. indir(d, fn1, fn2, n)
  232. daddr_t d;
  233. int (*fn1)(), (*fn2)();
  234. {
  235.     register i;
  236.     daddr_t    idblk[NINDIR];
  237.  
  238.     bread(d, (char *)idblk, sizeof(idblk));
  239.     if(n <= 0) {
  240.         spcl.c_type = TS_ADDR;
  241.         (*fn2)(idblk, NINDIR);
  242.         for(i=0; i<NINDIR; i++) {
  243.             d = idblk[i];
  244.             if(d != 0)
  245.                 (*fn1)(d);
  246.         }
  247.     } else {
  248.         n--;
  249.         for(i=0; i<NINDIR; i++) {
  250.             d = idblk[i];
  251.             if(d != 0)
  252.                 indir(d, fn1, fn2, n);
  253.         }
  254.     }
  255. }
  256.  
  257. mark(ip)
  258. struct dinode *ip;
  259. {
  260.     register f;
  261.  
  262.     f = ip->di_mode & IFMT;
  263.     if(f == 0)
  264.         return;
  265.     BIS(ino, clrmap);
  266.     if(f == IFDIR)
  267.         BIS(ino, dirmap);
  268.     if(ip->di_mtime >= spcl.c_ddate ||
  269.        ip->di_ctime >= spcl.c_ddate) {
  270.         BIS(ino, nodmap);
  271.         if (f != IFREG)
  272.             return;
  273.         est(ip);
  274.     }
  275. }
  276.  
  277. add(ip)
  278. struct dinode *ip;
  279. {
  280.  
  281.     if(BIT(ino, nodmap))
  282.         return;
  283.     nsubdir = 0;
  284.     dadded = 0;
  285.     icat(ip, dsrch, nullf);
  286.     if(dadded) {
  287.         BIS(ino, nodmap);
  288.         est(ip);
  289.         nadded++;
  290.     }
  291.     if(nsubdir == 0)
  292.         if(!BIT(ino, nodmap))
  293.             BIC(ino, dirmap);
  294. }
  295.  
  296. dump(ip)
  297. struct dinode *ip;
  298. {
  299.     register i;
  300.  
  301.     if(ntape) {
  302.         ntape = 0;
  303.         bitmap(nodmap, TS_BITS);
  304.     }
  305.     BIC(ino, nodmap);
  306.     spcl.c_dinode = *ip;
  307.     spcl.c_type = TS_INODE;
  308.     spcl.c_count = 0;
  309.     i = ip->di_mode & IFMT;
  310.     if(i != IFDIR && i != IFREG) {
  311.         spclrec();
  312.         return;
  313.     }
  314.     icat(ip, tapsrec, dmpspc);
  315. }
  316.  
  317. dmpspc(dp, n)
  318. daddr_t *dp;
  319. {
  320.     register i, t;
  321.  
  322.     spcl.c_count = n;
  323.     for(i=0; i<n; i++) {
  324.         t = 0;
  325.         if(dp[i] != 0)
  326.             t++;
  327.         spcl.c_addr[i] = t;
  328.     }
  329.     spclrec();
  330. }
  331.  
  332. bitmap(map, typ)
  333. short *map;
  334. {
  335.     register i, n;
  336.     char *cp;
  337.  
  338.     n = -1;
  339.     for(i=0; i<MSIZ; i++)
  340.         if(map[i])
  341.             n = i;
  342.     if(n < 0)
  343.         return;
  344.     spcl.c_type = typ;
  345.     spcl.c_count = (n*sizeof(map[0]) + BSIZE)/BSIZE;
  346.     spclrec();
  347.     cp = (char *)map;
  348.     for(i=0; i<spcl.c_count; i++) {
  349.         taprec(cp);
  350.         cp += BSIZE;
  351.     }
  352. }
  353.  
  354. spclrec()
  355. {
  356.     register i, *ip, s;
  357.  
  358.     spcl.c_inumber = ino;
  359.     spcl.c_magic = MAGIC;
  360.     spcl.c_checksum = 0;
  361.     ip = (int *)&spcl;
  362.     s = 0;
  363.     for(i=0; i<BSIZE/sizeof(*ip); i++)
  364.         s += *ip++;
  365.     spcl.c_checksum = CHECKSUM - s;
  366.     taprec((char *)&spcl);
  367. }
  368.  
  369. dsrch(d)
  370. daddr_t d;
  371. {
  372.     register char *cp;
  373.     register i;
  374.     register ino_t in;
  375.     struct direct dblk[DIRPB];
  376.  
  377.     if(dadded)
  378.         return;
  379.     bread(d, (char *)dblk, sizeof(dblk));
  380.     for(i=0; i<DIRPB; i++) {
  381.         in = dblk[i].d_ino;
  382.         if(in == 0)
  383.             continue;
  384.         cp = dblk[i].d_name;
  385.         if(cp[0] == '.') {
  386.             if(cp[1] == '\0')
  387.                 continue;
  388.             if(cp[1] == '.' && cp[2] == '\0')
  389.                 continue;
  390.         }
  391.         if(BIT(in, nodmap)) {
  392.             dadded++;
  393.             return;
  394.         }
  395.         if(BIT(in, dirmap))
  396.             nsubdir++;
  397.     }
  398. }
  399.  
  400. nullf()
  401. {
  402. }
  403.  
  404. bread(da, ba, c)
  405. daddr_t da;
  406. char *ba;
  407. {
  408.     register n;
  409.  
  410.     lseek(fi, da*512, 0);
  411.     n = read(fi, ba, c);
  412.     if(n != c)
  413.         printf("asked %d; got %d\n", c, n);
  414. }
  415.  
  416. CLR(map)
  417. register short *map;
  418. {
  419.     register n;
  420.  
  421.     n = MSIZ;
  422.     do
  423.         *map++ = 0;
  424.     while(--n);
  425. }
  426.  
  427.  
  428. char    tblock[NTREC][BSIZE];
  429. daddr_t    tdaddr[NTREC];
  430. int    trecno;
  431.  
  432. taprec(dp)
  433. char *dp;
  434. {
  435.     register i;
  436.  
  437.     for(i=0; i<BSIZE; i++)
  438.         tblock[trecno][i] = *dp++;
  439.     tdaddr[trecno] = 0;
  440.     trecno++;
  441.     spcl.c_tapea++;
  442.     if(trecno >= NTREC)
  443.         flusht();
  444. }
  445.  
  446. tapsrec(d)
  447. daddr_t d;
  448. {
  449.  
  450.     if(d == 0)
  451.         return;
  452.     tdaddr[trecno] = d;
  453.     trecno++;
  454.     spcl.c_tapea++;
  455.     if(trecno >= NTREC)
  456.         flusht();
  457. }
  458.  
  459. flusht()
  460. {
  461.     char place[100];
  462.     register i, si;
  463.     daddr_t d;
  464.  
  465.     while(trecno < NTREC)
  466.         tdaddr[trecno++] = 1;
  467.  
  468. loop:
  469.     d = 0;
  470.     for(i=0; i<NTREC; i++)
  471.         if(tdaddr[i] != 0)
  472.         if(d == 0 || tdaddr[i] < d) {
  473.             si = i;
  474.             d = tdaddr[i];
  475.         }
  476.     if(d != 0) {
  477.         bread(d, tblock[si], BSIZE);
  478.         tdaddr[si] = 0;
  479.         goto loop;
  480.     }
  481.     trecno = 0;
  482.     write(to, tblock[0], sizeof(tblock));
  483.     asize += sizeof(tblock)/density;
  484.     asize += 7;
  485.     if(asize > tsize) {
  486.         close(to);
  487.         printf("change tapes\n");
  488.         read(0, place, sizeof(place));
  489.         otape();
  490.     }
  491. }
  492.  
  493. otape()
  494. {
  495.     to = creat(tape, 0666);
  496.     if(to < 0) {
  497.         printf("dump: cannot create %s\n", tape);
  498.         exit(1);
  499.     }
  500.     asize = 0;
  501.     ntape++;
  502.     spcl.c_volume++;
  503.     spcl.c_type = TS_TAPE;
  504.     spclrec();
  505. }
  506.  
  507. char *
  508. prdate(d)
  509. time_t d;
  510. {
  511.     char *p;
  512.  
  513.     if(d == 0)
  514.         return("the epoch");
  515.     p = ctime(&d);
  516.     p[24] = 0;
  517.     return(p);
  518. }
  519.  
  520. getitime()
  521. {
  522.     register i, df;
  523.     struct idates idbuf;
  524.     char *fname;
  525.  
  526.     fname = disk;
  527. l1:
  528.     for(i=0; fname[i]; i++)
  529.         if(fname[i] == '/') {
  530.             fname += i+1;
  531.             goto l1;
  532.         }
  533.  
  534.     spcl.c_ddate = 0;
  535.     df = open(increm, 0);
  536.     if(df < 0) {
  537.         printf("cannot open %s\n", increm);
  538.         exit(1);
  539.     }
  540.  
  541. l2:
  542.     i = read(df, (char *)&idbuf, sizeof(idbuf));
  543.     if(i != sizeof(idbuf)) {
  544.         close(df);
  545.         return;
  546.     }
  547.     for(i=0;; i++) {
  548.         if(fname[i] != idbuf.id_name[i])
  549.             goto l2;
  550.         if(fname[i] == '\0')
  551.             break;
  552.     }
  553.     if(idbuf.id_incno >= incno)
  554.         goto l2;
  555.     if(idbuf.id_ddate <= spcl.c_ddate)
  556.         goto l2;
  557.     spcl.c_ddate = idbuf.id_ddate;
  558.     goto l2;
  559. }
  560.  
  561. putitime()
  562. {
  563.     register i, n, df;
  564.     struct idates idbuf;
  565.     char *fname;
  566.  
  567.     if(uflag == 0)
  568.         return;
  569.     fname = disk;
  570. l1:
  571.     for(i=0; fname[i]; i++)
  572.         if(fname[i] == '/') {
  573.             fname += i+1;
  574.             goto l1;
  575.         }
  576.  
  577.     spcl.c_ddate = 0;
  578.     df = open(increm, 2);
  579.     if(df < 0) {
  580.         printf("cannot open %s\n", increm);
  581.         exit(1);
  582.     }
  583.     n = 0;
  584. l2:
  585.     i = read(df, (char *)&idbuf, sizeof(idbuf));
  586.     if(i != sizeof(idbuf))
  587.         goto l3;
  588.     n++;
  589.     for(i=0;; i++) {
  590.         if(fname[i] != idbuf.id_name[i])
  591.             goto l2;
  592.         if(fname[i] == '\0')
  593.             break;
  594.     }
  595.     if(idbuf.id_incno != incno)
  596.         goto l2;
  597. l3:
  598.     lseek(df, (long)n*sizeof(idbuf), 0);
  599.     for(i=0;; i++) {
  600.         idbuf.id_name[i] = fname[i];
  601.         if(fname[i] == '\0')
  602.             break;
  603.     }
  604.     idbuf.id_incno = incno;
  605.     idbuf.id_ddate = spcl.c_date;
  606.     write(df, (char *)&idbuf, sizeof(idbuf));
  607.     close(df);
  608.     printf("level %c dump on %s\n", incno, prdate(spcl.c_date));
  609. }
  610.  
  611. est(ip)
  612. struct dinode *ip;
  613. {
  614.     long s;
  615.  
  616.     esize++;
  617.     s = (ip->di_size + BSIZE-1) / BSIZE;
  618.     esize += s;
  619.     if(s > NADDR-3) {
  620.         s -= NADDR-3;
  621.         s = (s + (BSIZE/sizeof(daddr_t))-1) / (BSIZE/sizeof(daddr_t));
  622.         esize += s;
  623.     }
  624. }
  625.  
  626. bmapest(map)
  627. short *map;
  628. {
  629.     register i, n;
  630.  
  631.     n = -1;
  632.     for(i=0; i<MSIZ; i++)
  633.         if(map[i])
  634.             n = i;
  635.     if(n < 0)
  636.         return;
  637.     esize++;
  638.     esize += (n + (BSIZE/sizeof(short))-1) / (BSIZE/sizeof(short));
  639. }
  640.