Annotation of coherent/d/bin/dump/dumpdir.c, revision 1.1.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.