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

unix.superglobalmegacorp.com

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