Annotation of researchv9/jerq/sgs/ar/ar.c, revision 1.1

1.1     ! root        1: /*     @(#)ar.c        2.8 10/12/83    */
        !             2: /* ar: UNIX Archive Maintainer */
        !             3: 
        !             4: 
        !             5: #include <stdio.h>
        !             6: #include <signal.h>
        !             7: #include <sys/types.h>
        !             8: #include <sys/stat.h>
        !             9: #include <ar.h>
        !            10: #include <filehdr.h>
        !            11: #include <syms.h>
        !            12: #include <string.h>
        !            13: 
        !            14: 
        !            15: #define        SKIP    1
        !            16: #define        IODD    2
        !            17: #define        OODD    4
        !            18: #define        HEAD    8
        !            19: 
        !            20: #define        SUID    04000
        !            21: #define        SGID    02000
        !            22: #define        ROWN    0400
        !            23: #define        WOWN    0200
        !            24: #define        XOWN    0100
        !            25: #define        RGRP    040
        !            26: #define        WGRP    020
        !            27: #define        XGRP    010
        !            28: #define        ROTH    04
        !            29: #define        WOTH    02
        !            30: #define        XOTH    01
        !            31: #define        STXT    01000
        !            32: 
        !            33: #define TABSZ  2000
        !            34: 
        !            35: #define SYMDIRNAME     "/               "      /* symbol directory filename */
        !            36: 
        !            37: struct stat    stbuf;
        !            38: 
        !            39: struct ar_hdr  ariobuf;       /* input/output copy of archive member header */
        !            40: 
        !            41: struct         /* usable copy of archive file member header */
        !            42: {
        !            43:        char    ar_name[16];
        !            44:        long    ar_date;
        !            45:        int     ar_uid;
        !            46:        int     ar_gid;
        !            47:        long    ar_mode;
        !            48:        long    ar_size;
        !            49: } arbuf;
        !            50: 
        !            51: long   sym_ptr[TABSZ];         /* offsets for symbol directory */
        !            52: char   sym_offsets[TABSZ][4];  /* sputl'd version of the offsets */
        !            53: char   *sym_name[TABSZ];       /* names for symbols in directory */
        !            54: char   sym_nsyms[4];           /* sputl'd number of symbols */
        !            55: 
        !            56: struct filehdr ml_filhdr;      /* COFF machine language file header */
        !            57: 
        !            58: char   *man    =       { "mrxtdpq" };
        !            59: char   *opt    =       { "uvcbailso" };
        !            60: 
        !            61: int    signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
        !            62: char   flg[26];
        !            63: char   **namv;
        !            64: int    namc;
        !            65: char   *arnam;
        !            66: char   *ponam;
        !            67: char   *tmpdir = ""; /* default temp file directory to environment */
        !            68: char   *tfnam;
        !            69: char   *tf1nam;
        !            70: char   *tf2nam;
        !            71: char   *file;
        !            72: char   name[16];
        !            73: int    af;
        !            74: int    tf;
        !            75: int    tf1;
        !            76: int    tf2;
        !            77: int    qf;
        !            78: 
        !            79: int    bastate;
        !            80: char   buf[BUFSIZ];
        !            81: 
        !            82: 
        !            83: int    update;         /* was archive written or updated */
        !            84: int    nsyms;          /* nbr of symbol directory entries */
        !            85: long   mem_ptr;        /* position of archive member in the archive */
        !            86: long   mem_skip;       /* adjustment to add to mem_ptr for "real" position */
        !            87: 
        !            88: int    filenum = 0;    /* incremented by ml_file() for getname()'s benefit */
        !            89: 
        !            90: char   *str_base,      /* start of string table for names */
        !            91:        *str_top;       /* pointer to next available location */
        !            92: 
        !            93: 
        !            94: int    m1[] = { 1, ROWN, 'r', '-' };
        !            95: int    m2[] = { 1, WOWN, 'w', '-' };
        !            96: int    m3[] = { 2, SUID, 's', XOWN, 'x', '-' };
        !            97: int    m4[] = { 1, RGRP, 'r', '-' };
        !            98: int    m5[] = { 1, WGRP, 'w', '-' };
        !            99: int    m6[] = { 2, SGID, 's', XGRP, 'x', '-' };
        !           100: int    m7[] = { 1, ROTH, 'r', '-' };
        !           101: int    m8[] = { 1, WOTH, 'w', '-' };
        !           102: int    m9[] = { 2, STXT, 't', XOTH, 'x', '-' };
        !           103: 
        !           104: int    *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
        !           105: 
        !           106: 
        !           107:        /* declare all archive functions */
        !           108:        
        !           109: int    setcom(),       rcmd(),         dcmd(),         xcmd(),
        !           110:        pcmd(),         mcmd(),         tcmd(),         qcmd(),
        !           111:        init(),         getaf(),        getqf(),        usage(),
        !           112:        noar(),         sigdone(),      done(),         notfound(),
        !           113:        morefil(),      cleanup(),      install(),      movefil(),
        !           114:        stats(),        copyfil(),      getdir(),       match(),
        !           115:        bamatch(),      phserr(),       mesg(),         longt(),
        !           116:        pmode(),        select(),       wrerr(),        mksymtab(),
        !           117:        ml_file(),      sputl();
        !           118: char   *trim(),        *trimslash(),   *getname();
        !           119: 
        !           120: char   *tempnam();
        !           121: char   *ctime();
        !           122: long   time();
        !           123: 
        !           124: int    (*comfun)();
        !           125: 
        !           126: 
        !           127: 
        !           128: main(argc, argv)
        !           129:        int argc;
        !           130:        char **argv;
        !           131: {
        !           132:        register int i;
        !           133:        register char *cp;
        !           134: 
        !           135:        for (i = 0; signum[i]; i++)
        !           136:                if (signal(signum[i], SIG_IGN) != SIG_IGN)
        !           137:                        signal(signum[i], sigdone);
        !           138:        if (argc < 3)
        !           139:                usage();
        !           140:        cp = argv[1];
        !           141:        if (*cp == '-') /* skip a '-', make ar more like other commands */
        !           142:                cp++;
        !           143:        for (; *cp; cp++)
        !           144:        {
        !           145:                switch (*cp)
        !           146:                {
        !           147:                case 'l':
        !           148:                case 'v':
        !           149:                case 'u':
        !           150:                case 'a':
        !           151:                case 'b':
        !           152:                case 'c':
        !           153:                case 'i':
        !           154:                case 's':
        !           155:                case 'o':
        !           156:                        flg[*cp - 'a']++;
        !           157:                        continue;
        !           158:                case 'r':
        !           159:                        setcom(rcmd);
        !           160:                        flg[*cp - 'a']++;
        !           161:                        continue;
        !           162:                case 'd':
        !           163:                        setcom(dcmd);
        !           164:                        flg[*cp - 'a']++;
        !           165:                        continue;
        !           166:                case 'x':
        !           167:                        setcom(xcmd);
        !           168:                        flg[*cp - 'a']++;
        !           169:                        continue;
        !           170:                case 't':
        !           171:                        setcom(tcmd);
        !           172:                        flg[*cp - 'a']++;
        !           173:                        continue;
        !           174:                case 'p':
        !           175:                        setcom(pcmd);
        !           176:                        flg[*cp - 'a']++;
        !           177:                        continue;
        !           178:                case 'm':
        !           179:                        setcom(mcmd);
        !           180:                        flg[*cp - 'a']++;
        !           181:                        continue;
        !           182:                case 'q':
        !           183:                        setcom(qcmd);
        !           184:                        flg[*cp - 'a']++;
        !           185:                        continue;
        !           186:                default:
        !           187:                        fprintf(stderr, "ar: bad option `%c'\n", *cp);
        !           188:                        done(1);
        !           189:                }
        !           190:        }
        !           191:        if (flg['l' - 'a'])
        !           192:                tmpdir = ".";   /* use local directory for temp files */
        !           193:        if (flg['i' - 'a'])
        !           194:                flg['b' - 'a']++;
        !           195:        if (flg['a' - 'a'] || flg['b' - 'a'])
        !           196:        {
        !           197:                bastate = 1;
        !           198:                ponam = trim(argv[2]);
        !           199:                argv++;
        !           200:                argc--;
        !           201:                if (argc < 3)
        !           202:                        usage();
        !           203:        }
        !           204:        arnam = argv[2];
        !           205:        namv = argv + 3;
        !           206:        namc = argc - 3;
        !           207:        if (comfun == 0)
        !           208:        {
        !           209:                if (flg['u' - 'a'] == 0)
        !           210:                {
        !           211:                        fprintf(stderr,
        !           212:                                "ar: one of [%s] must be specified\n", man);
        !           213:                        done(1);
        !           214:                }
        !           215:                setcom(rcmd);
        !           216:        }
        !           217:        update = (flg['d' - 'a'] | flg['q' - 'a'] | flg['m' - 'a'] |
        !           218:                flg['r' - 'a'] | flg['u' - 'a'] | flg['s' - 'a']);
        !           219:        (*comfun)();
        !           220:        if (update)     /* make archive symbol table */
        !           221:                mksymtab();
        !           222:        done(notfound());
        !           223: }
        !           224: 
        !           225: 
        !           226: 
        !           227: setcom(fun)
        !           228:        int (*fun)();
        !           229: {
        !           230: 
        !           231:        if (comfun != 0)
        !           232:        {
        !           233:                fprintf(stderr, "ar: only one of [%s] allowed\n", man);
        !           234:                done(1);
        !           235:        }
        !           236:        comfun = fun;
        !           237: }
        !           238: 
        !           239: 
        !           240: 
        !           241: rcmd()
        !           242: {
        !           243:        register int f;
        !           244: 
        !           245:        init();
        !           246:        getaf();
        !           247:        while (!getdir())
        !           248:        {
        !           249:                bamatch();
        !           250:                if (namc == 0 || match())
        !           251:                {
        !           252:                        f = stats();
        !           253:                        if (f < 0)
        !           254:                        {
        !           255:                                if (namc)
        !           256:                                        fprintf(stderr,
        !           257:                                                "ar: cannot open %s\n", file);
        !           258:                                goto cp;
        !           259:                        }
        !           260:                        if (flg['u' - 'a'])
        !           261:                                if (stbuf.st_mtime <= arbuf.ar_date)
        !           262:                                {
        !           263:                                        close(f);
        !           264:                                        goto cp;
        !           265:                                }
        !           266:                        mesg('r');
        !           267:                        copyfil(af, -1, IODD + SKIP);
        !           268:                        movefil(f);
        !           269:                        continue;
        !           270:                }
        !           271:        cp:
        !           272:                mesg('c');
        !           273:                copyfil(af, tf, IODD + OODD + HEAD);
        !           274:        }
        !           275:        cleanup();
        !           276: }
        !           277: 
        !           278: 
        !           279: 
        !           280: 
        !           281: dcmd()
        !           282: {
        !           283:        init();
        !           284:        if (getaf())
        !           285:                noar();
        !           286:        while (!getdir())
        !           287:        {
        !           288:                if (match())
        !           289:                {
        !           290:                        mesg('d');
        !           291:                        copyfil(af, -1, IODD + SKIP);
        !           292:                        continue;
        !           293:                }
        !           294:                mesg('c');
        !           295:                copyfil(af, tf, IODD + OODD + HEAD);
        !           296:        }
        !           297:        install();
        !           298: }
        !           299: 
        !           300: 
        !           301: 
        !           302: 
        !           303: xcmd()
        !           304: {
        !           305:        register int f;
        !           306: 
        !           307:        if (getaf())
        !           308:                noar();
        !           309:        while (!getdir())
        !           310:        {
        !           311:                if (namc == 0 || match())
        !           312:                {
        !           313:                        f = creat(file, arbuf.ar_mode & 0777);
        !           314:                        if (f < 0)
        !           315:                        {
        !           316:                                fprintf(stderr, "ar: %s cannot create\n", file);
        !           317:                                goto sk;
        !           318:                        }
        !           319:                        mesg('x');
        !           320:                        copyfil(af, f, IODD);
        !           321:                        close(f);
        !           322:                        if(flg['o'-'a']) {
        !           323:                                long timep[2];
        !           324:                                timep[0] = arbuf.ar_date;
        !           325:                                timep[1] = arbuf.ar_date;
        !           326:                                utime(file, timep);
        !           327:                        }
        !           328:                        continue;
        !           329:                }
        !           330:        sk:
        !           331:                mesg('c');
        !           332:                copyfil(af, -1, IODD + SKIP);
        !           333:                if (namc > 0  &&  !morefil())
        !           334:                        done(0);
        !           335:        }
        !           336: }
        !           337: 
        !           338: 
        !           339: 
        !           340: 
        !           341: pcmd()
        !           342: {
        !           343:        if (getaf())
        !           344:                noar();
        !           345:        while (!getdir())
        !           346:        {
        !           347:                if (namc == 0 || match())
        !           348:                {
        !           349:                        if (flg['v' - 'a'])
        !           350:                        {
        !           351:                                fprintf(stdout, "\n<%s>\n\n", file);
        !           352:                                fflush(stdout);
        !           353:                        }
        !           354:                        copyfil(af, 1, IODD);
        !           355:                        continue;
        !           356:                }
        !           357:                copyfil(af, -1, IODD + SKIP);
        !           358:        }
        !           359: }
        !           360: 
        !           361: 
        !           362: 
        !           363: 
        !           364: mcmd()
        !           365: {
        !           366:        init();
        !           367:        if (getaf())
        !           368:                noar();
        !           369:        tf2nam = tempnam(tmpdir, "ar");
        !           370:        close(creat(tf2nam, 0600));
        !           371:        tf2 = open(tf2nam, 2);
        !           372:        if (tf2 < 0)
        !           373:        {
        !           374:                fprintf(stderr, "ar: cannot create third temp\n");
        !           375:                done(1);
        !           376:        }
        !           377:        while (!getdir())
        !           378:        {
        !           379:                bamatch();
        !           380:                if (match())
        !           381:                {
        !           382:                        mesg('m');
        !           383:                        copyfil(af, tf2, IODD + OODD + HEAD);
        !           384:                        continue;
        !           385:                }
        !           386:                mesg('c');
        !           387:                copyfil(af, tf, IODD + OODD + HEAD);
        !           388:        }
        !           389:        install();
        !           390: }
        !           391: 
        !           392: 
        !           393: 
        !           394: 
        !           395: tcmd()
        !           396: {
        !           397:        if (getaf())
        !           398:                noar();
        !           399:        while (!getdir())
        !           400:        {
        !           401:                if (namc == 0 || match())
        !           402:                {
        !           403:                        if (flg['v' - 'a'])
        !           404:                                longt();
        !           405:                        fprintf(stdout, "%s\n", trim(file));
        !           406:                }
        !           407:                copyfil(af, -1, IODD + SKIP);
        !           408:        }
        !           409: }
        !           410: 
        !           411: 
        !           412: 
        !           413: 
        !           414: qcmd()
        !           415: {
        !           416:        register int i, f;
        !           417:        char *tmpfilname;
        !           418:        int n;
        !           419:        int mode=0644;
        !           420: 
        !           421:        if (flg['a' - 'a'] || flg['b' - 'a'])
        !           422:        {
        !           423:                fprintf(stderr, "ar: abi not allowed with q\n");
        !           424:                done(1);
        !           425:        }
        !           426:        getqf();
        !           427:        tmpfilname = tempnam(tmpdir, "ar");
        !           428:        close(creat(tmpfilname, 0600));
        !           429:        tf = open(tmpfilname, 2);
        !           430:        if (tf < 0)
        !           431:        {
        !           432:                fprintf(stderr, "ar: cannot create temp file\n");
        !           433:                done(1);
        !           434:        }
        !           435:        lseek(qf, 0l, 0);
        !           436:        while ((n = read(qf, buf, BUFSIZ)) > 0)
        !           437:                if (write(tf, buf, n) != n)
        !           438:                        wrerr;
        !           439:        for (i = 0; signum[i]; i++)
        !           440:                signal(signum[i], SIG_IGN);
        !           441:        lseek(tf, 0l, 2);
        !           442:        for (i = 0; i < namc; i++)
        !           443:        {
        !           444:                file = namv[i];
        !           445:                if (file == 0)
        !           446:                        continue;
        !           447:                namv[i] = 0;
        !           448:                mesg('q');
        !           449:                f = stats();
        !           450:                if (f < 0)
        !           451:                {
        !           452:                        fprintf(stderr, "ar: %s cannot open\n", file);
        !           453:                        continue;
        !           454:                }
        !           455:                movefil(f);
        !           456:        }
        !           457:        lseek(tf, 0l, 0);
        !           458:        lseek(qf, 0l, 0);
        !           459:        while ((n = read(tf, buf, BUFSIZ)) > 0)
        !           460:                if (write(qf, buf, n) != n)
        !           461:                        wrerr;
        !           462: }
        !           463: 
        !           464: 
        !           465: 
        !           466: 
        !           467: init()
        !           468: {
        !           469:        tfnam = tempnam(tmpdir, "ar");
        !           470:        close(creat(tfnam, 0600));
        !           471:        tf = open(tfnam, 2);
        !           472:        if (tf < 0)
        !           473:        {
        !           474:                fprintf(stderr, "ar: cannot create temp file\n");
        !           475:                done(1);
        !           476:        }
        !           477:        if (write(tf, ARMAG, sizeof(char) * SARMAG) != sizeof(char) * SARMAG)
        !           478:                wrerr();
        !           479: }
        !           480: 
        !           481: 
        !           482: 
        !           483: 
        !           484: getaf()
        !           485: {
        !           486:        char buf[SARMAG + 1];
        !           487:        long home;
        !           488: 
        !           489:        af = open(arnam, 0);
        !           490:        if (af < 0)
        !           491:                return (1);
        !           492:        if (read(af, buf, sizeof(char) * SARMAG) != sizeof(char) * SARMAG ||
        !           493:                strncmp(buf, ARMAG, SARMAG))
        !           494:        {
        !           495:                fprintf(stderr, "ar: %s not in archive format\n", arnam);
        !           496:                done(1);
        !           497:        }
        !           498:        /*
        !           499:        * If the first entry is the symbol directory, skip it
        !           500:        */
        !           501:        home = lseek(af, 0L, 1);
        !           502:        if (!getdir() && file[0] == '\0')
        !           503:        {
        !           504:                copyfil(af, -1, IODD + SKIP);
        !           505:                return (0);
        !           506:        }
        !           507:        /*
        !           508:        * Otherwise, get back to beginning of first file header
        !           509:        */
        !           510:        if (lseek(af, home, 0) < 0)
        !           511:        {
        !           512:                fprintf(stderr, "ar: %s cannot seek\n", arnam);
        !           513:                done(1);
        !           514:        }
        !           515:        return (0);
        !           516: }
        !           517: 
        !           518: 
        !           519: 
        !           520: 
        !           521: getqf()
        !           522: {
        !           523:        char buf[SARMAG + 1];
        !           524: 
        !           525:        if ((qf = open(arnam, 2)) < 0)          /* a new archive */
        !           526:        {
        !           527:                if (!flg['c' - 'a'])
        !           528:                        fprintf(stderr, "ar: creating %s\n", arnam);
        !           529:                close(creat(arnam, 0666));
        !           530:                if ((qf = open(arnam, 2)) < 0)
        !           531:                {
        !           532:                        fprintf(stderr, "ar: cannot create %s\n", arnam);
        !           533:                        done(1);
        !           534:                }
        !           535:                if (write(qf, ARMAG, sizeof(char) * SARMAG) !=
        !           536:                        sizeof(char) * SARMAG)
        !           537:                {
        !           538:                        wrerr();
        !           539:                }
        !           540:        }
        !           541:        else if (read(qf, buf, sizeof(char) * SARMAG) !=
        !           542:                sizeof(char) * SARMAG || strncmp(buf, ARMAG, SARMAG))
        !           543:        {
        !           544:                fprintf(stderr, "ar: %s not in archive format\n", arnam);
        !           545:                done(1);
        !           546:        }
        !           547:        return (0);
        !           548: }
        !           549: 
        !           550: 
        !           551: 
        !           552: 
        !           553: usage()
        !           554: {
        !           555:        fprintf(stderr, "usage: ar [%s][%s] [posname] archive files ...\n",
        !           556:                man, opt);
        !           557:        done(1);
        !           558: }
        !           559: 
        !           560: 
        !           561: 
        !           562: 
        !           563: noar()
        !           564: {
        !           565:        fprintf(stderr, "ar: %s does not exist\n", arnam);
        !           566:        done(1);
        !           567: }
        !           568: 
        !           569: 
        !           570: 
        !           571: 
        !           572: sigdone()
        !           573: {
        !           574:        done(100);
        !           575: }
        !           576: 
        !           577: 
        !           578: 
        !           579: 
        !           580: done(c)
        !           581:        int c;
        !           582: {
        !           583:        if (tfnam)
        !           584:                unlink(tfnam);
        !           585:        if (tf1nam)
        !           586:                unlink(tf1nam);
        !           587:        if (tf2nam)
        !           588:                unlink(tf2nam);
        !           589:        exit(c);
        !           590: }
        !           591: 
        !           592: 
        !           593: 
        !           594: 
        !           595: notfound()
        !           596: {
        !           597:        register int i, n;
        !           598: 
        !           599:        n = 0;
        !           600:        for (i = 0; i < namc; i++)
        !           601:                if (namv[i])
        !           602:                {
        !           603:                        fprintf(stderr, "ar: %s not found\n", namv[i]);
        !           604:                        n++;
        !           605:                }
        !           606:        return (n);
        !           607: }
        !           608: 
        !           609: 
        !           610: 
        !           611: 
        !           612: morefil()
        !           613: {
        !           614:        register int i, n;
        !           615: 
        !           616:        n = 0;
        !           617:        for (i = 0; i < namc; i++)
        !           618:                if (namv[i])
        !           619:                        n++;
        !           620:        return (n);
        !           621: }
        !           622: 
        !           623: 
        !           624: 
        !           625: 
        !           626: cleanup()
        !           627: {
        !           628:        register int i, f;
        !           629: 
        !           630:        for (i = 0; i < namc; i++)
        !           631:        {
        !           632:                file = namv[i];
        !           633:                if (file == 0)
        !           634:                        continue;
        !           635:                namv[i] = 0;
        !           636:                mesg('a');
        !           637:                f = stats();
        !           638:                if (f < 0)
        !           639:                {
        !           640:                        fprintf(stderr, "ar: %s cannot open\n", file);
        !           641:                        continue;
        !           642:                }
        !           643:                movefil(f);
        !           644:        }
        !           645:        install();
        !           646: }
        !           647: 
        !           648: 
        !           649: 
        !           650: 
        !           651: install()
        !           652: {
        !           653:        register int i;
        !           654: 
        !           655:        for (i = 0; signum[i]; i++)
        !           656:                signal(signum[i], SIG_IGN);
        !           657:        if (af < 0)
        !           658:        {
        !           659:                if (!flg['c' - 'a'])
        !           660:                        fprintf(stderr, "ar: creating %s\n", arnam);
        !           661:        }
        !           662:        close(af);
        !           663:        af = creat(arnam, 0666);
        !           664:        if (af < 0)
        !           665:        {
        !           666:                fprintf(stderr, "ar: cannot create %s\n", arnam);
        !           667:                done(1);
        !           668:        }
        !           669:        if (tfnam)
        !           670:        {
        !           671:                lseek(tf, 0l, 0);
        !           672:                while ((i = read(tf, buf, BUFSIZ)) > 0)
        !           673:                        if (write(af, buf, i) != i)
        !           674:                                wrerr();
        !           675:        }
        !           676:        if (tf2nam)
        !           677:        {
        !           678:                lseek(tf2, 0l, 0);
        !           679:                while ((i = read(tf2, buf, BUFSIZ)) > 0)
        !           680:                        if (write(af, buf, i) != i)
        !           681:                                wrerr();
        !           682:        }
        !           683:        if (tf1nam)
        !           684:        {
        !           685:                lseek(tf1, 0l, 0);
        !           686:                while ((i = read(tf1, buf, BUFSIZ)) > 0)
        !           687:                        if (write(af, buf, i) != i)
        !           688:                                wrerr();
        !           689:        }
        !           690: }
        !           691: 
        !           692: 
        !           693: 
        !           694: /*
        !           695: * insert the file 'file' into the temporary file
        !           696: */
        !           697: movefil(f)
        !           698:        int f;
        !           699: {
        !           700:        (void)strcpy(arbuf.ar_name, trim(file));
        !           701:        arbuf.ar_size = stbuf.st_size;
        !           702:        arbuf.ar_date = stbuf.st_mtime;
        !           703:        arbuf.ar_uid = stbuf.st_uid;
        !           704:        arbuf.ar_gid = stbuf.st_gid;
        !           705:        arbuf.ar_mode = stbuf.st_mode;
        !           706:        copyfil(f, tf, OODD + HEAD);
        !           707:        close(f);
        !           708: }
        !           709: 
        !           710: 
        !           711: 
        !           712: stats()
        !           713: {
        !           714:        register int f;
        !           715: 
        !           716:        f = open(file, 0);
        !           717:        if (f < 0)
        !           718:                return(f);
        !           719:        if (fstat(f, &stbuf) < 0)
        !           720:        {
        !           721:                close(f);
        !           722:                return(-1);
        !           723:        }
        !           724:        return (f);
        !           725: }
        !           726: 
        !           727: 
        !           728: 
        !           729: 
        !           730: /*
        !           731: * copy next file size given in arbuf
        !           732: */
        !           733: copyfil(fin, fout, flag)
        !           734:        int fin, fout, flag;
        !           735: {
        !           736:        register int i, o;
        !           737:        int pe;
        !           738: int c;
        !           739: 
        !           740:        if (flag & HEAD)
        !           741:        {
        !           742:                char buf[sizeof(ariobuf) + 1];
        !           743: 
        !           744: #ifndef sun
        !           745:                if (
        !           746: #endif sun
        !           747:                    sprintf(buf, "%-16s%-12ld%-6u%-6u%-8o%-10ld%-2s",
        !           748:                        trimslash(file), arbuf.ar_date, arbuf.ar_uid,
        !           749:                        arbuf.ar_gid, arbuf.ar_mode, arbuf.ar_size,
        !           750:                        ARFMAG)
        !           751: #if sun
        !           752:                                ;
        !           753: #else
        !           754:                                != sizeof(ariobuf))
        !           755:                {
        !           756:                        fprintf(stderr,
        !           757:                                "ar: %s internal header generation error\n",
        !           758:                                arnam);
        !           759:                        done(1);
        !           760:                }
        !           761: #endif sun
        !           762:                (void)strncpy((char *)&ariobuf, buf, sizeof(ariobuf));
        !           763:                if (write(fout, &ariobuf, sizeof(ariobuf)) != sizeof(ariobuf))
        !           764:                        wrerr();
        !           765:        }
        !           766:        pe = 0;
        !           767:        while (arbuf.ar_size > 0)
        !           768:        {
        !           769:                i = o = BUFSIZ;
        !           770:                if (arbuf.ar_size < i)
        !           771:                {
        !           772:                        i = o = arbuf.ar_size;
        !           773:                        if (i & 1)
        !           774:                        {
        !           775:                                buf[i] = '\n';
        !           776:                                if (flag & IODD)
        !           777:                                        i++;
        !           778:                                if (flag & OODD)
        !           779:                                        o++;
        !           780:                        }
        !           781:                }
        !           782:                if (read(fin, buf, i) != i)
        !           783:                        pe++;
        !           784:                if ((flag & SKIP) == 0)
        !           785:                        if (write(fout, buf, o) != o)
        !           786:                                wrerr();
        !           787:                arbuf.ar_size -= BUFSIZ;
        !           788:        }
        !           789:        if (pe)
        !           790:                phserr();
        !           791: }
        !           792: 
        !           793: 
        !           794: 
        !           795: 
        !           796: getdir()
        !           797: {
        !           798:        register char *cp;
        !           799:        register int i;
        !           800: 
        !           801:        i = read(af, (char *)&ariobuf, sizeof(ariobuf));
        !           802:        if (i != sizeof(ariobuf))
        !           803:        {
        !           804:                if (tf1nam)
        !           805:                {
        !           806:                        i = tf;
        !           807:                        tf = tf1;
        !           808:                        tf1 = i;
        !           809:                }
        !           810:                return (1);
        !           811:        }
        !           812:        if (strncmp(ariobuf.ar_fmag, ARFMAG, sizeof(ariobuf.ar_fmag)))
        !           813:        {
        !           814:                fprintf(stderr, "ar: malformed archive (at %ld)\n",
        !           815:                        lseek(af, 0L, 1));
        !           816:                done(1);
        !           817:        }
        !           818:        cp = ariobuf.ar_name + sizeof(ariobuf.ar_name);
        !           819:        while (*--cp == ' ')
        !           820:                ;
        !           821:        if (*cp == '/')
        !           822:                *cp = '\0';
        !           823:        else
        !           824:                *++cp = '\0';
        !           825:        file = strcpy(name, ariobuf.ar_name);
        !           826:        (void)strncpy(arbuf.ar_name, name, sizeof(arbuf.ar_name));
        !           827:        if (sscanf(ariobuf.ar_date, "%ld", &arbuf.ar_date) != 1 ||
        !           828:                sscanf(ariobuf.ar_uid, "%d", &arbuf.ar_uid) != 1 ||
        !           829:                sscanf(ariobuf.ar_gid, "%d", &arbuf.ar_gid) != 1 ||
        !           830:                sscanf(ariobuf.ar_mode, "%o", &arbuf.ar_mode) != 1 ||
        !           831:                sscanf(ariobuf.ar_size, "%ld", &arbuf.ar_size) != 1)
        !           832:        {
        !           833:                fprintf(stderr, "ar: %s bad header layout for %s\n",
        !           834:                        arnam, name);
        !           835:                done(1);
        !           836:        }
        !           837:        return (0);
        !           838: }
        !           839: 
        !           840: 
        !           841: 
        !           842: 
        !           843: match()
        !           844: {
        !           845:        register int i;
        !           846: 
        !           847:        for (i = 0; i < namc; i++)
        !           848:        {
        !           849:                if (namv[i] == 0)
        !           850:                        continue;
        !           851:                if (strcmp(trim(namv[i]), file) == 0)
        !           852:                {
        !           853:                        file = namv[i];
        !           854:                        namv[i] = 0;
        !           855:                        return (1);
        !           856:                }
        !           857:        }
        !           858:        return (0);
        !           859: }
        !           860: 
        !           861: 
        !           862: 
        !           863: 
        !           864: bamatch()
        !           865: {
        !           866:        register int f;
        !           867: 
        !           868:        switch (bastate)
        !           869:        {
        !           870:        case 1:
        !           871:                if (strcmp(file, ponam) != 0)
        !           872:                        return;
        !           873:                bastate = 2;
        !           874:                if (flg['a' - 'a'])
        !           875:                        return;
        !           876:        case 2:
        !           877:                bastate = 0;
        !           878:                tf1nam = tempnam(tmpdir, "ar");
        !           879:                close(creat(tf1nam, 0600));
        !           880:                f = open(tf1nam, 2);
        !           881:                if (f < 0)
        !           882:                {
        !           883:                        fprintf(stderr, "ar: cannot create second temp\n");
        !           884:                        return;
        !           885:                }
        !           886:                tf1 = tf;
        !           887:                tf = f;
        !           888:        }
        !           889: }
        !           890: 
        !           891: 
        !           892: 
        !           893: 
        !           894: phserr()
        !           895: {
        !           896:        fprintf(stderr, "ar: phase error on %s\n", file);
        !           897:        done(1);
        !           898: }
        !           899: 
        !           900: 
        !           901: 
        !           902: 
        !           903: mesg(c)
        !           904:        int c;
        !           905: {
        !           906:        if (flg['v' - 'a'])
        !           907:                if (c != 'c' || flg['v' - 'a'] > 1)
        !           908:                        fprintf(stdout, "%c - %s\n", c, file);
        !           909: }
        !           910: 
        !           911: 
        !           912: 
        !           913: 
        !           914: char *
        !           915: trimslash(s)
        !           916:        char *s;
        !           917: {
        !           918:        static char buf[sizeof(arbuf.ar_name)];
        !           919: 
        !           920:        (void)strncpy(buf, trim(s), sizeof(arbuf.ar_name) - 2);
        !           921:        buf[sizeof(arbuf.ar_name) - 2] = '\0';
        !           922:        return (strcat(buf, "/"));
        !           923: }
        !           924: 
        !           925: 
        !           926: char *
        !           927: trim(s)
        !           928:        char *s;
        !           929: {
        !           930:        register char *p1, *p2;
        !           931: 
        !           932:        for (p1 = s; *p1; p1++)
        !           933:                ;
        !           934:        while (p1 > s)
        !           935:        {
        !           936:                if (*--p1 != '/')
        !           937:                        break;
        !           938:                *p1 = 0;
        !           939:        }
        !           940:        p2 = s;
        !           941:        for (p1 = s; *p1; p1++)
        !           942:                if (*p1 == '/')
        !           943:                        p2 = p1 + 1;
        !           944:        return (p2);
        !           945: }
        !           946: 
        !           947: 
        !           948: 
        !           949: 
        !           950: longt()
        !           951: {
        !           952:        register char *cp;
        !           953: 
        !           954:        pmode();
        !           955:        fprintf(stdout, "%6d/%6d", arbuf.ar_uid, arbuf.ar_gid);
        !           956:        fprintf(stdout, "%7ld", arbuf.ar_size);
        !           957:        cp = ctime(&arbuf.ar_date);
        !           958:        fprintf(stdout, " %-12.12s %-4.4s ", cp + 4, cp + 20);
        !           959: }
        !           960: 
        !           961: 
        !           962: 
        !           963: 
        !           964: pmode()
        !           965: {
        !           966:        register int **mp;
        !           967: 
        !           968:        for (mp = &m[0]; mp < &m[9];)
        !           969:                select(*mp++);
        !           970: }
        !           971: 
        !           972: 
        !           973: 
        !           974: 
        !           975: select(pairp)
        !           976:        int *pairp;
        !           977: {
        !           978:        register int n, *ap;
        !           979: 
        !           980:        ap = pairp;
        !           981:        n = *ap++;
        !           982:        while (--n >= 0 && (arbuf.ar_mode & *ap++) == 0)
        !           983:                ap++;
        !           984:        putchar(*ap);
        !           985: }
        !           986: 
        !           987: 
        !           988: 
        !           989: 
        !           990: wrerr()
        !           991: {
        !           992:        perror("ar write error");
        !           993:        done(1);
        !           994: }
        !           995: 
        !           996: 
        !           997: 
        !           998: 
        !           999: mksymtab()
        !          1000: {
        !          1001:        int i, j, offset;
        !          1002:        struct syment symbol;   /* usable copy of a symbol entry */
        !          1003:        char buf[sizeof(ariobuf) + 1];
        !          1004: 
        !          1005:        if (getaf())
        !          1006:        {
        !          1007:                fprintf(stderr, "ar: cannot make symbol directory\n");
        !          1008:                done(1);
        !          1009:        }
        !          1010:        nsyms = 0;
        !          1011:        mem_ptr = sizeof(char) * SARMAG;
        !          1012:        mem_skip = lseek(af, 0L, 1) - mem_ptr;
        !          1013:        while (!getdir())
        !          1014:        {
        !          1015:                /*
        !          1016:                * scan machine language file members for symbols
        !          1017:                */
        !          1018:                if (i = ml_file())      /* read the symbol table */
        !          1019:                {
        !          1020:                        while (i > 0)
        !          1021:                        {
        !          1022:                                i--;
        !          1023:                                if (read(af, (char *)&symbol, SYMESZ) != SYMESZ)
        !          1024:                                {
        !          1025:                                        fprintf(stderr, "ar: internal error, archive %s out of order!\n",
        !          1026:                                                arnam);
        !          1027:                                        done(1);
        !          1028:                                }
        !          1029:                                /*
        !          1030:                                * check out symbol, is it
        !          1031:                                * text, data, bss or common
        !          1032:                                */
        !          1033:                                if ((symbol.n_scnum > 0 &&      /* defined */
        !          1034:                                        symbol.n_sclass == C_EXT) ||
        !          1035:                                        (symbol.n_scnum == 0 && /* common */
        !          1036:                                        symbol.n_sclass == C_EXT &&
        !          1037:                                        symbol.n_value != 0))
        !          1038:                                {
        !          1039:                                        sym_ptr[nsyms] = mem_ptr;
        !          1040:                                        sym_name[nsyms] = getname(&symbol);
        !          1041:                                        if (++nsyms > TABSZ)    /* too many! */
        !          1042:                                        {
        !          1043:                                                fprintf(stderr, "ar: too many external symbols\n");
        !          1044:                                                done(1);
        !          1045:                                        }
        !          1046:                                }
        !          1047:                                /*
        !          1048:                                * skip over any auxilliary entries
        !          1049:                                */
        !          1050:                                j = symbol.n_numaux;
        !          1051:                                while (j)
        !          1052:                                {
        !          1053:                                        j--;
        !          1054:                                        i--;
        !          1055:                                        if (read(af, (char *)&symbol, SYMESZ)
        !          1056:                                                != SYMESZ)
        !          1057:                                        {
        !          1058:                                                fprintf(stderr, "ar: internal error, archive %s out of order!\n",
        !          1059:                                                        arnam);
        !          1060:                                                done(1);
        !          1061:                                        }
        !          1062:                                }
        !          1063:                        }
        !          1064:                /*
        !          1065:                * Be careful with odd length .o files (now possible)
        !          1066:                */
        !          1067:                mem_ptr += ((arbuf.ar_size + 1) & ~01) + sizeof(struct ar_hdr);
        !          1068:                /*
        !          1069:                * Skip string table (if any)
        !          1070:                */
        !          1071:                if (lseek(af, mem_ptr + mem_skip, 0) < 0)
        !          1072:                {
        !          1073:                        fprintf(stderr,
        !          1074:                                "ar: %s cannot skip string table for %s\n",
        !          1075:                                arnam, file);
        !          1076:                        done(1);
        !          1077:                }
        !          1078:                }
        !          1079:        }
        !          1080:        /*
        !          1081:        * rewrite the archive to include the symbol directory
        !          1082:        */
        !          1083:        close(af);
        !          1084:        /*
        !          1085:        * clean up the garbage that may have been left around
        !          1086:        */
        !          1087:        unlink(tfnam);
        !          1088:        tfnam = 0;
        !          1089:        unlink(tf1nam);
        !          1090:        tf1nam = 0;
        !          1091:        unlink(tf2nam);
        !          1092:        tf2nam = 0;
        !          1093:        init();         /* rewrite the archive header */
        !          1094:        /*
        !          1095:        * patch up archive pointers and write the symbol entries
        !          1096:        */
        !          1097:        if ((str_top - str_base) & 01)  /* round up string table */
        !          1098:                *++str_top = '\0';
        !          1099:        offset = (nsyms + 1) * sizeof(sym_offsets[0]) +
        !          1100:                sizeof(char) * (str_top - str_base) + sizeof(struct ar_hdr);
        !          1101:        for (i = 0; i < nsyms; i++)
        !          1102:        {
        !          1103:                sym_ptr[i] += offset;
        !          1104:                sputl(sym_ptr[i], sym_offsets[i]);
        !          1105:        }
        !          1106:        if (nsyms > 0)
        !          1107:        {
        !          1108:                sputl(nsyms, sym_nsyms);
        !          1109: #ifndef sun
        !          1110:                if (
        !          1111: #endif sun
        !          1112:                    sprintf(buf, "%-16s%-12ld%-6u%-6u%-8o%-10ld%-2s",
        !          1113:                        SYMDIRNAME, time(0), 0, 0, 0,
        !          1114:                        (long)(offset - sizeof(struct ar_hdr)), ARFMAG)
        !          1115: #if sun
        !          1116:                        ;
        !          1117: #else
        !          1118:                        != sizeof(ariobuf))
        !          1119:                {
        !          1120:                        fprintf(stderr,
        !          1121:                                "ar: %s internal header generation error\n",
        !          1122:                                arnam);
        !          1123:                        done(1);
        !          1124:                }
        !          1125: #endif sun
        !          1126:                if (write(tf, buf, sizeof(ariobuf)) != sizeof(ariobuf) ||
        !          1127:                        write(tf, sym_nsyms, sizeof(sym_nsyms))
        !          1128:                        != sizeof(sym_nsyms) || write(tf, (char *)sym_offsets,
        !          1129:                        nsyms * sizeof(sym_offsets[0]))
        !          1130:                        != nsyms * sizeof(sym_offsets[0]) ||
        !          1131:                        write(tf, str_base, sizeof(char) * (str_top - str_base))
        !          1132:                        != sizeof(char) * (str_top - str_base))
        !          1133:                {
        !          1134:                        wrerr();
        !          1135:                }
        !          1136:        }
        !          1137:        /*
        !          1138:        * copy the rest of the archive to finish up
        !          1139:        */
        !          1140:        getaf();                /* skip past the old header */
        !          1141:        while (!getdir())
        !          1142:                copyfil(af, tf, IODD + OODD + HEAD);
        !          1143:        install();
        !          1144: }
        !          1145: 
        !          1146: 
        !          1147: 
        !          1148: 
        !          1149: ml_file()
        !          1150: {
        !          1151:        long save_size;
        !          1152: 
        !          1153:        /*
        !          1154:        * is this a recognizable machine language file
        !          1155:        * if so, then skip down to the beginning of the symbol table
        !          1156:        * function returns the number of symbol table entries
        !          1157:        * if not, then skip to the next file
        !          1158:        */
        !          1159:        filenum++;
        !          1160:        if (arbuf.ar_size <= sizeof(ml_filhdr))         /* don't bother */
        !          1161:        {
        !          1162:                copyfil(af, -1, IODD + SKIP);
        !          1163:                return (0);
        !          1164:        }
        !          1165:        /*
        !          1166:        * check the "magic" number
        !          1167:        */
        !          1168:        if (read(af, (char *)&ml_filhdr, sizeof(ml_filhdr))
        !          1169:                != sizeof(ml_filhdr))
        !          1170:        {
        !          1171:                fprintf(stderr,
        !          1172:                        "ar: internal error, archive %s out of order!\n",arnam);
        !          1173:                done(1);
        !          1174:        }
        !          1175:        switch (ml_filhdr.f_magic)
        !          1176:        {
        !          1177:        default:        /* skip to the next archive file member */
        !          1178:                        /* beware of old format .o files (pre-5.0) */
        !          1179:                if (ml_filhdr.f_magic == 0407 || ml_filhdr.f_magic == 0410)
        !          1180:                {
        !          1181:                        fprintf(stderr, 
        !          1182:                                "ar: (warning) file %.16s in pre 5.0 format\n",
        !          1183:                                arbuf.ar_name);
        !          1184:                }
        !          1185:        skip_it:;
        !          1186:                save_size = arbuf.ar_size;
        !          1187:                arbuf.ar_size -= sizeof(ml_filhdr);
        !          1188:                copyfil(af, -1, IODD + SKIP);
        !          1189:                arbuf.ar_size = save_size;
        !          1190:                return (0);
        !          1191:        case B16MAGIC:
        !          1192:        case BTVMAGIC:
        !          1193:        case X86MAGIC:
        !          1194:        case XTVMAGIC:
        !          1195:        case N3BMAGIC:
        !          1196:        case NTVMAGIC:
        !          1197:        case FBOMAGIC:
        !          1198:        case RBOMAGIC:
        !          1199:        case MTVMAGIC:
        !          1200:        case VAXWRMAGIC:
        !          1201:        case VAXROMAGIC:
        !          1202:        case XLMAGIC:
        !          1203:        case MC68MAGIC:
        !          1204:        case MC68TVMAGIC:
        !          1205:        case M68MAGIC:
        !          1206:        case M68TVMAGIC:
        !          1207:        case U370WRMAGIC:
        !          1208:        case U370ROMAGIC:
        !          1209:                /*
        !          1210:                * skip to the beginning of the symbol table and return the
        !          1211:                * number of symbols in the table
        !          1212:                */
        !          1213:                save_size = arbuf.ar_size;
        !          1214:                if (ml_filhdr.f_symptr < 0 || ml_filhdr.f_symptr > save_size)
        !          1215:                {
        !          1216: #if unix && (u3b || u3b5)
        !          1217:                        /*
        !          1218:                        * Check for special case of sccs file.  This type
        !          1219:                        * of file looks like an object file on the 3b family.
        !          1220:                        * The special numbers are the strings '^As 0' through
        !          1221:                        * '^As 9' which are what can be found in an sccs file
        !          1222:                        * on these machines.  If the object file header is
        !          1223:                        * changed, or the structure of sccs files is modified,
        !          1224:                        * this code will no longer be valid.
        !          1225:                        */
        !          1226:                        if (ml_filhdr.f_symptr >= 0x01732030 && /* in ascii */
        !          1227:                                ml_filhdr.f_symptr <= 0x01732039)
        !          1228:                        {
        !          1229:                                goto skip_it;   /* don't bother with warning */
        !          1230:                        }
        !          1231: #endif
        !          1232:                        fprintf(stderr, "ar: (warning) file %.16s pretends to be an object file\n",
        !          1233:                                arbuf.ar_name);
        !          1234:                        goto skip_it;
        !          1235:                }
        !          1236:                arbuf.ar_size = ml_filhdr.f_symptr - sizeof(ml_filhdr);
        !          1237:                copyfil(af, -1, IODD + SKIP);
        !          1238:                arbuf.ar_size = save_size;
        !          1239:                return (ml_filhdr.f_nsyms);     /* return the nbr of entries */
        !          1240:        }
        !          1241: }
        !          1242: 
        !          1243: 
        !          1244: #define max(A,B) (((A) < (B)) ? (B) : (A))
        !          1245: 
        !          1246: extern char    *malloc(),      *realloc(),     *getenv(),      *mktemp();
        !          1247: extern void    free();
        !          1248: extern int     access();
        !          1249: static char    *pcopy(),       *seed="AAA";
        !          1250: 
        !          1251: 
        !          1252: 
        !          1253: char *
        !          1254: tempnam(dir, pfx)
        !          1255:        char *dir;              /* use this directory please (if non-NULL) */
        !          1256:        char *pfx;              /* use this (if non-NULL) as filename prefix */
        !          1257: {
        !          1258:        register char *p, *q, *tdir;
        !          1259:        int x = 0, y = 0, z;
        !          1260: 
        !          1261:        z = strlen(P_tmpdir);
        !          1262:        if ((tdir = getenv("TMPDIR")) != NULL)
        !          1263:                x = strlen(tdir);
        !          1264:        if (dir != NULL)
        !          1265:                y = strlen(dir);
        !          1266:        if ((p = malloc((unsigned)(max(max(x, y), z) + 16))) == NULL)
        !          1267:                return (NULL);
        !          1268:        if (x > 0 && access(pcopy(p, tdir), 3) == 0)
        !          1269:                goto OK;
        !          1270:        if (y > 0 && access(pcopy(p, dir), 3) == 0)
        !          1271:                goto OK;
        !          1272:        if (access(pcopy(p, P_tmpdir), 3) == 0)
        !          1273:                goto OK;
        !          1274:        if (access(pcopy(p, "/tmp"), 3) != 0)
        !          1275:                return (NULL);
        !          1276: OK:
        !          1277:        (void)strcat(p, "/");
        !          1278:        if (pfx)
        !          1279:        {
        !          1280:                *(p + strlen(p) + 5) = '\0';
        !          1281:                (void)strncat(p, pfx, 5);
        !          1282:        }
        !          1283:        (void)strcat(p, seed);
        !          1284:        (void)strcat(p, "XXXXXX");
        !          1285:        q = seed;
        !          1286:        while (*q == 'Z')
        !          1287:                *q++ = 'A';
        !          1288:        ++*q;
        !          1289:        if (*mktemp(p) == '\0')
        !          1290:                return (NULL);
        !          1291:        return (p);
        !          1292: }
        !          1293: 
        !          1294: 
        !          1295: 
        !          1296: static char *
        !          1297: pcopy(space, arg)
        !          1298:        char *space, *arg;
        !          1299: {
        !          1300:        char *p;
        !          1301: 
        !          1302:        if (arg)
        !          1303:        {
        !          1304:                (void)strcpy(space, arg);
        !          1305:                p = space - 1 + strlen(space);
        !          1306:                if (*p == '/')
        !          1307:                        *p = '\0';
        !          1308:        }
        !          1309:        return (space);
        !          1310: }
        !          1311: 
        !          1312: 
        !          1313: 
        !          1314: char *
        !          1315: getname(symbol)
        !          1316:        struct syment *symbol;
        !          1317: {
        !          1318:        static int str_length = BUFSIZ * 5;
        !          1319: #ifdef FLEXNAMES
        !          1320:        static int lastfilenum = 0;
        !          1321:        static char *strtab = NULL;
        !          1322:        static long strtablen = 0;
        !          1323: #endif
        !          1324: 
        !          1325:        if (str_base == (char *)0)      /* no space allocated yet */
        !          1326:        {
        !          1327:                if ((str_base = malloc((unsigned)str_length)) == NULL)
        !          1328:                {
        !          1329:                        fprintf(stderr,
        !          1330:                                "ar: %s cannot get string table space\n",
        !          1331:                                arnam);
        !          1332:                        done(1);
        !          1333:                }
        !          1334:                str_top = str_base;
        !          1335:        }
        !          1336: #ifdef FLEXNAMES
        !          1337:        if (symbol->n_zeroes == 0)      /* symbol is in string table */
        !          1338:        {
        !          1339:                char *p;
        !          1340:                register int i;
        !          1341: 
        !          1342:                if (lastfilenum != filenum || strtab == NULL)   /* read it in */
        !          1343:                {
        !          1344:                        union
        !          1345:                        {
        !          1346:                                long l;
        !          1347:                                char c[sizeof(long) / sizeof(char)];
        !          1348:                        } u;
        !          1349:                        long home = lseek(af, 0L, 1);
        !          1350:                        long len, len1;
        !          1351: 
        !          1352:                        if (strtab != NULL)
        !          1353:                                free(strtab);
        !          1354:                        len = ml_filhdr.f_symptr + ml_filhdr.f_nsyms * SYMESZ;
        !          1355:                        len1 = arbuf.ar_size - len;
        !          1356:                        if (len1 < 4L)  /* room for string table */
        !          1357:                        {
        !          1358:                                fprintf(stderr,
        !          1359:                                        "ar: %s missing string table for %s\n",
        !          1360:                                        arnam, file);
        !          1361:                                done(1);
        !          1362:                        }
        !          1363:                        len += sizeof(struct ar_hdr) + mem_ptr + mem_skip;
        !          1364:                        if ((strtab = malloc((unsigned)len1)) == NULL ||
        !          1365:                                lseek(af, len, 0) < 0 ||
        !          1366:                                read(af, strtab, len1) != len1 ||
        !          1367:                                lseek(af, home, 0) < 0 ||
        !          1368:                                strtab[len1 - 1] != '\0')
        !          1369:                        {
        !          1370:                                fprintf(stderr,
        !          1371:                                        "ar: %s bad strings table for %s\n",
        !          1372:                                        arnam, file);
        !          1373:                                done(1);
        !          1374:                        }
        !          1375:                        lastfilenum = filenum;
        !          1376:                        for (i = 0; i < sizeof(u.c); i++)
        !          1377:                                u.c[i] = strtab[i];
        !          1378:                        strtablen = u.l;
        !          1379:                }
        !          1380:                if (symbol->n_offset < 4 || symbol->n_offset >= strtablen)
        !          1381:                {
        !          1382:                        fprintf(stderr,
        !          1383:                                "ar: %s bad string table offset for %s\n",
        !          1384:                                arnam, file);
        !          1385:                        done(1);
        !          1386:                }
        !          1387:                p = str_top;
        !          1388:                str_top += strlen(strtab + symbol->n_offset) + 1;
        !          1389:                if (str_top > str_base + str_length)
        !          1390:                {
        !          1391:                        char *old_base = str_base;
        !          1392:                        int diff;
        !          1393: 
        !          1394:                        str_length += BUFSIZ * 2;
        !          1395:                        if ((str_base = realloc(str_base, str_length)) == NULL)
        !          1396:                        {
        !          1397:                                fprintf(stderr,
        !          1398:                                        "ar: %s cannot grow string table\n",
        !          1399:                                        arnam);
        !          1400:                                done(1);
        !          1401:                        }
        !          1402:                        /*
        !          1403:                        * Re-adjust other pointers
        !          1404:                        */
        !          1405:                        diff = str_base - old_base;
        !          1406:                        p += diff;
        !          1407:                        str_top += diff;
        !          1408:                }
        !          1409:                (void)strcpy(p, strtab + symbol->n_offset);
        !          1410:                return (p);
        !          1411:        }
        !          1412:        else    /* old COFF version - copy into string table */
        !          1413: #endif
        !          1414:        {
        !          1415:                register char *p, *s;
        !          1416:                register int i;
        !          1417: 
        !          1418:                if (str_top + SYMNMLEN >= str_base + str_length)
        !          1419:                {
        !          1420:                        char *old_base = str_base;
        !          1421:                        int diff;
        !          1422: 
        !          1423:                        str_length += BUFSIZ * 2;
        !          1424:                        if ((str_base = realloc(str_base, str_length)) == NULL)
        !          1425:                        {
        !          1426:                                fprintf(stderr,
        !          1427:                                        "ar: %s cannot grow string table\n",
        !          1428:                                        arnam);
        !          1429:                                done(1);
        !          1430:                        }
        !          1431:                        /*
        !          1432:                        * Re-adjust other pointers
        !          1433:                        */
        !          1434:                        diff = str_base - old_base;
        !          1435:                        p += diff;
        !          1436:                        str_top += diff;
        !          1437:                }
        !          1438:                for (i = 0, p = str_top, s = symbol->n_name;
        !          1439:                        i < SYMNMLEN && *s != '\0'; i++)
        !          1440:                {
        !          1441:                        *p++ = *s++;
        !          1442:                }
        !          1443:                *p++ = '\0';
        !          1444:                s = str_top;
        !          1445:                str_top = p;
        !          1446:                return (s);
        !          1447:        }
        !          1448: }

unix.superglobalmegacorp.com

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