Annotation of 3BSD/cmd/ar.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 <ar.h>
                      5: #include <signal.h>
                      6: struct stat    stbuf;
                      7: struct ar_hdr  arbuf;
                      8: 
                      9: #define        SKIP    1
                     10: #define        IODD    2
                     11: #define        OODD    4
                     12: #define        HEAD    8
                     13: 
                     14: char   *man    =       { "mrxtdpq" };
                     15: char   *opt    =       { "uvnbail" };
                     16: 
                     17: int    signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
                     18: int    sigdone();
                     19: long   lseek();
                     20: int    rcmd();
                     21: int    dcmd();
                     22: int    xcmd();
                     23: int    tcmd();
                     24: int    pcmd();
                     25: int    mcmd();
                     26: int    qcmd();
                     27: int    (*comfun)();
                     28: char   flg[26];
                     29: char   **namv;
                     30: int    namc;
                     31: char   *arnam;
                     32: char   *ponam;
                     33: char   *tmpnam         =       { "/tmp/vXXXXX" };
                     34: char   *tmp1nam        =       { "/tmp/v1XXXXX" };
                     35: char   *tmp2nam        =       { "/tmp/v2XXXXX" };
                     36: char   *tfnam;
                     37: char   *tf1nam;
                     38: char   *tf2nam;
                     39: char   *file;
                     40: char   name[16];
                     41: int    af;
                     42: int    tf;
                     43: int    tf1;
                     44: int    tf2;
                     45: int    qf;
                     46: int    bastate;
                     47: char   buf[BUFSIZ];
                     48: 
                     49: char   *trim();
                     50: char   *mktemp();
                     51: char   *ctime();
                     52: 
                     53: main(argc, argv)
                     54: char *argv[];
                     55: {
                     56:        register i;
                     57:        register char *cp;
                     58: 
                     59:        for(i=0; signum[i]; i++)
                     60:                if(signal(signum[i], SIG_IGN) != SIG_IGN)
                     61:                        signal(signum[i], sigdone);
                     62:        if(argc < 3)
                     63:                usage();
                     64:        cp = argv[1];
                     65:        for(cp = argv[1]; *cp; cp++)
                     66:        switch(*cp) {
                     67:        case 'l':
                     68:        case 'v':
                     69:        case 'u':
                     70:        case 'n':
                     71:        case 'a':
                     72:        case 'b':
                     73:        case 'c':
                     74:        case 'i':
                     75:                flg[*cp - 'a']++;
                     76:                continue;
                     77: 
                     78:        case 'r':
                     79:                setcom(rcmd);
                     80:                continue;
                     81: 
                     82:        case 'd':
                     83:                setcom(dcmd);
                     84:                continue;
                     85: 
                     86:        case 'x':
                     87:                setcom(xcmd);
                     88:                continue;
                     89: 
                     90:        case 't':
                     91:                setcom(tcmd);
                     92:                continue;
                     93: 
                     94:        case 'p':
                     95:                setcom(pcmd);
                     96:                continue;
                     97: 
                     98:        case 'm':
                     99:                setcom(mcmd);
                    100:                continue;
                    101: 
                    102:        case 'q':
                    103:                setcom(qcmd);
                    104:                continue;
                    105: 
                    106:        default:
                    107:                fprintf(stderr, "ar: bad option `%c'\n", *cp);
                    108:                done(1);
                    109:        }
                    110:        if(flg['l'-'a']) {
                    111:                tmpnam = "vXXXXX";
                    112:                tmp1nam = "v1XXXXX";
                    113:                tmp2nam = "v2XXXXX";
                    114:                }
                    115:        if(flg['i'-'a'])
                    116:                flg['b'-'a']++;
                    117:        if(flg['a'-'a'] || flg['b'-'a']) {
                    118:                bastate = 1;
                    119:                ponam = trim(argv[2]);
                    120:                argv++;
                    121:                argc--;
                    122:                if(argc < 3)
                    123:                        usage();
                    124:        }
                    125:        arnam = argv[2];
                    126:        namv = argv+3;
                    127:        namc = argc-3;
                    128:        if(comfun == 0) {
                    129:                if(flg['u'-'a'] == 0) {
                    130:                        fprintf(stderr, "ar: one of [%s] must be specified\n", man);
                    131:                        done(1);
                    132:                }
                    133:                setcom(rcmd);
                    134:        }
                    135:        (*comfun)();
                    136:        done(notfound());
                    137: }
                    138: 
                    139: setcom(fun)
                    140: int (*fun)();
                    141: {
                    142: 
                    143:        if(comfun != 0) {
                    144:                fprintf(stderr, "ar: only one of [%s] allowed\n", man);
                    145:                done(1);
                    146:        }
                    147:        comfun = fun;
                    148: }
                    149: 
                    150: rcmd()
                    151: {
                    152:        register f;
                    153: 
                    154:        init();
                    155:        getaf();
                    156:        while(!getdir()) {
                    157:                bamatch();
                    158:                if(namc == 0 || match()) {
                    159:                        f = stats();
                    160:                        if(f < 0) {
                    161:                                if(namc)
                    162:                                        fprintf(stderr, "ar: cannot open %s\n", file);
                    163:                                goto cp;
                    164:                        }
                    165:                        if(flg['u'-'a'])
                    166:                                if(stbuf.st_mtime <= arbuf.ar_date) {
                    167:                                        close(f);
                    168:                                        goto cp;
                    169:                                }
                    170:                        mesg('r');
                    171:                        copyfil(af, -1, IODD+SKIP);
                    172:                        movefil(f);
                    173:                        continue;
                    174:                }
                    175:        cp:
                    176:                mesg('c');
                    177:                copyfil(af, tf, IODD+OODD+HEAD);
                    178:        }
                    179:        cleanup();
                    180: }
                    181: 
                    182: dcmd()
                    183: {
                    184: 
                    185:        init();
                    186:        if(getaf())
                    187:                noar();
                    188:        while(!getdir()) {
                    189:                if(match()) {
                    190:                        mesg('d');
                    191:                        copyfil(af, -1, IODD+SKIP);
                    192:                        continue;
                    193:                }
                    194:                mesg('c');
                    195:                copyfil(af, tf, IODD+OODD+HEAD);
                    196:        }
                    197:        install();
                    198: }
                    199: 
                    200: xcmd()
                    201: {
                    202:        register f;
                    203: 
                    204:        if(getaf())
                    205:                noar();
                    206:        while(!getdir()) {
                    207:                if(namc == 0 || match()) {
                    208:                        f = creat(file, arbuf.ar_mode & 0777);
                    209:                        if(f < 0) {
                    210:                                fprintf(stderr, "ar: %s cannot create\n", file);
                    211:                                goto sk;
                    212:                        }
                    213:                        mesg('x');
                    214:                        copyfil(af, f, IODD);
                    215:                        close(f);
                    216:                        continue;
                    217:                }
                    218:        sk:
                    219:                mesg('c');
                    220:                copyfil(af, -1, IODD+SKIP);
                    221:                if (namc > 0  &&  !morefil())
                    222:                        done(0);
                    223:        }
                    224: }
                    225: 
                    226: pcmd()
                    227: {
                    228: 
                    229:        if(getaf())
                    230:                noar();
                    231:        while(!getdir()) {
                    232:                if(namc == 0 || match()) {
                    233:                        if(flg['v'-'a']) {
                    234:                                printf("\n<%s>\n\n", file);
                    235:                                fflush(stdout);
                    236:                        }
                    237:                        copyfil(af, 1, IODD);
                    238:                        continue;
                    239:                }
                    240:                copyfil(af, -1, IODD+SKIP);
                    241:        }
                    242: }
                    243: 
                    244: mcmd()
                    245: {
                    246: 
                    247:        init();
                    248:        if(getaf())
                    249:                noar();
                    250:        tf2nam = mktemp(tmp2nam);
                    251:        close(creat(tf2nam, 0600));
                    252:        tf2 = open(tf2nam, 2);
                    253:        if(tf2 < 0) {
                    254:                fprintf(stderr, "ar: cannot create third temp\n");
                    255:                done(1);
                    256:        }
                    257:        while(!getdir()) {
                    258:                bamatch();
                    259:                if(match()) {
                    260:                        mesg('m');
                    261:                        copyfil(af, tf2, IODD+OODD+HEAD);
                    262:                        continue;
                    263:                }
                    264:                mesg('c');
                    265:                copyfil(af, tf, IODD+OODD+HEAD);
                    266:        }
                    267:        install();
                    268: }
                    269: 
                    270: tcmd()
                    271: {
                    272: 
                    273:        if(getaf())
                    274:                noar();
                    275:        while(!getdir()) {
                    276:                if(namc == 0 || match()) {
                    277:                        if(flg['v'-'a'])
                    278:                                longt();
                    279:                        printf("%s\n", trim(file));
                    280:                }
                    281:                copyfil(af, -1, IODD+SKIP);
                    282:        }
                    283: }
                    284: 
                    285: qcmd()
                    286: {
                    287:        register i, f;
                    288: 
                    289:        if (flg['a'-'a'] || flg['b'-'a']) {
                    290:                fprintf(stderr, "ar: abi not allowed with q\n");
                    291:                done(1);
                    292:        }
                    293:        getqf();
                    294:        for(i=0; signum[i]; i++)
                    295:                signal(signum[i], SIG_IGN);
                    296:        lseek(qf, 0l, 2);
                    297:        for(i=0; i<namc; i++) {
                    298:                file = namv[i];
                    299:                if(file == 0)
                    300:                        continue;
                    301:                namv[i] = 0;
                    302:                mesg('q');
                    303:                f = stats();
                    304:                if(f < 0) {
                    305:                        fprintf(stderr, "ar: %s cannot open\n", file);
                    306:                        continue;
                    307:                }
                    308:                tf = qf;
                    309:                movefil(f);
                    310:                qf = tf;
                    311:        }
                    312: }
                    313: 
                    314: init()
                    315: {
                    316:        static mbuf = ARMAG;
                    317: 
                    318:        tfnam = mktemp(tmpnam);
                    319:        close(creat(tfnam, 0600));
                    320:        tf = open(tfnam, 2);
                    321:        if(tf < 0) {
                    322:                fprintf(stderr, "ar: cannot create temp file\n");
                    323:                done(1);
                    324:        }
                    325:        if (write(tf, (char *)&mbuf, sizeof(int)) != sizeof(int))
                    326:                wrerr();
                    327: }
                    328: 
                    329: getaf()
                    330: {
                    331:        int mbuf;
                    332: 
                    333:        af = open(arnam, 0);
                    334:        if(af < 0)
                    335:                return(1);
                    336:        if (read(af, (char *)&mbuf, sizeof(int)) != sizeof(int) || mbuf!=ARMAG) {
                    337:                fprintf(stderr, "ar: %s not in archive format\n", arnam);
                    338:                done(1);
                    339:        }
                    340:        return(0);
                    341: }
                    342: 
                    343: getqf()
                    344: {
                    345:        int mbuf;
                    346: 
                    347:        if ((qf = open(arnam, 2)) < 0) {
                    348:                if(!flg['c'-'a'])
                    349:                        fprintf(stderr, "ar: creating %s\n", arnam);
                    350:                close(creat(arnam, 0666));
                    351:                if ((qf = open(arnam, 2)) < 0) {
                    352:                        fprintf(stderr, "ar: cannot create %s\n", arnam);
                    353:                        done(1);
                    354:                }
                    355:                mbuf = ARMAG;
                    356:                if (write(qf, (char *)&mbuf, sizeof(int)) != sizeof(int))
                    357:                        wrerr();
                    358:        }
                    359:        else if (read(qf, (char *)&mbuf, sizeof(int)) != sizeof(int)
                    360:                || mbuf!=ARMAG) {
                    361:                fprintf(stderr, "ar: %s not in archive format\n", arnam);
                    362:                done(1);
                    363:        }
                    364: }
                    365: 
                    366: usage()
                    367: {
                    368:        printf("usage: ar [%s][%s] archive files ...\n", opt, man);
                    369:        done(1);
                    370: }
                    371: 
                    372: noar()
                    373: {
                    374: 
                    375:        fprintf(stderr, "ar: %s does not exist\n", arnam);
                    376:        done(1);
                    377: }
                    378: 
                    379: sigdone()
                    380: {
                    381:        done(100);
                    382: }
                    383: 
                    384: done(c)
                    385: {
                    386: 
                    387:        if(tfnam)
                    388:                unlink(tfnam);
                    389:        if(tf1nam)
                    390:                unlink(tf1nam);
                    391:        if(tf2nam)
                    392:                unlink(tf2nam);
                    393:        exit(c);
                    394: }
                    395: 
                    396: notfound()
                    397: {
                    398:        register i, n;
                    399: 
                    400:        n = 0;
                    401:        for(i=0; i<namc; i++)
                    402:                if(namv[i]) {
                    403:                        fprintf(stderr, "ar: %s not found\n", namv[i]);
                    404:                        n++;
                    405:                }
                    406:        return(n);
                    407: }
                    408: 
                    409: morefil()
                    410: {
                    411:        register i, n;
                    412: 
                    413:        n = 0;
                    414:        for(i=0; i<namc; i++)
                    415:                if(namv[i])
                    416:                        n++;
                    417:        return(n);
                    418: }
                    419: 
                    420: cleanup()
                    421: {
                    422:        register i, f;
                    423: 
                    424:        for(i=0; i<namc; i++) {
                    425:                file = namv[i];
                    426:                if(file == 0)
                    427:                        continue;
                    428:                namv[i] = 0;
                    429:                mesg('a');
                    430:                f = stats();
                    431:                if(f < 0) {
                    432:                        fprintf(stderr, "ar: %s cannot open\n", file);
                    433:                        continue;
                    434:                }
                    435:                movefil(f);
                    436:        }
                    437:        install();
                    438: }
                    439: 
                    440: install()
                    441: {
                    442:        register i;
                    443: 
                    444:        for(i=0; signum[i]; i++)
                    445:                signal(signum[i], SIG_IGN);
                    446:        if(af < 0)
                    447:                if(!flg['c'-'a'])
                    448:                        fprintf(stderr, "ar: creating %s\n", arnam);
                    449:        close(af);
                    450:        af = creat(arnam, 0666);
                    451:        if(af < 0) {
                    452:                fprintf(stderr, "ar: cannot create %s\n", arnam);
                    453:                done(1);
                    454:        }
                    455:        if(tfnam) {
                    456:                lseek(tf, 0l, 0);
                    457:                while((i = read(tf, buf, BUFSIZ)) > 0)
                    458:                        if (write(af, buf, i) != i)
                    459:                                wrerr();
                    460:        }
                    461:        if(tf2nam) {
                    462:                lseek(tf2, 0l, 0);
                    463:                while((i = read(tf2, buf, BUFSIZ)) > 0)
                    464:                        if (write(af, buf, i) != i)
                    465:                                wrerr();
                    466:        }
                    467:        if(tf1nam) {
                    468:                lseek(tf1, 0l, 0);
                    469:                while((i = read(tf1, buf, BUFSIZ)) > 0)
                    470:                        if (write(af, buf, i) != i)
                    471:                                wrerr();
                    472:        }
                    473: }
                    474: 
                    475: /*
                    476:  * insert the file 'file'
                    477:  * into the temporary file
                    478:  */
                    479: movefil(f)
                    480: {
                    481:        register char *cp;
                    482:        register i;
                    483: 
                    484:        cp = trim(file);
                    485:        for(i=0; i<14; i++)
                    486:                if(arbuf.ar_name[i] = *cp)
                    487:                        cp++;
                    488:        arbuf.ar_size = stbuf.st_size;
                    489:        arbuf.ar_date = stbuf.st_mtime;
                    490:        arbuf.ar_uid = stbuf.st_uid;
                    491:        arbuf.ar_gid = stbuf.st_gid;
                    492:        arbuf.ar_mode = stbuf.st_mode;
                    493:        copyfil(f, tf, OODD+HEAD);
                    494:        close(f);
                    495: }
                    496: 
                    497: stats()
                    498: {
                    499:        register f;
                    500: 
                    501:        f = open(file, 0);
                    502:        if(f < 0)
                    503:                return(f);
                    504:        if(fstat(f, &stbuf) < 0) {
                    505:                close(f);
                    506:                return(-1);
                    507:        }
                    508:        return(f);
                    509: }
                    510: 
                    511: /*
                    512:  * copy next file
                    513:  * size given in arbuf
                    514:  */
                    515: copyfil(fi, fo, flag)
                    516: {
                    517:        register i, o;
                    518:        int pe;
                    519: 
                    520:        if(flag & HEAD)
                    521:                if (write(fo, (char *)&arbuf, sizeof arbuf) != sizeof arbuf)
                    522:                        wrerr();
                    523:        pe = 0;
                    524:        while(arbuf.ar_size > 0) {
                    525:                i = o = BUFSIZ;
                    526:                if(arbuf.ar_size < i) {
                    527:                        i = o = arbuf.ar_size;
                    528:                        if(i&1) {
                    529:                                if(flag & IODD)
                    530:                                        i++;
                    531:                                if(flag & OODD)
                    532:                                        o++;
                    533:                        }
                    534:                }
                    535:                if(read(fi, buf, i) != i)
                    536:                        pe++;
                    537:                if((flag & SKIP) == 0)
                    538:                        if (write(fo, buf, o) != o)
                    539:                                wrerr();
                    540:                arbuf.ar_size -= BUFSIZ;
                    541:        }
                    542:        if(pe)
                    543:                phserr();
                    544: }
                    545: 
                    546: getdir()
                    547: {
                    548:        register i;
                    549: 
                    550:        i = read(af, (char *)&arbuf, sizeof arbuf);
                    551:        if(i != sizeof arbuf) {
                    552:                if(tf1nam) {
                    553:                        i = tf;
                    554:                        tf = tf1;
                    555:                        tf1 = i;
                    556:                }
                    557:                return(1);
                    558:        }
                    559:        for(i=0; i<14; i++)
                    560:                name[i] = arbuf.ar_name[i];
                    561:        file = name;
                    562:        return(0);
                    563: }
                    564: 
                    565: match()
                    566: {
                    567:        register i;
                    568: 
                    569:        for(i=0; i<namc; i++) {
                    570:                if(namv[i] == 0)
                    571:                        continue;
                    572:                if(strcmp(trim(namv[i]), file) == 0) {
                    573:                        file = namv[i];
                    574:                        namv[i] = 0;
                    575:                        return(1);
                    576:                }
                    577:        }
                    578:        return(0);
                    579: }
                    580: 
                    581: bamatch()
                    582: {
                    583:        register f;
                    584: 
                    585:        switch(bastate) {
                    586: 
                    587:        case 1:
                    588:                if(strcmp(file, ponam) != 0)
                    589:                        return;
                    590:                bastate = 2;
                    591:                if(flg['a'-'a'])
                    592:                        return;
                    593: 
                    594:        case 2:
                    595:                bastate = 0;
                    596:                tf1nam = mktemp(tmp1nam);
                    597:                close(creat(tf1nam, 0600));
                    598:                f = open(tf1nam, 2);
                    599:                if(f < 0) {
                    600:                        fprintf(stderr, "ar: cannot create second temp\n");
                    601:                        return;
                    602:                }
                    603:                tf1 = tf;
                    604:                tf = f;
                    605:        }
                    606: }
                    607: 
                    608: phserr()
                    609: {
                    610: 
                    611:        fprintf(stderr, "ar: phase error on %s\n", file);
                    612: }
                    613: 
                    614: mesg(c)
                    615: {
                    616: 
                    617:        if(flg['v'-'a'])
                    618:                if(c != 'c' || flg['v'-'a'] > 1)
                    619:                        printf("%c - %s\n", c, file);
                    620: }
                    621: 
                    622: char *
                    623: trim(s)
                    624: char *s;
                    625: {
                    626:        register char *p1, *p2;
                    627: 
                    628:        for(p1 = s; *p1; p1++)
                    629:                ;
                    630:        while(p1 > s) {
                    631:                if(*--p1 != '/')
                    632:                        break;
                    633:                *p1 = 0;
                    634:        }
                    635:        p2 = s;
                    636:        for(p1 = s; *p1; p1++)
                    637:                if(*p1 == '/')
                    638:                        p2 = p1+1;
                    639:        return(p2);
                    640: }
                    641: 
                    642: #define        IFMT    060000
                    643: #define        ISARG   01000
                    644: #define        LARGE   010000
                    645: #define        SUID    04000
                    646: #define        SGID    02000
                    647: #define        ROWN    0400
                    648: #define        WOWN    0200
                    649: #define        XOWN    0100
                    650: #define        RGRP    040
                    651: #define        WGRP    020
                    652: #define        XGRP    010
                    653: #define        ROTH    04
                    654: #define        WOTH    02
                    655: #define        XOTH    01
                    656: #define        STXT    01000
                    657: 
                    658: longt()
                    659: {
                    660:        register char *cp;
                    661: 
                    662:        pmode();
                    663:        printf("%3d/%1d", arbuf.ar_uid, arbuf.ar_gid);
                    664:        printf("%7D", arbuf.ar_size);
                    665:        cp = ctime(&arbuf.ar_date);
                    666:        printf(" %-12.12s %-4.4s ", cp+4, cp+20);
                    667: }
                    668: 
                    669: int    m1[] = { 1, ROWN, 'r', '-' };
                    670: int    m2[] = { 1, WOWN, 'w', '-' };
                    671: int    m3[] = { 2, SUID, 's', XOWN, 'x', '-' };
                    672: int    m4[] = { 1, RGRP, 'r', '-' };
                    673: int    m5[] = { 1, WGRP, 'w', '-' };
                    674: int    m6[] = { 2, SGID, 's', XGRP, 'x', '-' };
                    675: int    m7[] = { 1, ROTH, 'r', '-' };
                    676: int    m8[] = { 1, WOTH, 'w', '-' };
                    677: int    m9[] = { 2, STXT, 't', XOTH, 'x', '-' };
                    678: 
                    679: int    *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
                    680: 
                    681: pmode()
                    682: {
                    683:        register int **mp;
                    684: 
                    685:        for (mp = &m[0]; mp < &m[9];)
                    686:                select(*mp++);
                    687: }
                    688: 
                    689: select(pairp)
                    690: int *pairp;
                    691: {
                    692:        register int n, *ap;
                    693: 
                    694:        ap = pairp;
                    695:        n = *ap++;
                    696:        while (--n>=0 && (arbuf.ar_mode&*ap++)==0)
                    697:                ap++;
                    698:        putchar(*ap);
                    699: }
                    700: 
                    701: wrerr()
                    702: {
                    703:        perror("ar write error");
                    704:        done(1);
                    705: }

unix.superglobalmegacorp.com

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