Annotation of 3BSD/cmd/tar.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <sys/types.h>
                      3: #include <sys/stat.h>
                      4: #include <sys/dir.h>
                      5: #include <signal.h>
                      6: 
                      7: char   *sprintf();
                      8: char   *strcat();
                      9: daddr_t        bsrch();
                     10: #define TBLOCK 512
                     11: #define NBLOCK 20
                     12: #define NAMSIZ 100
                     13: union hblock {
                     14:        char dummy[TBLOCK];
                     15:        struct header {
                     16:                char name[NAMSIZ];
                     17:                char mode[8];
                     18:                char uid[8];
                     19:                char gid[8];
                     20:                char size[12];
                     21:                char mtime[12];
                     22:                char chksum[8];
                     23:                char linkflag;
                     24:                char linkname[NAMSIZ];
                     25:        } dbuf;
                     26: } dblock, tbuf[NBLOCK];
                     27: 
                     28: struct linkbuf {
                     29:        ino_t   inum;
                     30:        dev_t   devnum;
                     31:        int     count;
                     32:        char    pathname[NAMSIZ];
                     33:        struct  linkbuf *nextp;
                     34: } *ihead;
                     35: 
                     36: struct stat stbuf;
                     37: 
                     38: int    rflag, xflag, vflag, tflag, mt, cflag, mflag, fflag;
                     39: int    term, chksum, wflag, recno, first, linkerrok;
                     40: int    freemem = 1;
                     41: int    nblock = 1;
                     42: 
                     43: daddr_t        low;
                     44: daddr_t        high;
                     45: 
                     46: FILE   *tfile;
                     47: char   tname[] = "/tmp/tarXXXXXX";
                     48: 
                     49: 
                     50: char   *usefile;
                     51: char   magtape[]       = "/dev/mt1";
                     52: 
                     53: char   *malloc();
                     54: 
                     55: main(argc, argv)
                     56: int    argc;
                     57: char   *argv[];
                     58: {
                     59:        char *cp;
                     60:        int onintr(), onquit(), onhup(), onterm();
                     61: 
                     62:        if (argc < 2)
                     63:                usage();
                     64: 
                     65:        tfile = NULL;
                     66:        usefile =  magtape;
                     67:        argv[argc] = 0;
                     68:        argv++;
                     69:        for (cp = *argv++; *cp; cp++) 
                     70:                switch(*cp) {
                     71:                case 'f':
                     72:                        usefile = *argv++;
                     73:                        fflag++;
                     74:                        if (nblock == 1)
                     75:                                nblock = 0;
                     76:                        break;
                     77:                case 'c':
                     78:                        cflag++;
                     79:                        rflag++;
                     80:                        break;
                     81:                case 'u':
                     82:                        mktemp(tname);
                     83:                        if ((tfile = fopen(tname, "w")) == NULL) {
                     84:                                fprintf(stderr, "Tar: cannot create temporary file (%s)\n", tname);
                     85:                                done(1);
                     86:                        }
                     87:                        fprintf(tfile, "!!!!!/!/!/!/!/!/!/! 000\n");
                     88:                        /* FALL THROUGH */
                     89:                case 'r':
                     90:                        rflag++;
                     91: noupdate:
                     92:                        if (nblock != 1 && cflag == 0) {
                     93:                                fprintf(stderr, "Tar: Blocked tapes cannot be updated (yet)\n");
                     94:                                done(1);
                     95:                        }
                     96:                        break;
                     97:                case 'v':
                     98:                        vflag++;
                     99:                        break;
                    100:                case 'w':
                    101:                        wflag++;
                    102:                        break;
                    103:                case 'x':
                    104:                        xflag++;
                    105:                        break;
                    106:                case 't':
                    107:                        tflag++;
                    108:                        break;
                    109:                case 'm':
                    110:                        mflag++;
                    111:                        break;
                    112:                case '-':
                    113:                        break;
                    114:                case '0':
                    115:                case '1':
                    116:                case '4':
                    117:                case '5':
                    118:                case '7':
                    119:                case '8':
                    120:                        magtape[7] = *cp;
                    121:                        usefile = magtape;
                    122:                        break;
                    123:                case 'b':
                    124:                        nblock = atoi(*argv++);
                    125:                        if (nblock > NBLOCK || nblock <= 0) {
                    126:                                fprintf(stderr, "Invalid blocksize. (Max %d)\n", NBLOCK);
                    127:                                done(1);
                    128:                        }
                    129:                        if (rflag && !cflag)
                    130:                                goto noupdate;
                    131:                        break;
                    132:                case 'l':
                    133:                        linkerrok++;
                    134:                        break;
                    135:                default:
                    136:                        fprintf(stderr, "tar: %c: unknown option\n", *cp);
                    137:                        usage();
                    138:                }
                    139: 
                    140:        if (rflag) {
                    141:                if (cflag && tfile != NULL) {
                    142:                        usage();
                    143:                        done(1);
                    144:                }
                    145:                if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                    146:                        signal(SIGINT, onintr);
                    147:                if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
                    148:                        signal(SIGHUP, onhup);
                    149:                if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
                    150:                        signal(SIGQUIT, onquit);
                    151: /*
                    152:                if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
                    153:                        signal(SIGTERM, onterm);
                    154: */
                    155:                if (strcmp(usefile, "-") == 0) {
                    156:                        if (cflag == 0) {
                    157:                                fprintf(stderr, "Can only create standard output archives\n");
                    158:                                done(1);
                    159:                        }
                    160:                        mt = dup(1);
                    161:                        nblock = 1;
                    162:                }
                    163:                else if ((mt = open(usefile, 2)) < 0) {
                    164:                        if (cflag == 0 || (mt =  creat(usefile, 0666)) < 0) {
                    165:                                fprintf(stderr, "tar: cannot open %s\n", usefile);
                    166:                                done(1);
                    167:                        }
                    168:                }
                    169:                if (cflag == 0 && nblock == 0)
                    170:                        nblock = 1;
                    171:                dorep(argv);
                    172:        }
                    173:        else if (xflag)  {
                    174:                if (strcmp(usefile, "-") == 0) {
                    175:                        mt = dup(0);
                    176:                        nblock = 1;
                    177:                }
                    178:                else if ((mt = open(usefile, 0)) < 0) {
                    179:                        fprintf(stderr, "tar: cannot open %s\n", usefile);
                    180:                        done(1);
                    181:                }
                    182:                doxtract(argv);
                    183:        }
                    184:        else if (tflag) {
                    185:                if (strcmp(usefile, "-") == 0) {
                    186:                        mt = dup(0);
                    187:                        nblock = 1;
                    188:                }
                    189:                else if ((mt = open(usefile, 0)) < 0) {
                    190:                        fprintf(stderr, "tar: cannot open %s\n", usefile);
                    191:                        done(1);
                    192:                }
                    193:                dotable();
                    194:        }
                    195:        else
                    196:                usage();
                    197:        done(0);
                    198: }
                    199: 
                    200: usage()
                    201: {
                    202:        fprintf(stderr, "tar: usage  tar -{txru}[cvfblm] [tapefile] [blocksize] file1 file2...\n");
                    203:        done(1);
                    204: }
                    205: 
                    206: dorep(argv)
                    207: char   *argv[];
                    208: {
                    209:        register char *cp, *cp2;
                    210:        char wdir[60];
                    211: 
                    212:        if (!cflag) {
                    213:                getdir();
                    214:                do {
                    215:                        passtape();
                    216:                        if (term)
                    217:                                done(0);
                    218:                        getdir();
                    219:                } while (!endtape());
                    220:                if (tfile != NULL) {
                    221:                        char buf[200];
                    222: 
                    223:                        strcat(buf, "sort +0 -1 +1nr ");
                    224:                        strcat(buf, tname);
                    225:                        strcat(buf, " -o ");
                    226:                        strcat(buf, tname);
                    227:                        sprintf(buf, "sort +0 -1 +1nr %s -o %s; awk '$1 != prev {print; prev=$1}' %s >%sX;mv %sX %s",
                    228:                                tname, tname, tname, tname, tname, tname);
                    229:                        fflush(tfile);
                    230:                        system(buf);
                    231:                        freopen(tname, "r", tfile);
                    232:                        fstat(fileno(tfile), &stbuf);
                    233:                        high = stbuf.st_size;
                    234:                }
                    235:        }
                    236: 
                    237:        getwdir(wdir);
                    238:        while (*argv && ! term) {
                    239:                cp2 = *argv;
                    240:                if (!strcmp(cp2, "-C") && argv[1]) {
                    241:                        argv++;
                    242:                        if (chdir(*argv) < 0)
                    243:                                perror(*argv);
                    244:                        else
                    245:                                getwdir(wdir);
                    246:                        argv++;
                    247:                        continue;
                    248:                }
                    249:                for (cp = *argv; *cp; cp++)
                    250:                        if (*cp == '/')
                    251:                                cp2 = cp;
                    252:                if (cp2 != *argv) {
                    253:                        *cp2 = '\0';
                    254:                        chdir(*argv);
                    255:                        *cp2 = '/';
                    256:                        cp2++;
                    257:                }
                    258:                putfile(*argv++, cp2);
                    259:                chdir(wdir);
                    260:        }
                    261:        putempty();
                    262:        putempty();
                    263:        flushtape();
                    264:        if (linkerrok == 1)
                    265:                for (; ihead != NULL; ihead = ihead->nextp)
                    266:                        if (ihead->count != 0)
                    267:                                fprintf(stderr, "Missing links to %s\n", ihead->pathname);
                    268: }
                    269: 
                    270: endtape()
                    271: {
                    272:        if (dblock.dbuf.name[0] == '\0') {
                    273:                backtape();
                    274:                return(1);
                    275:        }
                    276:        else
                    277:                return(0);
                    278: }
                    279: 
                    280: getdir()
                    281: {
                    282:        register struct stat *sp;
                    283:        int i;
                    284: 
                    285:        readtape( (char *) &dblock);
                    286:        if (dblock.dbuf.name[0] == '\0')
                    287:                return;
                    288:        sp = &stbuf;
                    289:        sscanf(dblock.dbuf.mode, "%o", &i);
                    290:        sp->st_mode = i;
                    291:        sscanf(dblock.dbuf.uid, "%o", &i);
                    292:        sp->st_uid = i;
                    293:        sscanf(dblock.dbuf.gid, "%o", &i);
                    294:        sp->st_gid = i;
                    295:        sscanf(dblock.dbuf.size, "%lo", &sp->st_size);
                    296:        sscanf(dblock.dbuf.mtime, "%lo", &sp->st_mtime);
                    297:        sscanf(dblock.dbuf.chksum, "%o", &chksum);
                    298:        if (chksum != checksum()) {
                    299:                fprintf(stderr, "directory checksum error\n");
                    300:                done(2);
                    301:        }
                    302:        if (tfile != NULL)
                    303:                fprintf(tfile, "%s %s\n", dblock.dbuf.name, dblock.dbuf.mtime);
                    304: }
                    305: 
                    306: passtape()
                    307: {
                    308:        long blocks;
                    309:        char buf[TBLOCK];
                    310: 
                    311:        if (dblock.dbuf.linkflag == '1')
                    312:                return;
                    313:        blocks = stbuf.st_size;
                    314:        blocks += TBLOCK-1;
                    315:        blocks /= TBLOCK;
                    316: 
                    317:        while (blocks-- > 0)
                    318:                readtape(buf);
                    319: }
                    320: 
                    321: putfile(longname, shortname)
                    322: char *longname;
                    323: char *shortname;
                    324: {
                    325:        int infile;
                    326:        long blocks;
                    327:        char buf[TBLOCK];
                    328:        register char *cp, *cp2;
                    329:        struct direct dbuf;
                    330:        int i, j;
                    331: 
                    332:        infile = open(shortname, 0);
                    333:        if (infile < 0) {
                    334:                fprintf(stderr, "tar: %s: cannot open file\n", longname);
                    335:                return;
                    336:        }
                    337: 
                    338:        fstat(infile, &stbuf);
                    339: 
                    340:        if (tfile != NULL && checkupdate(longname) == 0) {
                    341:                close(infile);
                    342:                return;
                    343:        }
                    344:        if (checkw('r', longname) == 0) {
                    345:                close(infile);
                    346:                return;
                    347:        }
                    348: 
                    349:        if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
                    350:                for (i = 0, cp = buf; *cp++ = longname[i++];);
                    351:                *--cp = '/';
                    352:                cp++;
                    353:                i = 0;
                    354:                chdir(shortname);
                    355:                while (read(infile, (char *)&dbuf, sizeof(dbuf)) > 0 && !term) {
                    356:                        if (dbuf.d_ino == 0) {
                    357:                                i++;
                    358:                                continue;
                    359:                        }
                    360:                        if (strcmp(".", dbuf.d_name) == 0 || strcmp("..", dbuf.d_name) == 0) {
                    361:                                i++;
                    362:                                continue;
                    363:                        }
                    364:                        cp2 = cp;
                    365:                        for (j=0; j < DIRSIZ; j++)
                    366:                                *cp2++ = dbuf.d_name[j];
                    367:                        *cp2 = '\0';
                    368:                        close(infile);
                    369:                        putfile(buf, cp);
                    370:                        infile = open(".", 0);
                    371:                        i++;
                    372:                        lseek(infile, (long) (sizeof(dbuf) * i), 0);
                    373:                }
                    374:                close(infile);
                    375:                chdir("..");
                    376:                return;
                    377:        }
                    378:        if ((stbuf.st_mode & S_IFMT) != S_IFREG) {
                    379:                fprintf(stderr, "tar: %s is not a file. Not dumped\n", longname);
                    380:                return;
                    381:        }
                    382: 
                    383:        tomodes(&stbuf);
                    384: 
                    385:        cp2 = longname;
                    386:        for (cp = dblock.dbuf.name, i=0; (*cp++ = *cp2++) && i < NAMSIZ; i++);
                    387:        if (i >= NAMSIZ) {
                    388:                fprintf(stderr, "%s: file name too long\n", longname);
                    389:                close(infile);
                    390:                return;
                    391:        }
                    392: 
                    393:        if (stbuf.st_nlink > 1) {
                    394:                struct linkbuf *lp;
                    395:                int found = 0;
                    396: 
                    397:                for (lp = ihead; lp != NULL; lp = lp->nextp) {
                    398:                        if (lp->inum == stbuf.st_ino && lp->devnum == stbuf.st_dev) {
                    399:                                found++;
                    400:                                break;
                    401:                        }
                    402:                }
                    403:                if (found) {
                    404:                        strcpy(dblock.dbuf.linkname, lp->pathname);
                    405:                        dblock.dbuf.linkflag = '1';
                    406:                        sprintf(dblock.dbuf.chksum, "%6o", checksum());
                    407:                        writetape( (char *) &dblock);
                    408:                        if (vflag) {
                    409:                                fprintf(stderr, "a %s ", longname);
                    410:                                fprintf(stderr, "link to %s\n", lp->pathname);
                    411:                        }
                    412:                        lp->count--;
                    413:                        close(infile);
                    414:                        return;
                    415:                }
                    416:                else {
                    417:                        lp = (struct linkbuf *) malloc(sizeof(*lp));
                    418:                        if (lp == NULL) {
                    419:                                if (freemem) {
                    420:                                        fprintf(stderr, "Out of memory. Link information lost\n");
                    421:                                        freemem = 0;
                    422:                                }
                    423:                        }
                    424:                        else {
                    425:                                lp->nextp = ihead;
                    426:                                ihead = lp;
                    427:                                lp->inum = stbuf.st_ino;
                    428:                                lp->devnum = stbuf.st_dev;
                    429:                                lp->count = stbuf.st_nlink - 1;
                    430:                                strcpy(lp->pathname, longname);
                    431:                        }
                    432:                }
                    433:        }
                    434: 
                    435:        blocks = (stbuf.st_size + (TBLOCK-1)) / TBLOCK;
                    436:        if (vflag) {
                    437:                fprintf(stderr, "a %s ", longname);
                    438:                fprintf(stderr, "%ld blocks\n", blocks);
                    439:        }
                    440:        sprintf(dblock.dbuf.chksum, "%6o", checksum());
                    441:        writetape( (char *) &dblock);
                    442: 
                    443:        while ((i = read(infile, buf, TBLOCK)) > 0 && blocks > 0) {
                    444:                writetape(buf);
                    445:                blocks--;
                    446:        }
                    447:        close(infile);
                    448:        if (blocks != 0 || i != 0)
                    449:                fprintf(stderr, "%s: file changed size\n", longname);
                    450:        while (blocks-- >  0)
                    451:                putempty();
                    452: }
                    453: 
                    454: 
                    455: 
                    456: doxtract(argv)
                    457: char   *argv[];
                    458: {
                    459:        long blocks, bytes;
                    460:        char buf[TBLOCK];
                    461:        char **cp;
                    462:        int ofile;
                    463: 
                    464:        for (;;) {
                    465:                getdir();
                    466:                if (endtape())
                    467:                        break;
                    468: 
                    469:                if (*argv == 0)
                    470:                        goto gotit;
                    471: 
                    472:                for (cp = argv; *cp; cp++)
                    473:                        if (prefix(*cp, dblock.dbuf.name))
                    474:                                goto gotit;
                    475:                passtape();
                    476:                continue;
                    477: 
                    478: gotit:
                    479:                if (checkw('x', dblock.dbuf.name) == 0) {
                    480:                        passtape();
                    481:                        continue;
                    482:                }
                    483: 
                    484:                checkdir(dblock.dbuf.name);
                    485: 
                    486:                if (dblock.dbuf.linkflag == '1') {
                    487:                        unlink(dblock.dbuf.name);
                    488:                        if (link(dblock.dbuf.linkname, dblock.dbuf.name) < 0) {
                    489:                                fprintf(stderr, "%s: cannot link\n", dblock.dbuf.name);
                    490:                                continue;
                    491:                        }
                    492:                        if (vflag)
                    493:                                fprintf(stderr, "%s linked to %s\n", dblock.dbuf.name, dblock.dbuf.linkname);
                    494:                        continue;
                    495:                }
                    496:                if ((ofile = creat(dblock.dbuf.name, stbuf.st_mode & 07777)) < 0) {
                    497:                        fprintf(stderr, "tar: %s - cannot create\n", dblock.dbuf.name);
                    498:                        passtape();
                    499:                        continue;
                    500:                }
                    501: 
                    502:                chown(dblock.dbuf.name, stbuf.st_uid, stbuf.st_gid);
                    503: 
                    504:                blocks = ((bytes = stbuf.st_size) + TBLOCK-1)/TBLOCK;
                    505:                if (vflag)
                    506:                        fprintf(stderr, "x %s, %ld bytes, %ld tape blocks\n", dblock.dbuf.name, bytes, blocks);
                    507:                while (blocks-- > 0) {
                    508:                        readtape(buf);
                    509:                        if (bytes > TBLOCK) {
                    510:                                if (write(ofile, buf, TBLOCK) < 0) {
                    511:                                        fprintf(stderr, "tar: %s: HELP - extract write error\n", dblock.dbuf.name);
                    512:                                        done(2);
                    513:                                }
                    514:                        } else
                    515:                                if (write(ofile, buf, (int) bytes) < 0) {
                    516:                                        fprintf(stderr, "tar: %s: HELP - extract write error\n", dblock.dbuf.name);
                    517:                                        done(2);
                    518:                                }
                    519:                        bytes -= TBLOCK;
                    520:                }
                    521:                close(ofile);
                    522:                if (mflag == 0) {
                    523:                        time_t timep[2];
                    524: 
                    525:                        timep[0] = time(NULL);
                    526:                        timep[1] = stbuf.st_mtime;
                    527:                        utime(dblock.dbuf.name, timep);
                    528:                }
                    529:        }
                    530: }
                    531: 
                    532: dotable()
                    533: {
                    534:        for (;;) {
                    535:                getdir();
                    536:                if (endtape())
                    537:                        break;
                    538:                if (vflag)
                    539:                        longt(&stbuf);
                    540:                printf("%s", dblock.dbuf.name);
                    541:                if (dblock.dbuf.linkflag == '1')
                    542:                        printf(" linked to %s", dblock.dbuf.linkname);
                    543:                printf("\n");
                    544:                passtape();
                    545:        }
                    546: }
                    547: 
                    548: putempty()
                    549: {
                    550:        char buf[TBLOCK];
                    551:        char *cp;
                    552: 
                    553:        for (cp = buf; cp < &buf[TBLOCK]; )
                    554:                *cp++ = '\0';
                    555:        writetape(buf);
                    556: }
                    557: 
                    558: longt(st)
                    559: register struct stat *st;
                    560: {
                    561:        register char *cp;
                    562:        char *ctime();
                    563: 
                    564:        pmode(st);
                    565:        printf("%3d/%1d", st->st_uid, st->st_gid);
                    566:        printf("%7D", st->st_size);
                    567:        cp = ctime(&st->st_mtime);
                    568:        printf(" %-12.12s %-4.4s ", cp+4, cp+20);
                    569: }
                    570: 
                    571: #define        SUID    04000
                    572: #define        SGID    02000
                    573: #define        ROWN    0400
                    574: #define        WOWN    0200
                    575: #define        XOWN    0100
                    576: #define        RGRP    040
                    577: #define        WGRP    020
                    578: #define        XGRP    010
                    579: #define        ROTH    04
                    580: #define        WOTH    02
                    581: #define        XOTH    01
                    582: #define        STXT    01000
                    583: int    m1[] = { 1, ROWN, 'r', '-' };
                    584: int    m2[] = { 1, WOWN, 'w', '-' };
                    585: int    m3[] = { 2, SUID, 's', XOWN, 'x', '-' };
                    586: int    m4[] = { 1, RGRP, 'r', '-' };
                    587: int    m5[] = { 1, WGRP, 'w', '-' };
                    588: int    m6[] = { 2, SGID, 's', XGRP, 'x', '-' };
                    589: int    m7[] = { 1, ROTH, 'r', '-' };
                    590: int    m8[] = { 1, WOTH, 'w', '-' };
                    591: int    m9[] = { 2, STXT, 't', XOTH, 'x', '-' };
                    592: 
                    593: int    *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
                    594: 
                    595: pmode(st)
                    596: register struct stat *st;
                    597: {
                    598:        register int **mp;
                    599: 
                    600:        for (mp = &m[0]; mp < &m[9];)
                    601:                select(*mp++, st);
                    602: }
                    603: 
                    604: select(pairp, st)
                    605: int *pairp;
                    606: struct stat *st;
                    607: {
                    608:        register int n, *ap;
                    609: 
                    610:        ap = pairp;
                    611:        n = *ap++;
                    612:        while (--n>=0 && (st->st_mode&*ap++)==0)
                    613:                ap++;
                    614:        printf("%c", *ap);
                    615: }
                    616: 
                    617: checkdir(name)
                    618: register char *name;
                    619: {
                    620:        register char *cp;
                    621:        int i;
                    622:        for (cp = name; *cp; cp++) {
                    623:                if (*cp == '/') {
                    624:                        *cp = '\0';
                    625:                        if (access(name, 01) < 0) {
                    626:                                register int pid, rp;
                    627: 
                    628:                                if ((pid = fork()) == 0) {
                    629:                                        execl("/bin/mkdir", "mkdir", name, 0);
                    630:                                        execl("/usr/bin/mkdir", "mkdir", name, 0);
                    631:                                        fprintf(stderr, "tar: cannot find mkdir!\n");
                    632:                                        done(0);
                    633:                                }
                    634:                                while ((rp = wait(&i)) >= 0 && rp != pid)
                    635:                                        ;
                    636:                                chown(name, stbuf.st_uid, stbuf.st_gid);
                    637:                        }
                    638:                        *cp = '/';
                    639:                }
                    640:        }
                    641: }
                    642: 
                    643: onintr()
                    644: {
                    645:        signal(SIGINT, SIG_IGN);
                    646:        term++;
                    647: }
                    648: 
                    649: onquit()
                    650: {
                    651:        signal(SIGQUIT, SIG_IGN);
                    652:        term++;
                    653: }
                    654: 
                    655: onhup()
                    656: {
                    657:        signal(SIGHUP, SIG_IGN);
                    658:        term++;
                    659: }
                    660: 
                    661: onterm()
                    662: {
                    663:        signal(SIGTERM, SIG_IGN);
                    664:        term++;
                    665: }
                    666: 
                    667: tomodes(sp)
                    668: register struct stat *sp;
                    669: {
                    670:        register char *cp;
                    671: 
                    672:        for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++)
                    673:                *cp = '\0';
                    674:        sprintf(dblock.dbuf.mode, "%6o ", sp->st_mode & 07777);
                    675:        sprintf(dblock.dbuf.uid, "%6o ", sp->st_uid);
                    676:        sprintf(dblock.dbuf.gid, "%6o ", sp->st_gid);
                    677:        sprintf(dblock.dbuf.size, "%11lo ", sp->st_size);
                    678:        sprintf(dblock.dbuf.mtime, "%11lo ", sp->st_mtime);
                    679: }
                    680: 
                    681: checksum()
                    682: {
                    683:        register i;
                    684:        register char *cp;
                    685: 
                    686:        for (cp = dblock.dbuf.chksum; cp < &dblock.dbuf.chksum[sizeof(dblock.dbuf.chksum)]; cp++)
                    687:                *cp = ' ';
                    688:        i = 0;
                    689:        for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++)
                    690:                i += *cp;
                    691:        return(i);
                    692: }
                    693: 
                    694: checkw(c, name)
                    695: char *name;
                    696: {
                    697:        if (wflag) {
                    698:                printf("%c ", c);
                    699:                if (vflag)
                    700:                        longt(&stbuf);
                    701:                printf("%s: ", name);
                    702:                if (response() == 'y'){
                    703:                        return(1);
                    704:                }
                    705:                return(0);
                    706:        }
                    707:        return(1);
                    708: }
                    709: 
                    710: response()
                    711: {
                    712:        char c;
                    713: 
                    714:        c = getchar();
                    715:        if (c != '\n')
                    716:                while (getchar() != '\n');
                    717:        else c = 'n';
                    718:        return(c);
                    719: }
                    720: 
                    721: checkupdate(arg)
                    722: char   *arg;
                    723: {
                    724:        char name[100];
                    725:        long    mtime;
                    726:        daddr_t seekp;
                    727:        daddr_t lookup();
                    728: 
                    729:        rewind(tfile);
                    730:        for (;;) {
                    731:                if ((seekp = lookup(arg)) < 0)
                    732:                        return(1);
                    733:                fseek(tfile, seekp, 0);
                    734:                fscanf(tfile, "%s %lo", name, &mtime);
                    735:                if (stbuf.st_mtime > mtime)
                    736:                        return(1);
                    737:                else
                    738:                        return(0);
                    739:        }
                    740: }
                    741: 
                    742: done(n)
                    743: {
                    744:        unlink(tname);
                    745:        exit(n);
                    746: }
                    747: 
                    748: prefix(s1, s2)
                    749: register char *s1, *s2;
                    750: {
                    751:        while (*s1)
                    752:                if (*s1++ != *s2++)
                    753:                        return(0);
                    754:        if (*s2)
                    755:                return(*s2 == '/');
                    756:        return(1);
                    757: }
                    758: 
                    759: getwdir(s)
                    760: char *s;
                    761: {
                    762:        int i;
                    763:        int     pipdes[2];
                    764: 
                    765:        pipe(pipdes);
                    766:        if ((i = fork()) == 0) {
                    767:                close(1);
                    768:                dup(pipdes[1]);
                    769:                execl("/bin/pwd", "pwd", 0);
                    770:                execl("/usr/bin/pwd", "pwd", 0);
                    771:                fprintf(stderr, "pwd failed!\n");
                    772:                printf("/\n");
                    773:                exit(1);
                    774:        }
                    775:        while (wait((int *)NULL) != -1)
                    776:                        ;
                    777:        read(pipdes[0], s, 50);
                    778:        while(*s != '\n')
                    779:                s++;
                    780:        *s = '\0';
                    781:        close(pipdes[0]);
                    782:        close(pipdes[1]);
                    783: }
                    784: 
                    785: #define        N       200
                    786: int    njab;
                    787: daddr_t
                    788: lookup(s)
                    789: char *s;
                    790: {
                    791:        register i;
                    792:        daddr_t a;
                    793: 
                    794:        for(i=0; s[i]; i++)
                    795:                if(s[i] == ' ')
                    796:                        break;
                    797:        a = bsrch(s, i, low, high);
                    798:        return(a);
                    799: }
                    800: 
                    801: daddr_t
                    802: bsrch(s, n, l, h)
                    803: daddr_t l, h;
                    804: char *s;
                    805: {
                    806:        register i, j;
                    807:        char b[N];
                    808:        daddr_t m, m1;
                    809: 
                    810:        njab = 0;
                    811: 
                    812: loop:
                    813:        if(l >= h)
                    814:                return(-1L);
                    815:        m = l + (h-l)/2 - N/2;
                    816:        if(m < l)
                    817:                m = l;
                    818:        fseek(tfile, m, 0);
                    819:        fread(b, 1, N, tfile);
                    820:        njab++;
                    821:        for(i=0; i<N; i++) {
                    822:                if(b[i] == '\n')
                    823:                        break;
                    824:                m++;
                    825:        }
                    826:        if(m >= h)
                    827:                return(-1L);
                    828:        m1 = m;
                    829:        j = i;
                    830:        for(i++; i<N; i++) {
                    831:                m1++;
                    832:                if(b[i] == '\n')
                    833:                        break;
                    834:        }
                    835:        i = cmp(b+j, s, n);
                    836:        if(i < 0) {
                    837:                h = m;
                    838:                goto loop;
                    839:        }
                    840:        if(i > 0) {
                    841:                l = m1;
                    842:                goto loop;
                    843:        }
                    844:        return(m);
                    845: }
                    846: 
                    847: cmp(b, s, n)
                    848: char *b, *s;
                    849: {
                    850:        register i;
                    851: 
                    852:        if(b[0] != '\n')
                    853:                exit(2);
                    854:        for(i=0; i<n; i++) {
                    855:                if(b[i+1] > s[i])
                    856:                        return(-1);
                    857:                if(b[i+1] < s[i])
                    858:                        return(1);
                    859:        }
                    860:        return(b[i+1] == ' '? 0 : -1);
                    861: }
                    862: 
                    863: readtape(buffer)
                    864: char *buffer;
                    865: {
                    866:        int i, j;
                    867: 
                    868:        if (recno >= nblock || first == 0) {
                    869:                if (first == 0 && nblock == 0)
                    870:                        j =  fflag ? NBLOCK : 1; /* orignally, NBLOCK;  */
                    871:                else
                    872:                        j = nblock;
                    873:                if ((i = read(mt, tbuf, TBLOCK*j)) < 0) {
                    874:                        fprintf(stderr, "Tar: tape read error\n");
                    875:                        done(3);
                    876:                }
                    877:                if (first == 0) {
                    878:                        if ((i % TBLOCK) != 0) {
                    879:                                fprintf(stderr, "Tar: tape blocksize error\n");
                    880:                                done(3);
                    881:                        }
                    882:                        i /= TBLOCK;
                    883:                        if (rflag && i != 1) {
                    884:                                fprintf(stderr, "Tar: Cannot update blocked tapes (yet)\n");
                    885:                                done(4);
                    886:                        }
                    887:                        if (i != nblock && (i != 1 || nblock == 0)) {
                    888:                                fprintf(stderr, "Tar: blocksize = %d\n", i);
                    889:                                nblock = i;
                    890:                        }
                    891:                }
                    892:                recno = 0;
                    893:        }
                    894:        first = 1;
                    895:        copy(buffer, &tbuf[recno++]);
                    896:        return(TBLOCK);
                    897: }
                    898: 
                    899: writetape(buffer)
                    900: char *buffer;
                    901: {
                    902:        first = 1;
                    903:        if (nblock == 0)
                    904:                nblock = 1;
                    905:        if (recno >= nblock) {
                    906:                if (write(mt, tbuf, TBLOCK*nblock) < 0) {
                    907:                        fprintf(stderr, "Tar: tape write error\n");
                    908:                        done(2);
                    909:                }
                    910:                recno = 0;
                    911:        }
                    912:        copy(&tbuf[recno++], buffer);
                    913:        if (recno >= nblock) {
                    914:                if (write(mt, tbuf, TBLOCK*nblock) < 0) {
                    915:                        fprintf(stderr, "Tar: tape write error\n");
                    916:                        done(2);
                    917:                }
                    918:                recno = 0;
                    919:        }
                    920:        return(TBLOCK);
                    921: }
                    922: 
                    923: backtape()
                    924: {
                    925:        lseek(mt, (long) -TBLOCK, 1);
                    926:        if (recno >= nblock) {
                    927:                recno = nblock - 1;
                    928:                if (read(mt, tbuf, TBLOCK*nblock) < 0) {
                    929:                        fprintf(stderr, "Tar: tape read error after seek\n");
                    930:                        done(4);
                    931:                }
                    932:                lseek(mt, (long) -TBLOCK, 1);
                    933:        }
                    934: }
                    935: 
                    936: flushtape()
                    937: {
                    938:        write(mt, tbuf, TBLOCK*nblock);
                    939: }
                    940: 
                    941: copy(to, from)
                    942: register char *to, *from;
                    943: {
                    944:        register i;
                    945: 
                    946:        i = TBLOCK;
                    947:        do {
                    948:                *to++ = *from++;
                    949:        } while (--i);
                    950: }

unix.superglobalmegacorp.com

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