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

unix.superglobalmegacorp.com

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