1*22410Sdist /* 2*22410Sdist * Copyright (c) 1980 Regents of the University of California. 3*22410Sdist * All rights reserved. The Berkeley software License Agreement 4*22410Sdist * specifies the terms and conditions for redistribution. 5*22410Sdist */ 6*22410Sdist 712673Ssam #ifndef lint 8*22410Sdist char copyright[] = 9*22410Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10*22410Sdist All rights reserved.\n"; 11*22410Sdist #endif not lint 12*22410Sdist 13*22410Sdist #ifndef lint 14*22410Sdist static char sccsid[] = "@(#)ranlib.c 5.1 (Berkeley) 06/06/85"; 15*22410Sdist #endif not lint 16*22410Sdist 17625Sbill /* 18625Sbill * ranlib - create table of contents for archive; string table version 19625Sbill */ 20625Sbill #include <sys/types.h> 21899Sbill #include <ar.h> 22625Sbill #include <ranlib.h> 23899Sbill #include <a.out.h> 24625Sbill #include <stdio.h> 25625Sbill 26625Sbill struct ar_hdr archdr; 27625Sbill #define OARMAG 0177545 28625Sbill long arsize; 29625Sbill struct exec exp; 30625Sbill FILE *fi, *fo; 31625Sbill long off, oldoff; 32625Sbill long atol(), ftell(); 3311152Sshantz #define TABSZ 6000 34625Sbill struct ranlib tab[TABSZ]; 35625Sbill int tnum; 361753Sbill #define STRTABSZ 75000 37625Sbill char tstrtab[STRTABSZ]; 38625Sbill int tssiz; 39625Sbill char *strtab; 40625Sbill int ssiz; 41625Sbill int new; 42625Sbill char tempnm[] = "__.SYMDEF"; 43625Sbill char firstname[17]; 44625Sbill 45625Sbill main(argc, argv) 46625Sbill char **argv; 47625Sbill { 48625Sbill char cmdbuf[BUFSIZ]; 499343Srt /* magbuf must be an int array so it is aligned on an int-ish 509343Srt boundary, so that we may access its first word as an int! */ 519343Srt int magbuf[(SARMAG+sizeof(int))/sizeof(int)]; 5219932Smckusick register int just_touch = 0; 53625Sbill 5419932Smckusick /* check for the "-t" flag" */ 5519932Smckusick if (argc > 1 && strcmp(argv[1], "-t") == 0) { 5619932Smckusick just_touch++; 5719932Smckusick argc--; 5819932Smckusick argv++; 5919932Smckusick } 6019932Smckusick 61625Sbill --argc; 62625Sbill while(argc--) { 63625Sbill fi = fopen(*++argv,"r"); 64625Sbill if (fi == NULL) { 65625Sbill fprintf(stderr, "ranlib: cannot open %s\n", *argv); 66625Sbill continue; 67625Sbill } 68625Sbill off = SARMAG; 699343Srt fread((char *)magbuf, 1, SARMAG, fi); 709343Srt if (strncmp((char *)magbuf, ARMAG, SARMAG)) { 719343Srt if (magbuf[0] == OARMAG) 72625Sbill fprintf(stderr, "old format "); 73625Sbill else 74625Sbill fprintf(stderr, "not an "); 75625Sbill fprintf(stderr, "archive: %s\n", *argv); 76625Sbill continue; 77625Sbill } 7819963Smckusick if (just_touch) { 7919963Smckusick register int len; 8019963Smckusick 8119963Smckusick fseek(fi, (long) SARMAG, 0); 8219963Smckusick if (fread(cmdbuf, sizeof archdr.ar_name, 1, fi) != 1) { 8319963Smckusick fprintf(stderr, "malformed archive: %s\n", 8419963Smckusick *argv); 8519963Smckusick continue; 8619963Smckusick } 8719963Smckusick len = strlen(tempnm); 8819963Smckusick if (bcmp(cmdbuf, tempnm, len) != 0 || 8919963Smckusick cmdbuf[len] != ' ') { 9019963Smckusick fprintf(stderr, "no symbol table: %s\n", *argv); 9119963Smckusick continue; 9219963Smckusick } 9319963Smckusick fclose(fi); 9419963Smckusick fixdate(*++argv); 9519963Smckusick continue; 9619963Smckusick } 97625Sbill fseek(fi, 0L, 0); 98625Sbill new = tnum = 0; 99625Sbill if (nextel(fi) == 0) { 100625Sbill fclose(fi); 101625Sbill continue; 102625Sbill } 103625Sbill do { 104625Sbill long o; 105625Sbill register n; 106625Sbill struct nlist sym; 107625Sbill 108625Sbill fread((char *)&exp, 1, sizeof(struct exec), fi); 109625Sbill if (N_BADMAG(exp)) 110625Sbill continue; 11117423Sralph if (!strncmp(tempnm, archdr.ar_name, sizeof(archdr.ar_name))) 11217423Sralph continue; 113625Sbill if (exp.a_syms == 0) { 114625Sbill fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name); 1153607Ssklower continue; 116625Sbill } 117625Sbill o = N_STROFF(exp) - sizeof (struct exec); 118625Sbill if (ftell(fi)+o+sizeof(ssiz) >= off) { 11917423Sralph fprintf(stderr, "ranlib: warning: %s(%s): old format .o file\n", *argv, archdr.ar_name); 12017423Sralph continue; 121625Sbill } 122625Sbill fseek(fi, o, 1); 123625Sbill fread((char *)&ssiz, 1, sizeof (ssiz), fi); 1249343Srt if (ssiz < sizeof ssiz){ 1259343Srt /* sanity check */ 12617423Sralph fprintf(stderr, "ranlib: warning: %s(%s): mangled string table\n", *argv, archdr.ar_name); 12717423Sralph continue; 1289343Srt } 129625Sbill strtab = (char *)calloc(1, ssiz); 130625Sbill if (strtab == 0) { 131625Sbill fprintf(stderr, "ranlib: ran out of memory\n"); 132625Sbill exit(1); 133625Sbill } 134625Sbill fread(strtab+sizeof(ssiz), ssiz - sizeof(ssiz), 1, fi); 135625Sbill fseek(fi, -(exp.a_syms+ssiz), 1); 136625Sbill n = exp.a_syms / sizeof(struct nlist); 137625Sbill while (--n >= 0) { 138625Sbill fread((char *)&sym, 1, sizeof(sym), fi); 139625Sbill if (sym.n_un.n_strx == 0) 140625Sbill continue; 141625Sbill sym.n_un.n_name = strtab + sym.n_un.n_strx; 142625Sbill if ((sym.n_type&N_EXT)==0) 143625Sbill continue; 144625Sbill switch (sym.n_type&N_TYPE) { 145625Sbill 146625Sbill case N_UNDF: 147625Sbill if (sym.n_value!=0) 148625Sbill stash(&sym); 149625Sbill continue; 150625Sbill 151625Sbill default: 152625Sbill stash(&sym); 153625Sbill continue; 154625Sbill } 155625Sbill } 156625Sbill } while(nextel(fi)); 157625Sbill new = fixsize(); 158625Sbill fclose(fi); 159625Sbill fo = fopen(tempnm, "w"); 160625Sbill if(fo == NULL) { 161625Sbill fprintf(stderr, "can't create temporary\n"); 162625Sbill exit(1); 163625Sbill } 164625Sbill tnum *= sizeof (struct ranlib); 165625Sbill fwrite(&tnum, 1, sizeof (tnum), fo); 166625Sbill tnum /= sizeof (struct ranlib); 167625Sbill fwrite((char *)tab, tnum, sizeof(struct ranlib), fo); 168625Sbill fwrite(&tssiz, 1, sizeof (tssiz), fo); 169625Sbill fwrite(tstrtab, tssiz, 1, fo); 170625Sbill fclose(fo); 171625Sbill if(new) 172899Sbill sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm); 173625Sbill else 174899Sbill sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm); 175625Sbill if(system(cmdbuf)) 176625Sbill fprintf(stderr, "ranlib: ``%s'' failed\n", cmdbuf); 177625Sbill else 178625Sbill fixdate(*argv); 179625Sbill unlink(tempnm); 180625Sbill } 181625Sbill exit(0); 182625Sbill } 183625Sbill 184625Sbill nextel(af) 185625Sbill FILE *af; 186625Sbill { 187625Sbill register r; 188625Sbill register char *cp; 189625Sbill 190625Sbill oldoff = off; 191625Sbill fseek(af, off, 0); 192625Sbill r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); 193625Sbill if (r != sizeof(struct ar_hdr)) 194625Sbill return(0); 195625Sbill for (cp=archdr.ar_name; cp < & archdr.ar_name[sizeof(archdr.ar_name)]; cp++) 196625Sbill if (*cp == ' ') 197625Sbill *cp = '\0'; 198625Sbill arsize = atol(archdr.ar_size); 199625Sbill if (arsize & 1) 200625Sbill arsize++; 201625Sbill off = ftell(af) + arsize; 202625Sbill return(1); 203625Sbill } 204625Sbill 205625Sbill stash(s) 206625Sbill struct nlist *s; 207625Sbill { 208625Sbill int i; 209625Sbill register char *cp; 210625Sbill 211625Sbill if(tnum >= TABSZ) { 212625Sbill fprintf(stderr, "ranlib: symbol table overflow\n"); 213625Sbill exit(1); 214625Sbill } 215625Sbill tab[tnum].ran_un.ran_strx = tssiz; 216625Sbill tab[tnum].ran_off = oldoff; 217625Sbill for (cp = s->n_un.n_name; tstrtab[tssiz++] = *cp++;) 218625Sbill if (tssiz > STRTABSZ) { 219625Sbill fprintf(stderr, "ranlib: string table overflow\n"); 220625Sbill exit(1); 221625Sbill } 222625Sbill tnum++; 223625Sbill } 224625Sbill 225625Sbill fixsize() 226625Sbill { 227625Sbill int i; 228625Sbill off_t offdelta; 229625Sbill 230625Sbill if (tssiz&1) 231625Sbill tssiz++; 232625Sbill offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) + 233625Sbill sizeof (tssiz) + tssiz; 234625Sbill off = SARMAG; 235625Sbill nextel(fi); 236625Sbill if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) { 237625Sbill new = 0; 238625Sbill offdelta -= sizeof(archdr) + arsize; 239625Sbill } else { 240625Sbill new = 1; 241625Sbill strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name)); 242625Sbill } 243625Sbill for(i=0; i<tnum; i++) 244625Sbill tab[i].ran_off += offdelta; 245625Sbill return(new); 246625Sbill } 247625Sbill 248625Sbill /* patch time */ 249625Sbill fixdate(s) 250625Sbill char *s; 251625Sbill { 252625Sbill long time(); 253625Sbill char buf[24]; 254625Sbill int fd; 255625Sbill 256625Sbill fd = open(s, 1); 257625Sbill if(fd < 0) { 258625Sbill fprintf(stderr, "ranlib: can't reopen %s\n", s); 259625Sbill return; 260625Sbill } 261625Sbill sprintf(buf, "%-*ld", sizeof(archdr.ar_date), time((long *)NULL)+5); 262625Sbill lseek(fd, (long)SARMAG + ((char *)archdr.ar_date-(char *)&archdr), 0); 263625Sbill write(fd, buf, sizeof(archdr.ar_date)); 264625Sbill close(fd); 265625Sbill } 266