Annotation of coherent/d/bin/dump/old/dump.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Dump a filesystem onto a
        !             3:  * tape. Dump only those files that
        !             4:  * have checked since the last
        !             5:  * dump.
        !             6:  */
        !             7: #include <stdio.h>
        !             8: #include <types.h>
        !             9: #include <discbuf.h>
        !            10: #include <dumptape.h>
        !            11: #include <canon.h>
        !            12: #include <filsys.h>
        !            13: 
        !            14: char   *dtn    = DTAPE;                /* Tape name */
        !            15: FILE   *dtp;                           /* Tape file pointer */
        !            16: char   *fsn    = DFSYS;                /* File system name */
        !            17: int    block   = 20;                   /* Blocking factor */
        !            18: int    density = 1600;                 /* Tape density, bpi */
        !            19: long   length  = 2300L*12L*100L;       /* Length of tape, inches/100 */
        !            20: long   used;                           /* Tape used, inches/100 */
        !            21: struct dumpheader dh;                  /* Dump header */
        !            22: int    reel    = 1;                    /* Reel # */
        !            23: int    uflag   = 1;                    /* Update dates file flag */
        !            24: int    vflag;                          /* Verbose flag */
        !            25: int    Sflag;                          /* Set when sizes are in blocks */
        !            26: int    level   = 9;                    /* Dump level */
        !            27: time_t bdate;                          /* Date at beginning of dump */
        !            28: time_t ddate;                          /* Dump since date */
        !            29: char   *map;                           /* Map pointer */
        !            30: char   *ddbuf;                         /* Dump data buffer */
        !            31: char   *ddend;                         /* Dump data buffer end pointer */
        !            32: int    ddnbuf;                         /* Buffer size */
        !            33: union  dumpdata *ddptr;                /* Pointer to current item */
        !            34: ino_t  isize;                          /* # of inodes */
        !            35: char   dev[DIRSIZ+1];                  /* Name of device, squashed */
        !            36: char   fname[6];                       /* File system name */
        !            37: char   fpack[6];                       /* File system pack name */
        !            38: long   ninodes;                        /* # of inodes dumped */
        !            39: long   nblocks;                        /* # of blocks of data */
        !            40: long   nsparse;                        /* # of sparse blocks deleted */
        !            41: char   helpmessage[]           = "\
        !            42: Usage: dump [bdfsuvS0123456789 [args]] filesystem ...\n\
        !            43: ";
        !            44: 
        !            45: /*
        !            46:  * Tables used by imap.
        !            47:  * This effectively implements
        !            48:  * the access polynomial for the indirect
        !            49:  * blocks.
        !            50:  */
        !            51: daddr_t        ranges[]        = {
        !            52:        ND,
        !            53:        ND+(daddr_t)1*NBN,
        !            54:        ND+(daddr_t)1*NBN + (daddr_t)1*NBN*NBN,
        !            55:        ND+(daddr_t)1*NBN + (daddr_t)1*NBN*NBN + (daddr_t)1*NBN*NBN*NBN
        !            56: };
        !            57: 
        !            58: char   offsets[]       = {
        !            59:        0,
        !            60:        ND,
        !            61:        ND+1,
        !            62:        ND+1+1
        !            63: };
        !            64: 
        !            65: daddr_t        coeff[]         = {
        !            66:        1,
        !            67:        (daddr_t) NBN,
        !            68:        (daddr_t) NBN*NBN,
        !            69:        (daddr_t) NBN*NBN*NBN
        !            70: };
        !            71: 
        !            72: /*
        !            73:  * One pass compilers are
        !            74:  * such fun.
        !            75:  */
        !            76: long   time();
        !            77: long   ddlen();
        !            78: union  dumpdata *ddnextbuf();
        !            79: long   getddate();
        !            80: char   *ctime();
        !            81: daddr_t        imap();
        !            82: char   *calloc();
        !            83: 
        !            84: main(argc, argv)
        !            85: char *argv[];
        !            86: {
        !            87:        register DISCBUF *dbp;
        !            88:        register struct filsys *fsp;
        !            89:        unsigned fi;
        !            90: 
        !            91:        init(argc, argv);
        !            92:        if (*fsn == 0)
        !            93:                fatal("no filesystem specified");
        !            94:        if ((dbfp=fopen(fsn, "r")) == NULL)
        !            95:                fatal("%s: cannot open filesystem", fsn);
        !            96:        if ((dtp=fopen(dtn, "w")) == NULL)
        !            97:                fatal("%s: cannot open dump file",  dtn);
        !            98:        squash(dev, fsn);
        !            99:        bdate = time((long *) 0);
        !           100:        ddate = getddate();
        !           101:        if (vflag) {
        !           102:                if (ddate == 0)
        !           103:                        fprintf(stderr, "dump: since epoch\n");
        !           104:                else
        !           105:                        fprintf(stderr, "dump: since %s", ctime(&ddate));
        !           106:        }
        !           107:        dbclaim(5);
        !           108:        sync();
        !           109:        dbp = dbread((long) SUPERI);
        !           110:        fsp = (struct filsys *) (dbp->db_data);
        !           111:        fi = fsp->s_isize;
        !           112:        canshort(fi);
        !           113:        isize = (fi-INODEI)*INOPB;
        !           114:        strncpy(fname, fsp->s_fname, sizeof(fname));
        !           115:        strncpy(fpack, fsp->s_fpack, sizeof(fpack));
        !           116:        dbfree(dbp, 0);
        !           117:        if ((map=calloc(isize, sizeof(char))) == NULL)
        !           118:                fatal("out of memory (map)");
        !           119:        walk((ino_t) ROOTIN);
        !           120:        nextvol();
        !           121:        dumpinomap();
        !           122:        dump(DD_DIR);           /* Directories */
        !           123:        dump(0);                /* Files */
        !           124:        dumpfinish();
        !           125:        if (uflag)
        !           126:                putddate();
        !           127:        if (vflag) {
        !           128:                if (Sflag)
        !           129:                        used /= 512; else
        !           130:                        used /= 100*12;
        !           131:                fprintf(stderr, "dump: length is %D ", used);
        !           132:                if (Sflag)
        !           133:                        fprintf(stderr, "blocks\n");
        !           134:                else if (used == 1)
        !           135:                        fprintf(stderr, "foot\n");
        !           136:                else
        !           137:                        fprintf(stderr, "feet\n");
        !           138:                fprintf(stderr, "dump: %D inodes, ",  ninodes);
        !           139:                fprintf(stderr, "%D real blocks, ",   nblocks);
        !           140:                fprintf(stderr, "%D sparse blocks\n", nsparse);
        !           141:        }
        !           142:        exit(0);
        !           143: }
        !           144: 
        !           145: /*
        !           146:  * Scan the command line and
        !           147:  * set options. Perhaps reset the name
        !           148:  * of the filesystem, the dump tape
        !           149:  * and the dump origin.
        !           150:  */
        !           151: init(argc, argv)
        !           152: char *argv[];
        !           153: {
        !           154:        register char *p;
        !           155:        register c, i;
        !           156: 
        !           157:        if (argc > 1) {
        !           158:                uflag = 0;
        !           159:                i = 1;
        !           160:                p = argv[1];
        !           161:                while ((c = *p++) != '\0') {
        !           162:                        switch (c) {
        !           163: 
        !           164:                        case 'f':
        !           165:                                if (++i >= argc)
        !           166:                                        usage();
        !           167:                                dtn = argv[i];
        !           168:                                break;
        !           169: 
        !           170:                        case 'u':
        !           171:                                uflag = 1;
        !           172:                                break;
        !           173: 
        !           174:                        case 'v':
        !           175:                                vflag = 1;
        !           176:                                break;
        !           177: 
        !           178:                        case 's':
        !           179:                                if (++i >= argc)
        !           180:                                        usage();
        !           181:                                length = (long)12*100*num(argv[i], "length",
        !           182:                                        600, 4800);
        !           183:                                break;
        !           184: 
        !           185:                        case 'S':
        !           186:                                if (++i >= argc)
        !           187:                                        usage();
        !           188:                                Sflag++;
        !           189:                                length = (long)512 * num(argv[i], "block size",
        !           190:                                        0, (unsigned)65535L);
        !           191:                                break;
        !           192: 
        !           193:                        case 'b':
        !           194:                                if (++i >= argc)
        !           195:                                        usage();
        !           196:                                block = num(argv[i], "blocking", 1, 20);
        !           197:                                break;
        !           198: 
        !           199:                        case 'd':
        !           200:                                if (++i >= argc)
        !           201:                                        usage();
        !           202:                                density = num(argv[i], "density", 800, 6250);
        !           203:                                break;
        !           204: 
        !           205:                        case '0':
        !           206:                        case '1':
        !           207:                        case '2':
        !           208:                        case '3':
        !           209:                        case '4':
        !           210:                        case '5':
        !           211:                        case '6':
        !           212:                        case '7':
        !           213:                        case '8':
        !           214:                        case '9':
        !           215:                                level = c-'0';
        !           216:                                break;
        !           217: 
        !           218:                        default:
        !           219:                                usage();
        !           220:                        }
        !           221:                }
        !           222:                if (++i < argc)
        !           223:                        fsn = argv[i];
        !           224:        }
        !           225: }
        !           226: 
        !           227: /*
        !           228:  * Collect and range check
        !           229:  * numeric arguments.
        !           230:  */
        !           231: num(s, msg, ll, hl)
        !           232: register char *s;
        !           233: char *msg;
        !           234: unsigned ll, hl;
        !           235: {
        !           236:        register c, n;
        !           237: 
        !           238:        n = 0;
        !           239:        while ((c=*s++)>='0' && c<='9')
        !           240:                n = 10*n + c - '0';
        !           241:        if (c!='\0' || n<ll || n>hl)
        !           242:                fatal("bad %s specification", msg);
        !           243:        return (n);
        !           244: }
        !           245: 
        !           246: /*
        !           247:  * Walk down the file system,
        !           248:  * looking for files that should be
        !           249:  * dumped. Mark them in the map.
        !           250:  * All directories that lead to changed
        !           251:  * inodes are forced to be dumped.
        !           252:  */
        !           253: walk(ino)
        !           254: ino_t ino;
        !           255: {
        !           256:        register DISCBUF *dbp;
        !           257:        register struct direct *dirp;
        !           258:        int flag, nent, ndir;
        !           259:        long pb, dirb;
        !           260:        struct dinode dinode;
        !           261:        ino_t ent[BUFSIZ/sizeof(struct direct)];
        !           262: 
        !           263:        if ((map[ino-1]&DD_DEJA) != 0)
        !           264:                return (0);
        !           265:        ireadin(&dinode, ino);
        !           266:        canshort(dinode.di_mode);
        !           267:        cantime(dinode.di_ctime);
        !           268:        /*
        !           269:         * Normally pipes stay in core,
        !           270:         * and are not in directories. Just to be
        !           271:         * safe we pretend any pipe is a clear
        !           272:         * inode.
        !           273:         */
        !           274:        if ((dinode.di_mode&IFMT) == IFPIPE)
        !           275:                return (0);
        !           276:        map[ino-1] |= DD_BUSY;
        !           277:        if ((dinode.di_mode&IFMT) != IFDIR) {
        !           278:                if (level==0 || dinode.di_ctime>ddate) {
        !           279:                        map[ino-1] |= DD_DUMP;
        !           280:                        return (1);
        !           281:                }
        !           282:                return (0);
        !           283:        }
        !           284:        map[ino-1] |= DD_DEJA|DD_DIR;
        !           285:        flag = dirb = 0;
        !           286:        cansize(dinode.di_size);
        !           287:        while (dinode.di_size != 0) {
        !           288:                if ((pb = imap(&dinode, dirb++)) == 0) {
        !           289:                        dinode.di_size -= BUFSIZ;
        !           290:                        continue;
        !           291:                }
        !           292:                /*
        !           293:                 * Writing the code is this
        !           294:                 * strange fashon makes it require 1 cache
        !           295:                 * buffer, not 1 per level.
        !           296:                 */
        !           297:                dbp = dbread(pb);
        !           298:                nent = 0;
        !           299:                ndir = BUFSIZ / sizeof(struct direct);
        !           300:                if (dinode.di_size < BUFSIZ)
        !           301:                        ndir = dinode.di_size / sizeof(struct direct);
        !           302:                dirp = (struct direct *) (dbp->db_data);
        !           303:                while (ndir--) {
        !           304:                        if (dirp->d_ino != 0) {
        !           305:                                ent[nent] = dirp->d_ino;
        !           306:                                canino(ent[nent]);
        !           307:                                ++nent;
        !           308:                        }
        !           309:                        ++dirp;
        !           310:                        dinode.di_size -= sizeof(struct direct);
        !           311:                }
        !           312:                dbfree(dbp, 0);
        !           313:                while (nent--) {
        !           314:                        if (walk(ent[nent]))
        !           315:                                flag = 1;
        !           316:                }
        !           317:        }
        !           318:        if (flag!=0 || level==0 || dinode.di_ctime>ddate)
        !           319:                map[ino-1] |= DD_DUMP;
        !           320:        map[ino-1] &= ~DD_DEJA;
        !           321:        return (flag);
        !           322: }
        !           323: 
        !           324: /*
        !           325:  * Read in an inode.
        !           326:  * Leave it in the buffer in disc
        !           327:  * (that is, cannonical) format.
        !           328:  */
        !           329: ireadin(diop, ino)
        !           330: register struct dinode *diop;
        !           331: ino_t ino;
        !           332: {
        !           333:        register struct dinode *diip;
        !           334:        DISCBUF *dbp;
        !           335: 
        !           336:        dbp = dbread((long)((ino-1)/INOPB + INODEI));
        !           337:        diip = (struct dinode *)(dbp->db_data) + (ino-1)%INOPB;
        !           338:        *diop = *diip;          /* Structure assignment */
        !           339:        dbfree(dbp, 0);
        !           340: }
        !           341: 
        !           342: /*
        !           343:  * Map logical block `lb' in the
        !           344:  * file whose in core inode is pointed to
        !           345:  * by `ip' to the associated physical
        !           346:  * block. Return 0 if the block will not
        !           347:  * map.
        !           348:  */
        !           349: daddr_t
        !           350: imap(ip, lb)
        !           351: register struct dinode *ip;
        !           352: daddr_t lb;
        !           353: {
        !           354:        register il;
        !           355:        daddr_t bpos, pb;
        !           356:        DISCBUF *dbp;
        !           357:        register daddr_t *bp;
        !           358:        register daddr_t addrs[NADDR];
        !           359: 
        !           360:        l3tol(addrs, ip->di_addr, NADDR);
        !           361:        for (il=0; il<4; il++)
        !           362:                if (lb < ranges[il]) {
        !           363:                        if (il != 0)
        !           364:                                lb -= ranges[il-1];
        !           365:                        bpos = lb/coeff[il];
        !           366:                        lb %= coeff[il];
        !           367:                        bp = &addrs[(int)bpos + offsets[il]];
        !           368:                        if ((pb = *bp) != 0) {
        !           369:                                while (il-- > 0) {
        !           370:                                        dbp = dbread((long) pb);
        !           371:                                        bpos = lb/coeff[il];
        !           372:                                        lb %= coeff[il];
        !           373:                                        bp = (daddr_t *)(dbp->db_data) + bpos;
        !           374:                                        dbfree(dbp, 0);
        !           375:                                        if ((pb = *bp) == 0)
        !           376:                                                break;
        !           377:                                        candaddr(pb);
        !           378:                                }
        !           379:                        }
        !           380:                        return (pb);
        !           381:                }
        !           382:        return (0);
        !           383: }
        !           384: 
        !           385: 
        !           386: /*
        !           387:  * Dump out the map.
        !           388:  * The map is packed into ordinary
        !           389:  * tape blocks.
        !           390:  */
        !           391: dumpinomap()
        !           392: {
        !           393:        register ino_t ibase;
        !           394:        register char *imapp;
        !           395:        register nmap;
        !           396:        union dumpdata *ddp;
        !           397: 
        !           398:        ibase = 0;
        !           399:        while ((nmap = isize-ibase) > 0) {
        !           400:                ddp = ddnextbuf();
        !           401:                ddp->dd_type = DD_MAP;
        !           402:                ddp->dd_ino = ibase+1;
        !           403:                if (nmap > BUFSIZ)
        !           404:                        nmap = BUFSIZ;
        !           405:                ddp->dd_nmap = nmap;
        !           406:                canint(ddp->dd_type);
        !           407:                canino(ddp->dd_ino);
        !           408:                canint(ddp->dd_nmap);
        !           409:                imapp = &ddp->dd_map[0];
        !           410:                do {
        !           411:                        *imapp++ = map[ibase++];
        !           412:                } while (--nmap);
        !           413:        }
        !           414: }
        !           415: 
        !           416: /*
        !           417:  * Fabricate a dump header and
        !           418:  * write it to the dump file. All the
        !           419:  * stuff in the header is in the
        !           420:  * usual canonical format. This makes it
        !           421:  * a little easier to move tapes from
        !           422:  * one machine to another.
        !           423:  */
        !           424: dumpheader()
        !           425: {
        !           426:        register char *p;
        !           427:        register checksum;
        !           428: 
        !           429:        dh.dh_magic = DH_MAG;
        !           430:        dh.dh_nino = isize;
        !           431:        dh.dh_bdate = bdate;
        !           432:        dh.dh_ddate = ddate;
        !           433:        dh.dh_level = level;
        !           434:        dh.dh_reel = reel++;
        !           435:        dh.dh_blocking = block;
        !           436:        dh.dh_nbyte = Sflag ? length : 0;
        !           437:        strncpy(dh.dh_dev, dev, DIRSIZ);
        !           438:        strncpy(dh.dh_fname, fname, 6);
        !           439:        strncpy(dh.dh_fpack, fpack, 6);
        !           440:        p = (char *) &dh;
        !           441:        checksum = 0;
        !           442:        while (p < (char *) &dh.dh_checksum)
        !           443:                checksum += (*p++) & 0377;
        !           444:        dh.dh_checksum = checksum;
        !           445:        canint(dh.dh_magic);
        !           446:        canino(dh.dh_nino);
        !           447:        cantime(dh.dh_bdate);
        !           448:        cantime(dh.dh_ddate);
        !           449:        canint(dh.dh_level);
        !           450:        canint(dh.dh_reel);
        !           451:        canint(dh.dh_blocking);
        !           452:        cansize(dh.dh_nbyte);
        !           453:        canint(dh.dh_checksum);
        !           454:        if (write(fileno(dtp), &dh, sizeof dh) != sizeof dh)
        !           455:                fatal("header write error");
        !           456: }
        !           457: 
        !           458: /*
        !           459:  * Put out the end of tape item
        !           460:  * and the very end of the very last
        !           461:  * dump tape.
        !           462:  */
        !           463: dumpfinish()
        !           464: {
        !           465:        register union dumpdata *ddp;
        !           466: 
        !           467:        ddp = ddnextbuf();
        !           468:        ddp->dd_type = DD_EOT;
        !           469:        canint(ddp->dd_type);
        !           470:        ddflush();
        !           471: }
        !           472: 
        !           473: /*
        !           474:  * Dump out all inodes with
        !           475:  * the appropriate flags set in the
        !           476:  * map.
        !           477:  */
        !           478: dump(flag)
        !           479: register flag;
        !           480: {
        !           481:        register ino_t i;
        !           482:        register mapentry;
        !           483: 
        !           484:        for (i=0; i<isize; ++i) {
        !           485:                mapentry = map[i];
        !           486:                if ((mapentry&DD_DUMP)!=0 && (mapentry&DD_DIR)==flag) {
        !           487:                        dumpi(i+1);
        !           488:                        map[i] = 0;
        !           489:                }
        !           490:        }
        !           491: }
        !           492: 
        !           493: /*
        !           494:  * Dump an inode.
        !           495:  */
        !           496: dumpi(ino)
        !           497: ino_t ino;
        !           498: {
        !           499:        struct dinode dinode;
        !           500:        register union dumpdata *ddp;
        !           501:        register DISCBUF *dbp;
        !           502:        daddr_t lb, pb;
        !           503:        int size;
        !           504: 
        !           505:        ++ninodes;
        !           506:        ireadin(&dinode, ino);
        !           507:        ddp = ddnextbuf();
        !           508:        ddp->dd_type = DD_INO;
        !           509:        ddp->dd_ino  = ino;
        !           510:        canint(ddp->dd_type);
        !           511:        canino(ddp->dd_ino);
        !           512:        copyb(&ddp->dd_dinode, &dinode, sizeof(struct dinode));
        !           513:        lb = 0;
        !           514:        cansize(dinode.di_size);
        !           515:        while (dinode.di_size != 0) {
        !           516:                pb = imap(&dinode, lb);
        !           517:                size = dinode.di_size<BUFSIZ ? dinode.di_size : BUFSIZ;
        !           518:                if (pb != 0) {
        !           519:                        dbp = dbread(pb);
        !           520:                        if (allzeros(dbp->db_data, size) == 0) {
        !           521:                                ++nblocks;
        !           522:                                ddp = ddnextbuf();
        !           523:                                ddp->dd_type = DD_DATA;
        !           524:                                ddp->dd_ino  = ino;
        !           525:                                ddp->dd_block = lb;
        !           526:                                ddp->dd_size = size;
        !           527:                                canint(ddp->dd_type);
        !           528:                                canino(ddp->dd_ino);
        !           529:                                candaddr(ddp->dd_block);
        !           530:                                canint(ddp->dd_size);
        !           531:                                copyb(ddp->dd_data, dbp->db_data, size);
        !           532:                        } else
        !           533:                                ++nsparse;
        !           534:                        dbfree(dbp, 0);
        !           535:                }
        !           536:                dinode.di_size -= size;
        !           537:                ++lb;
        !           538:        }
        !           539: }
        !           540: 
        !           541: /*
        !           542:  * Check if a disc block is all
        !           543:  * zero bytes. True return if it is.
        !           544:  */
        !           545: allzeros(cp, nb)
        !           546: register char  *cp;
        !           547: register int   nb;
        !           548: {
        !           549:        do {
        !           550:                if (*cp++ != 0)
        !           551:                        return (0);
        !           552:        } while (--nb);
        !           553:        return (1);
        !           554: }
        !           555: 
        !           556: /*
        !           557:  * Copy a block of bytes.
        !           558:  */
        !           559: copyb(atp, afp, anb)
        !           560: char *atp, *afp;
        !           561: {
        !           562:        register char *tp, *fp;
        !           563:        register nb;
        !           564: 
        !           565:        if ((nb = anb) != 0) {
        !           566:                tp = atp;
        !           567:                fp = afp;
        !           568:                do {
        !           569:                        *tp++ = *fp++;
        !           570:                } while (--nb);
        !           571:        }
        !           572: }
        !           573: 
        !           574: /*
        !           575:  * Return a pointer to the
        !           576:  * next data buffer.
        !           577:  */
        !           578: union  dumpdata *
        !           579: ddnextbuf()
        !           580: {
        !           581:        register char *p;
        !           582:        register n;
        !           583: 
        !           584:        if (ddbuf == NULL) {
        !           585:                ddnbuf = block * sizeof(union dumpdata);
        !           586:                if ((ddbuf = malloc(ddnbuf)) == NULL)
        !           587:                        fatal("out of memory (buffer)");
        !           588:                ddend = &ddbuf[ddnbuf];
        !           589:                ddptr = (union dumpdata *) ddbuf;
        !           590:        }
        !           591:        if ((char *) ddptr == ddend) {
        !           592:                ddflush();
        !           593:                ddptr = (union dumpdata *) ddbuf;
        !           594:        }
        !           595:        if ((char *) ddptr == ddbuf) {
        !           596:                p = ddbuf;
        !           597:                n = ddnbuf;
        !           598:                do {
        !           599:                        *p++ = 0;
        !           600:                } while (--n);
        !           601:        }
        !           602:        return (ddptr++);
        !           603: }
        !           604: 
        !           605: /*
        !           606:  * Write out the big data buffer.
        !           607:  */
        !           608: ddflush()
        !           609: {
        !           610:        used += ddlen(ddnbuf);
        !           611:        if (used >= length) {
        !           612:                nextvol();
        !           613:                used += ddlen(ddnbuf);
        !           614:        }
        !           615:        if (write(fileno(dtp), ddbuf, ddnbuf) != ddnbuf)
        !           616:                fatal("dump write error");
        !           617: }
        !           618: 
        !           619: /*
        !           620:  * Request next dump volume.
        !           621:  */
        !           622: nextvol()
        !           623: {
        !           624:        char buf[40];
        !           625: 
        !           626:        if (Sflag != 0 || reel != 1) {
        !           627:                fclose(dtp);
        !           628:                fprintf(stderr, "dump: mount %s %d, type return key ...",
        !           629:                        Sflag ? "volume" : "reel", reel);
        !           630:                if (gets(buf) == NULL)
        !           631:                        exit(1);
        !           632:                if ((dtp = fopen(dtn, "w")) == NULL)
        !           633:                        fatal("%s: cannot open dump file", dtn);
        !           634:        }
        !           635:        dumpheader();
        !           636:        used = ddlen(sizeof(dh));
        !           637: }
        !           638: 
        !           639: /*
        !           640:  * Given a record size in bytes,
        !           641:  * return the number of inches/100 of tape
        !           642:  * that will get used.
        !           643:  * For blocked devices, the granularity is
        !           644:  * actually in bytes.
        !           645:  */
        !           646: long
        !           647: ddlen(nbytes)
        !           648: {
        !           649:        if (Sflag)
        !           650:                return (nbytes);
        !           651:        return (100L*((nbytes+density-1)/density) + 75);
        !           652: }
        !           653: 
        !           654: /*
        !           655:  * Update the dump date in the
        !           656:  * dump date file. The date used is the
        !           657:  * date at the beginning of the dump.
        !           658:  */
        !           659: putddate()
        !           660: {
        !           661:        register FILE *ddfp;
        !           662:        struct idates id;
        !           663: 
        !           664:        if ((ddfp = fopen(DDATE, "r+w")) == NULL) {
        !           665:                fprintf(stderr, "dump: cannot update dump date\n");
        !           666:                return;
        !           667:        }
        !           668:        while (fread(&id, sizeof(id), 1, ddfp) == 1) {
        !           669:                if (strncmp(id.id_name, dev, DIRSIZ) == 0
        !           670:                && id.id_incno==level) {
        !           671:                        fseek(ddfp, (long)-sizeof(id), 1);
        !           672:                        break;
        !           673:                }
        !           674:        }
        !           675:        strncpy(id.id_name, dev, DIRSIZ);
        !           676:        id.id_incno = level;
        !           677:        id.id_ddate = bdate;
        !           678:        if (fwrite(&id, sizeof(id), 1, ddfp) != 1)
        !           679:                fprintf(stderr, "dump: error updating date file\n");
        !           680:        fclose(ddfp);
        !           681: }
        !           682: 
        !           683: /*
        !           684:  * Get dump date.
        !           685:  */
        !           686: long
        !           687: getddate()
        !           688: {
        !           689:        register FILE *ddfp;
        !           690:        register long ddate;
        !           691:        struct idates id;
        !           692: 
        !           693:        ddate = 0;
        !           694:        if ((ddfp = fopen(DDATE, "r")) != NULL) {
        !           695:                while (fread(&id, sizeof(id), 1, ddfp) == 1) {
        !           696:                        if (strncmp(id.id_name, dev, DIRSIZ)==0
        !           697:                        && id.id_incno<level
        !           698:                        && id.id_ddate>ddate)
        !           699:                                ddate = id.id_ddate;
        !           700:                }
        !           701:                fclose(ddfp);
        !           702:        }
        !           703:        return (ddate);
        !           704: }
        !           705: 
        !           706: /*
        !           707:  * Print out a fatal diagnostic
        !           708:  * and die.
        !           709:  */
        !           710: fatal(a)
        !           711: {
        !           712:        fprintf(stderr, "dump: %r", &a);
        !           713:        fprintf(stderr, "\n");
        !           714:        exit(1);
        !           715: }
        !           716: 
        !           717: /*
        !           718:  * Print out a usage message and
        !           719:  * exit. If you can figure out how to use
        !           720:  * dump from the usage message you are
        !           721:  * a better man than I.
        !           722:  */
        !           723: usage()
        !           724: {
        !           725:        fprintf(stderr, helpmessage);
        !           726:        exit(1);
        !           727: }
        !           728: 
        !           729: /*
        !           730:  * Squash off any structure
        !           731:  * before the last part of a file
        !           732:  * name and put it in the supplied
        !           733:  * buffer.
        !           734:  */
        !           735: squash(tp, fp)
        !           736: register char *tp, *fp;
        !           737: {
        !           738:        register char *np;
        !           739: 
        !           740:        np = fp;
        !           741:        while (*fp != '\0') {
        !           742:                if (*fp == '/')
        !           743:                        np = fp+1;
        !           744:                ++fp;
        !           745:        }
        !           746:        while (*tp++ = *np++)
        !           747:                ;
        !           748: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.