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

1.1     ! root        1: /*
        !             2:  * dumpdir [af [dumpfile]]
        !             3:  * a   Show all entries (include `.' and `..').
        !             4:  * f   Use `dumpfile', not default.
        !             5:  */
        !             6: #include <stdio.h>
        !             7: #include <dumptape.h>
        !             8: #include <canon.h>
        !             9: #include <sys/mdata.h>
        !            10: #include <signal.h>
        !            11: 
        !            12: /*
        !            13:  * Structure used to remember
        !            14:  * things about all the directories
        !            15:  * on the tape.
        !            16:  */
        !            17: struct dlist
        !            18: {
        !            19:        struct  dlist   *dl_dlp;        /* Link to next */
        !            20:        ino_t   dl_ino;                 /* Inumber */
        !            21:        int     dl_dejavu;              /* Already seen flag */
        !            22:        long    dl_seek;                /* Tempfile base */
        !            23:        long    dl_size;                /* Size */
        !            24: };
        !            25: 
        !            26: char   *dtn    = DTAPE;                /* Tape name */
        !            27: FILE   *dtp;                           /* Tape file pointer */
        !            28: char   tfn[30] = "/tmp/ddXXXXXX";      /* Temp file name */
        !            29: FILE   *tfp;                           /* Temp file pointer */
        !            30: int    aflag;                          /* All flag */
        !            31: int    is_open;                        /* dump device open? */
        !            32: fsize_t        length = 1;                     /* Length in bytes of volume */
        !            33: fsize_t        nread;                          /* Number of bytes read from volume */
        !            34: struct dlist   *dlist;                 /* List of remembered directories */
        !            35: struct dlist   *droot;                 /* Pointer to first directory */
        !            36: char   dstr[1000];                     /* Name string */
        !            37: char   *dstrp  = &dstr[0];             /* Pointer into the above */
        !            38: int    reel    = 1;                    /* Reel # */
        !            39: char   *ddbuf;                         /* Dump data buffer */
        !            40: char   *ddend;                         /* Ptr to end of dump data buffer */
        !            41: int    ddnbuf;                         /* Size of buffer (bytes) */
        !            42: union  dumpdata *ddptr;                /* Ptr to current record in buffer */
        !            43: char   *map;                           /* Inode map */
        !            44: 
        !            45: union  dumpdata *readdump();
        !            46: struct dlist    *findnode();
        !            47: int    cleanup();
        !            48: char   *calloc();
        !            49: 
        !            50: main(argc, argv)
        !            51: char *argv[];
        !            52: {
        !            53:        register char *p;
        !            54:        register c, i;
        !            55: 
        !            56:        if (argc > 1) {
        !            57:                i = 1;
        !            58:                p = argv[1];
        !            59:                while ((c = *p++) != '\0') {
        !            60:                        switch (c) {
        !            61: 
        !            62:                        case 'a':
        !            63:                                aflag = 1;
        !            64:                                break;
        !            65: 
        !            66:                        case 'f':
        !            67:                                if (++i >= argc)
        !            68:                                        usage();
        !            69:                                dtn = argv[i];
        !            70:                                break;
        !            71: 
        !            72:                        default:
        !            73:                                usage();
        !            74:                        }
        !            75:                }
        !            76:        }
        !            77:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
        !            78:                signal(SIGINT, cleanup);
        !            79:        mktemp(tfn);
        !            80:        if ((tfp=fopen(tfn, "w")) == NULL
        !            81:        ||  (tfp=freopen(tfn, "r+w", tfp)) == NULL)
        !            82:                fatal("%s: cannot create temporary file", tfn);
        !            83:        nextvol();
        !            84:        readdirs();
        !            85:        if (droot == NULL)
        !            86:                fatal("no directories");
        !            87:        dumpdirs(droot);
        !            88:        delexit(0);
        !            89: }
        !            90: 
        !            91: /*
        !            92:  * This routine has two jobs.
        !            93:  * It reads in the dump file header and
        !            94:  * checks it out, looking for strangenesses
        !            95:  * in format. It also is responsible for
        !            96:  * using information in the header to
        !            97:  * allocate the necessary map and dump I/O
        !            98:  * buffers.
        !            99:  */
        !           100: readhead()
        !           101: {
        !           102:        static struct dumpheader dh;
        !           103:        register char *p;
        !           104:        register checksum;
        !           105: 
        !           106:        if (read(fileno(dtp), &dh, sizeof dh) != sizeof dh)
        !           107:                fatal("header read error");
        !           108:        nread = sizeof dh;
        !           109:        canint(dh.dh_magic);
        !           110:        canino(dh.dh_nino);
        !           111:        cantime(dh.dh_bdate);
        !           112:        cantime(dh.dh_ddate);
        !           113:        canint(dh.dh_level);
        !           114:        canint(dh.dh_reel);
        !           115:        canint(dh.dh_blocking);
        !           116:        cansize(dh.dh_nbyte);
        !           117:        canint(dh.dh_checksum);
        !           118:        if (dh.dh_magic != DH_MAG)
        !           119:                fatal("not a dump");
        !           120:        p = (char *) &dh;
        !           121:        checksum = 0;
        !           122:        while (p < (char *) &dh.dh_checksum)
        !           123:                checksum += (*p++) & 0377;
        !           124:        if (checksum != dh.dh_checksum)
        !           125:                fatal("header checksum error");
        !           126:        if (dh.dh_reel != reel)
        !           127:                fatal("wrong reel (is %d, not %d)", dh.dh_reel, reel);
        !           128:        ++reel;
        !           129:        if (map != NULL)
        !           130:                free(map);
        !           131:        if (ddbuf != NULL)
        !           132:                free(ddbuf);
        !           133:        if ((map = calloc(sizeof(char), (dh.dh_nino+NBCHAR-1)/NBCHAR)) == NULL)
        !           134:                fatal("out of memory (map)");
        !           135:        ddnbuf = dh.dh_blocking * sizeof(union dumpdata);
        !           136:        if ((ddbuf = malloc(ddnbuf)) == NULL)
        !           137:                fatal("out of memory (buffer)");
        !           138:        ddend = &ddbuf[ddnbuf];
        !           139:        ddptr = (union dumpdata *) ddend;
        !           140:        length = dh.dh_nbyte;
        !           141: }
        !           142: 
        !           143: /*
        !           144:  * Read in all the directories.
        !           145:  * This routine assumes that the map entries
        !           146:  * have been put out before the inodes and
        !           147:  * that all the directories have been put out
        !           148:  * before the files.
        !           149:  */
        !           150: readdirs()
        !           151: {
        !           152:        register union dumpdata *ddp;
        !           153:        register struct dlist *dlp;
        !           154: 
        !           155:        while ((ddp=readdump()) != NULL) {
        !           156:                canint(ddp->dd_type);
        !           157:                switch (ddp->dd_type) {
        !           158: 
        !           159:                case DD_EOT:
        !           160:                        return;
        !           161: 
        !           162:                case DD_DATA:
        !           163:                        canino(ddp->dd_ino);
        !           164:                        candaddr(ddp->dd_block);
        !           165:                        canint(ddp->dd_size);
        !           166:                        if (dlist==NULL || dlist->dl_ino!=ddp->dd_ino)
        !           167:                                fatal("out of sync");
        !           168:                        fseek(tfp, dlist->dl_seek+(BUFSIZ*ddp->dd_block), 0);
        !           169:                        fwrite(ddp->dd_data, sizeof(char), BUFSIZ, tfp);
        !           170:                        if (ferror(tfp))
        !           171:                                fatal("temporary file write error");
        !           172:                        break;
        !           173: 
        !           174:                case DD_INO:
        !           175:                        canino(ddp->dd_ino);
        !           176:                        canshort(ddp->dd_dinode.di_mode);
        !           177:                        cansize(ddp->dd_dinode.di_size);
        !           178:                        if ((ddp->dd_dinode.di_mode&IFMT) != IFDIR)
        !           179:                                return;
        !           180:                        dlp = (struct dlist *) malloc(sizeof(struct dlist));
        !           181:                        if (dlp == NULL)
        !           182:                                fatal("out of memory (directory)");
        !           183:                        dlp->dl_dlp = dlist;
        !           184:                        dlist = dlp;
        !           185:                        if (droot == NULL)
        !           186:                                droot = dlp;
        !           187:                        dlp->dl_ino = ddp->dd_ino;
        !           188:                        dlp->dl_dejavu = 0;
        !           189:                        dlp->dl_seek = ftell(tfp);
        !           190:                        dlp->dl_size = ddp->dd_dinode.di_size;
        !           191:                        break;
        !           192: 
        !           193:                case DD_MAP:
        !           194:                        canino(ddp->dd_ino);
        !           195:                        canint(ddp->dd_nmap);
        !           196:                        setmap(ddp);
        !           197:                        break;
        !           198: 
        !           199:                default:
        !           200:                        fatal("bad type %d", ddp->dd_type);
        !           201:                }
        !           202:        }
        !           203: }
        !           204: 
        !           205: /*
        !           206:  * Process a map entry.
        !           207:  * Set a bit in the map for every inode
        !           208:  * whose dump map entry has the DD_DUMP flag
        !           209:  * set.
        !           210:  */
        !           211: setmap(ddp)
        !           212: union dumpdata *ddp;
        !           213: {
        !           214:        register char *mmapp, *dmapp;
        !           215:        register mmask;
        !           216:        register nmapb;
        !           217: 
        !           218:        mmapp = &map[--ddp->dd_ino/NBCHAR];
        !           219:        mmask = 01 << (ddp->dd_ino%NBCHAR);
        !           220:        dmapp = &ddp->dd_map[0];
        !           221:        nmapb = ddp->dd_nmap;
        !           222:        while (nmapb--) {
        !           223:                if (((*dmapp++)&DD_DUMP) != 0)
        !           224:                        *mmapp |= mmask;
        !           225:                if ((mmask <<= 1) == (01<<NBCHAR)) {
        !           226:                        ++mmapp;
        !           227:                        mmask = 01;
        !           228:                }
        !           229:        }
        !           230: }
        !           231: 
        !           232: /*
        !           233:  * Return a pointer to the 
        !           234:  * next dump file item. This routine
        !           235:  * knows all about reading the
        !           236:  * next tape in a multitape dump.
        !           237:  */
        !           238: union dumpdata *
        !           239: readdump()
        !           240: {
        !           241:        register nb;
        !           242: 
        !           243:        while ((char *) ddptr == ddend) {
        !           244:                if (length != 0 && (nread+ddnbuf) > length) {
        !           245:                        nextvol();
        !           246:                        continue;
        !           247:                }
        !           248:                if ((nb = read(fileno(dtp), ddbuf, ddnbuf)) != ddnbuf) {
        !           249:                        if (nb != 0)
        !           250:                                fatal("dump read error");
        !           251:                        nextvol();
        !           252:                        continue;
        !           253:                }
        !           254:                nread += nb;
        !           255:                ddptr = (union dumpdata *) ddbuf;
        !           256:                break;
        !           257:        }
        !           258:        return (ddptr++);
        !           259: }
        !           260: 
        !           261: /*
        !           262:  * Read the next reel or volume.
        !           263:  */
        !           264: nextvol()
        !           265: {
        !           266:        if (is_open) {
        !           267:                fclose(dtp);
        !           268:                is_open = 0;
        !           269:        }
        !           270:        fprintf(stderr, "dumpdir: mount %s %d, type return key ...",
        !           271:                length ? "volume" : "reel", reel);
        !           272:        if (fgets(dstr, sizeof(dstr), stdin) == NULL)
        !           273:                delexit(1);
        !           274:        if ((dtp = fopen(dtn, "r")) == NULL)
        !           275:                fatal("%s: cannot open dump tape", dtn);
        !           276:        ++is_open;
        !           277:        readhead();
        !           278: }
        !           279: 
        !           280: /*
        !           281:  * Start at the root and
        !           282:  * print all of the directories.
        !           283:  * Don't print the names of things that
        !           284:  * the map says are not on the tape.
        !           285:  */
        !           286: dumpdirs(dlp)
        !           287: register struct dlist *dlp;
        !           288: {
        !           289:        char *sdstrp;
        !           290:        struct direct dirbuf;
        !           291:        register char *p1, *p2;
        !           292:        register c;
        !           293:        register struct dlist *sdlp;
        !           294:        ino_t ino;
        !           295: 
        !           296:        dlp->dl_dejavu = 1;
        !           297:        while (dlp->dl_size != 0) {
        !           298:                fseek(tfp, dlp->dl_seek, 0);
        !           299:                if (fread(&dirbuf, sizeof(dirbuf), 1, tfp) != 1)
        !           300:                        fatal("temporary file read error");
        !           301:                dlp->dl_seek += sizeof(struct direct);
        !           302:                dlp->dl_size -= sizeof(struct direct);
        !           303:                if (aflag == 0) {
        !           304:                        if (strncmp(dirbuf.d_name, ".",  DIRSIZ) == 0)
        !           305:                                continue;
        !           306:                        if (strncmp(dirbuf.d_name, "..", DIRSIZ) == 0)
        !           307:                                continue;
        !           308:                }
        !           309:                canino(dirbuf.d_ino);
        !           310:                if ((ino = dirbuf.d_ino)!=0 && getbit(ino)!=0) {
        !           311:                        p1 = sdstrp = dstrp;
        !           312:                        if (p1 != dstr)
        !           313:                                *p1++ = '/';
        !           314:                        p2 = dirbuf.d_name;
        !           315:                        while (p2<&dirbuf.d_name[DIRSIZ] && (c=*p2++))
        !           316:                                *p1++ = c;
        !           317:                        *p1 = '\0';
        !           318:                        dstrp = p1;
        !           319:                        printf("%u\t%s\n", ino, dstr);
        !           320:                        if ((sdlp=findnode(ino))!=NULL && sdlp->dl_dejavu==0)
        !           321:                                dumpdirs(sdlp);
        !           322:                        dstrp = sdstrp;
        !           323:                        *dstrp = '\0';
        !           324:                }
        !           325:        }
        !           326:        dlp->dl_dejavu = 0;
        !           327: }
        !           328: 
        !           329: /*
        !           330:  * Get the dumped bit for
        !           331:  * inode `ino' from the big bit map.
        !           332:  */
        !           333: getbit(ino)
        !           334: ino_t ino;
        !           335: {
        !           336:        register mapent;
        !           337: 
        !           338:        mapent = map[--ino/NBCHAR];
        !           339:        return (mapent & (01<<ino%NBCHAR));
        !           340: }
        !           341: 
        !           342: /*
        !           343:  * Return the dlist pointer
        !           344:  * for directory inode `ino', or NULL
        !           345:  * if it is not there. Not there means
        !           346:  * not a directory.
        !           347:  */
        !           348: struct dlist *
        !           349: findnode(ino)
        !           350: register ino_t ino;
        !           351: {
        !           352:        register struct dlist *dlp;
        !           353: 
        !           354:        dlp = dlist;
        !           355:        while (dlp != NULL) {
        !           356:                if (dlp->dl_ino == ino)
        !           357:                        break;
        !           358:                dlp = dlp->dl_dlp;
        !           359:        }
        !           360:        return (dlp);
        !           361: }
        !           362: 
        !           363: /*
        !           364:  * Nasty nasty nasty.
        !           365:  */
        !           366: fatal(a)
        !           367: {
        !           368:        fprintf(stderr, "dumpdir: %r", &a);
        !           369:        fprintf(stderr, "\n");
        !           370:        delexit(1);
        !           371: }
        !           372: 
        !           373: /*
        !           374:  * This routine is called from the
        !           375:  * interupt signal. It points off to dumpdir
        !           376:  * who deletes the temp file and returns
        !           377:  * the error status.
        !           378:  */
        !           379: cleanup()
        !           380: {
        !           381:        delexit(1);
        !           382: }
        !           383: 
        !           384: /*
        !           385:  * A special version of `exit' that
        !           386:  * cleans up by unlinking the temporary
        !           387:  * file.
        !           388:  */
        !           389: delexit(s)
        !           390: {
        !           391:        if (tfp != NULL)
        !           392:                unlink(tfn);
        !           393:        exit(s);
        !           394: }
        !           395: 
        !           396: /*
        !           397:  * Print the usage message and
        !           398:  * exit.
        !           399:  */
        !           400: usage()
        !           401: {
        !           402:        fprintf(stderr, "Usage: dumpdir [af [dumpfile]]\n");
        !           403:        exit(1);
        !           404: }

unix.superglobalmegacorp.com

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