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

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

unix.superglobalmegacorp.com

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