Annotation of 43BSD/usr.bin/ranlib.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif not lint
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)ranlib.c   5.3 (Berkeley) 1/22/86";
        !            15: #endif not lint
        !            16: 
        !            17: /*
        !            18:  * ranlib - create table of contents for archive; string table version
        !            19:  */
        !            20: #include <sys/types.h>
        !            21: #include <ar.h>
        !            22: #include <ranlib.h>
        !            23: #include <a.out.h>
        !            24: #include <stdio.h>
        !            25: 
        !            26: struct ar_hdr  archdr;
        !            27: #define        OARMAG 0177545
        !            28: long   arsize;
        !            29: struct exec    exp;
        !            30: FILE   *fi, *fo;
        !            31: long   off, oldoff;
        !            32: long   atol(), ftell();
        !            33: #define TABSZ  3000
        !            34: int    tnum;
        !            35: #define        STRTABSZ        30000
        !            36: int    tssiz;
        !            37: char   *strtab;
        !            38: int    ssiz;
        !            39: int    new;
        !            40: char   tempnm[] = "__.SYMDEF";
        !            41: char   firstname[17];
        !            42: void   stash();
        !            43: char *malloc(), *calloc();
        !            44: 
        !            45: /*
        !            46:  * table segment definitions
        !            47:  */
        !            48: char   *segalloc();
        !            49: void   segclean();
        !            50: struct tabsegment {
        !            51:        struct tabsegment       *pnext;
        !            52:        unsigned                nelem;
        !            53:        struct ranlib           tab[TABSZ];
        !            54: } tabbase, *ptabseg;
        !            55: struct strsegment {
        !            56:        struct strsegment       *pnext;
        !            57:        unsigned                nelem;
        !            58:        char                    stab[STRTABSZ];
        !            59: } strbase, *pstrseg;
        !            60: 
        !            61: main(argc, argv)
        !            62: char **argv;
        !            63: {
        !            64:        char cmdbuf[BUFSIZ];
        !            65:        /* magbuf must be an int array so it is aligned on an int-ish
        !            66:           boundary, so that we may access its first word as an int! */
        !            67:        int magbuf[(SARMAG+sizeof(int))/sizeof(int)];
        !            68:        register int just_touch = 0;
        !            69:        register struct tabsegment *ptab;
        !            70:        register struct strsegment *pstr;
        !            71: 
        !            72:        /* check for the "-t" flag" */
        !            73:        if (argc > 1 && strcmp(argv[1], "-t") == 0) {
        !            74:                just_touch++;
        !            75:                argc--;
        !            76:                argv++;
        !            77:        }
        !            78: 
        !            79:        --argc;
        !            80:        while(argc--) {
        !            81:                fi = fopen(*++argv,"r");
        !            82:                if (fi == NULL) {
        !            83:                        fprintf(stderr, "ranlib: cannot open %s\n", *argv);
        !            84:                        continue;
        !            85:                }
        !            86:                off = SARMAG;
        !            87:                fread((char *)magbuf, 1, SARMAG, fi);
        !            88:                if (strncmp((char *)magbuf, ARMAG, SARMAG)) {
        !            89:                        if (magbuf[0] == OARMAG)
        !            90:                                fprintf(stderr, "old format ");
        !            91:                        else
        !            92:                                fprintf(stderr, "not an ");
        !            93:                        fprintf(stderr, "archive: %s\n", *argv);
        !            94:                        continue;
        !            95:                }
        !            96:                if (just_touch) {
        !            97:                        register int    len;
        !            98: 
        !            99:                        fseek(fi, (long) SARMAG, 0);
        !           100:                        if (fread(cmdbuf, sizeof archdr.ar_name, 1, fi) != 1) {
        !           101:                                fprintf(stderr, "malformed archive: %s\n",
        !           102:                                        *argv);
        !           103:                                continue;
        !           104:                        }
        !           105:                        len = strlen(tempnm);
        !           106:                        if (bcmp(cmdbuf, tempnm, len) != 0 ||
        !           107:                            cmdbuf[len] != ' ') {
        !           108:                                fprintf(stderr, "no symbol table: %s\n", *argv);
        !           109:                                continue;
        !           110:                        }
        !           111:                        fclose(fi);
        !           112:                        fixdate(*argv);
        !           113:                        continue;
        !           114:                }
        !           115:                fseek(fi, 0L, 0);
        !           116:                new = tssiz = tnum = 0;
        !           117:                segclean();
        !           118:                if (nextel(fi) == 0) {
        !           119:                        fclose(fi);
        !           120:                        continue;
        !           121:                }
        !           122:                do {
        !           123:                        long o;
        !           124:                        register n;
        !           125:                        struct nlist sym;
        !           126: 
        !           127:                        fread((char *)&exp, 1, sizeof(struct exec), fi);
        !           128:                        if (N_BADMAG(exp))
        !           129:                                continue;
        !           130:                        if (!strncmp(tempnm, archdr.ar_name, sizeof(archdr.ar_name)))
        !           131:                                continue;
        !           132:                        if (exp.a_syms == 0) {
        !           133:                                fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name);
        !           134:                                continue;
        !           135:                        }
        !           136:                        o = N_STROFF(exp) - sizeof (struct exec);
        !           137:                        if (ftell(fi)+o+sizeof(ssiz) >= off) {
        !           138:                                fprintf(stderr, "ranlib: warning: %s(%s): old format .o file\n", *argv, archdr.ar_name);
        !           139:                                continue;
        !           140:                        }
        !           141:                        fseek(fi, o, 1);
        !           142:                        fread((char *)&ssiz, 1, sizeof (ssiz), fi);
        !           143:                        if (ssiz < sizeof ssiz){
        !           144:                                /* sanity check */
        !           145:                                fprintf(stderr, "ranlib: warning: %s(%s): mangled string table\n", *argv, archdr.ar_name);
        !           146:                                continue;
        !           147:                        }
        !           148:                        strtab = (char *)calloc(1, ssiz);
        !           149:                        if (strtab == 0) {
        !           150:                                fprintf(stderr, "ranlib: ran out of memory\n");
        !           151:                                exit(1);
        !           152:                        }
        !           153:                        fread(strtab+sizeof(ssiz), ssiz - sizeof(ssiz), 1, fi);
        !           154:                        fseek(fi, -(exp.a_syms+ssiz), 1);
        !           155:                        n = exp.a_syms / sizeof(struct nlist);
        !           156:                        while (--n >= 0) {
        !           157:                                fread((char *)&sym, 1, sizeof(sym), fi);
        !           158:                                if (sym.n_un.n_strx == 0)
        !           159:                                        continue;
        !           160:                                sym.n_un.n_name = strtab + sym.n_un.n_strx;
        !           161:                                if ((sym.n_type&N_EXT)==0)
        !           162:                                        continue;
        !           163:                                switch (sym.n_type&N_TYPE) {
        !           164: 
        !           165:                                case N_UNDF:
        !           166:                                        if (sym.n_value!=0)
        !           167:                                                stash(&sym);
        !           168:                                        continue;
        !           169: 
        !           170:                                default:
        !           171:                                        stash(&sym);
        !           172:                                        continue;
        !           173:                                }
        !           174:                        }
        !           175:                        free(strtab);
        !           176:                } while(nextel(fi));
        !           177:                new = fixsize();
        !           178:                fclose(fi);
        !           179:                fo = fopen(tempnm, "w");
        !           180:                if(fo == NULL) {
        !           181:                        fprintf(stderr, "can't create temporary\n");
        !           182:                        exit(1);
        !           183:                }
        !           184:                tnum *= sizeof (struct ranlib);
        !           185:                fwrite(&tnum, 1, sizeof (tnum), fo);
        !           186:                tnum /= sizeof (struct ranlib);
        !           187:                ptab = &tabbase;
        !           188:                do {
        !           189:                        fwrite((char *)ptab->tab, ptab->nelem,
        !           190:                            sizeof(struct ranlib), fo);
        !           191:                } while (ptab = ptab->pnext);
        !           192:                fwrite(&tssiz, 1, sizeof (tssiz), fo);
        !           193:                pstr = &strbase;
        !           194:                do {
        !           195:                        fwrite(pstr->stab, pstr->nelem, 1, fo);
        !           196:                        tssiz -= pstr->nelem;
        !           197:                } while (pstr = pstr->pnext);
        !           198:                /* pad with nulls */
        !           199:                while (tssiz--) putc('\0', fo);
        !           200:                fclose(fo);
        !           201:                if(new)
        !           202:                        sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm);
        !           203:                else
        !           204:                        sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm);
        !           205:                if(system(cmdbuf))
        !           206:                        fprintf(stderr, "ranlib: ``%s'' failed\n", cmdbuf);
        !           207:                else
        !           208:                        fixdate(*argv);
        !           209:                unlink(tempnm);
        !           210:        }
        !           211:        exit(0);
        !           212: }
        !           213: 
        !           214: nextel(af)
        !           215: FILE *af;
        !           216: {
        !           217:        register r;
        !           218:        register char *cp;
        !           219: 
        !           220:        oldoff = off;
        !           221:        fseek(af, off, 0);
        !           222:        r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af);
        !           223:        if (r != sizeof(struct ar_hdr))
        !           224:                return(0);
        !           225:        for (cp=archdr.ar_name; cp < & archdr.ar_name[sizeof(archdr.ar_name)]; cp++)
        !           226:                if (*cp == ' ')
        !           227:                        *cp = '\0';
        !           228:        arsize = atol(archdr.ar_size);
        !           229:        if (arsize & 1)
        !           230:                arsize++;
        !           231:        off = ftell(af) + arsize;
        !           232:        return(1);
        !           233: }
        !           234: 
        !           235: void
        !           236: stash(s)
        !           237:        struct nlist *s;
        !           238: {
        !           239:        register char *cp;
        !           240:        register char *strtab;
        !           241:        register strsiz;
        !           242:        register struct ranlib *tab;
        !           243:        register tabsiz;
        !           244: 
        !           245:        if (ptabseg->nelem >= TABSZ) {
        !           246:                /* allocate a new symbol table segment */
        !           247:                ptabseg = ptabseg->pnext =
        !           248:                    (struct tabsegment *) segalloc(sizeof(struct tabsegment));
        !           249:                ptabseg->pnext = NULL;
        !           250:                ptabseg->nelem = 0;
        !           251:        }
        !           252:        tabsiz = ptabseg->nelem;
        !           253:        tab = ptabseg->tab;
        !           254: 
        !           255:        if (pstrseg->nelem >= STRTABSZ) {
        !           256:                /* allocate a new string table segment */
        !           257:                pstrseg = pstrseg->pnext =
        !           258:                    (struct strsegment *) segalloc(sizeof(struct strsegment));
        !           259:                pstrseg->pnext = NULL;
        !           260:                pstrseg->nelem = 0;
        !           261:        }
        !           262:        strsiz = pstrseg->nelem;
        !           263:        strtab = pstrseg->stab;
        !           264: 
        !           265:        tab[tabsiz].ran_un.ran_strx = tssiz;
        !           266:        tab[tabsiz].ran_off = oldoff;
        !           267: redo:
        !           268:        for (cp = s->n_un.n_name; strtab[strsiz++] = *cp++;)
        !           269:                if (strsiz >= STRTABSZ) {
        !           270:                        /* allocate a new string table segment */
        !           271:                        pstrseg = pstrseg->pnext =
        !           272:                            (struct strsegment *) segalloc(sizeof(struct strsegment));
        !           273:                        pstrseg->pnext = NULL;
        !           274:                        strsiz = pstrseg->nelem = 0;
        !           275:                        strtab = pstrseg->stab;
        !           276:                        goto redo;
        !           277:                }
        !           278: 
        !           279:        tssiz += strsiz - pstrseg->nelem; /* length of the string */
        !           280:        pstrseg->nelem = strsiz;
        !           281:        tnum++;
        !           282:        ptabseg->nelem++;
        !           283: }
        !           284: 
        !           285: /* allocate a zero filled segment of size bytes */
        !           286: char *
        !           287: segalloc(size)
        !           288: unsigned size;
        !           289: {
        !           290:        char *pseg = NULL;
        !           291: 
        !           292:        pseg = malloc(size);
        !           293:        if (pseg == NULL) {
        !           294:                fprintf(stderr, "ranlib: ran out of memeory\n");
        !           295:                exit(1);
        !           296:        }
        !           297:        return(pseg);
        !           298: }
        !           299: 
        !           300: /* free segments */
        !           301: void
        !           302: segclean()
        !           303: {
        !           304:        register struct tabsegment *ptab;
        !           305:        register struct strsegment *pstr;
        !           306: 
        !           307:        /*
        !           308:         * symbol table
        !           309:         *
        !           310:         * The first entry is static.
        !           311:         */
        !           312:        ptabseg = &tabbase;
        !           313:        ptab = ptabseg->pnext;
        !           314:        while (ptabseg = ptab) {
        !           315:                ptab = ptabseg->pnext;
        !           316:                free((char *)ptabseg);
        !           317:        }
        !           318:        ptabseg = &tabbase;
        !           319:        ptabseg->pnext = NULL;
        !           320:        ptabseg->nelem = 0;
        !           321: 
        !           322:        /*
        !           323:         * string table
        !           324:         *
        !           325:         * The first entry is static.
        !           326:         */
        !           327:        pstrseg = &strbase;
        !           328:        pstr = pstrseg->pnext;
        !           329:        while (pstrseg = pstr) {
        !           330:                pstr = pstrseg->pnext;
        !           331:                free((char *)pstrseg);
        !           332:        }
        !           333:        pstrseg = &strbase;
        !           334:        pstrseg->pnext = NULL;
        !           335:        pstrseg->nelem = 0;
        !           336: }
        !           337: 
        !           338: fixsize()
        !           339: {
        !           340:        int i;
        !           341:        off_t offdelta;
        !           342:        register struct tabsegment *ptab;
        !           343: 
        !           344:        if (tssiz&1)
        !           345:                tssiz++;
        !           346:        offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) +
        !           347:            sizeof (tssiz) + tssiz;
        !           348:        off = SARMAG;
        !           349:        nextel(fi);
        !           350:        if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) {
        !           351:                new = 0;
        !           352:                offdelta -= sizeof(archdr) + arsize;
        !           353:        } else {
        !           354:                new = 1;
        !           355:                strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name));
        !           356:        }
        !           357:        ptab = &tabbase;
        !           358:        do {
        !           359:                for (i = 0; i < ptab->nelem; i++)
        !           360:                        ptab->tab[i].ran_off += offdelta;
        !           361:        } while (ptab = ptab->pnext);
        !           362:        return(new);
        !           363: }
        !           364: 
        !           365: /* patch time */
        !           366: fixdate(s)
        !           367:        char *s;
        !           368: {
        !           369:        long time();
        !           370:        char buf[24];
        !           371:        int fd;
        !           372: 
        !           373:        fd = open(s, 1);
        !           374:        if(fd < 0) {
        !           375:                fprintf(stderr, "ranlib: can't reopen %s\n", s);
        !           376:                return;
        !           377:        }
        !           378:        sprintf(buf, "%-*ld", sizeof(archdr.ar_date), time((long *)NULL)+5);
        !           379:        lseek(fd, (long)SARMAG + ((char *)archdr.ar_date-(char *)&archdr), 0);
        !           380:        write(fd, buf, sizeof(archdr.ar_date));
        !           381:        close(fd);
        !           382: }

unix.superglobalmegacorp.com

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