Annotation of 43BSDTahoe/usr.bin/ranlib.c, revision 1.1.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.4 (Berkeley) 4/6/87";
                     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[] = RANLIBMAG;
                     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.