112673Ssam #ifndef lint 2*17423Sralph static char sccsid[] = "@(#)ranlib.c 4.7 11/26/84"; 312673Ssam #endif 4625Sbill /* 5625Sbill * ranlib - create table of contents for archive; string table version 6625Sbill */ 7625Sbill #include <sys/types.h> 8899Sbill #include <ar.h> 9625Sbill #include <ranlib.h> 10899Sbill #include <a.out.h> 11625Sbill #include <stdio.h> 12625Sbill 13625Sbill struct ar_hdr archdr; 14625Sbill #define OARMAG 0177545 15625Sbill long arsize; 16625Sbill struct exec exp; 17625Sbill FILE *fi, *fo; 18625Sbill long off, oldoff; 19625Sbill long atol(), ftell(); 2011152Sshantz #define TABSZ 6000 21625Sbill struct ranlib tab[TABSZ]; 22625Sbill int tnum; 231753Sbill #define STRTABSZ 75000 24625Sbill char tstrtab[STRTABSZ]; 25625Sbill int tssiz; 26625Sbill char *strtab; 27625Sbill int ssiz; 28625Sbill int new; 29625Sbill char tempnm[] = "__.SYMDEF"; 30625Sbill char firstname[17]; 31625Sbill 32625Sbill main(argc, argv) 33625Sbill char **argv; 34625Sbill { 35625Sbill char cmdbuf[BUFSIZ]; 369343Srt /* magbuf must be an int array so it is aligned on an int-ish 379343Srt boundary, so that we may access its first word as an int! */ 389343Srt int magbuf[(SARMAG+sizeof(int))/sizeof(int)]; 39625Sbill 40625Sbill --argc; 41625Sbill while(argc--) { 42625Sbill fi = fopen(*++argv,"r"); 43625Sbill if (fi == NULL) { 44625Sbill fprintf(stderr, "ranlib: cannot open %s\n", *argv); 45625Sbill continue; 46625Sbill } 47625Sbill off = SARMAG; 489343Srt fread((char *)magbuf, 1, SARMAG, fi); 499343Srt if (strncmp((char *)magbuf, ARMAG, SARMAG)) { 509343Srt if (magbuf[0] == OARMAG) 51625Sbill fprintf(stderr, "old format "); 52625Sbill else 53625Sbill fprintf(stderr, "not an "); 54625Sbill fprintf(stderr, "archive: %s\n", *argv); 55625Sbill continue; 56625Sbill } 57625Sbill fseek(fi, 0L, 0); 58625Sbill new = tnum = 0; 59625Sbill if (nextel(fi) == 0) { 60625Sbill fclose(fi); 61625Sbill continue; 62625Sbill } 63625Sbill do { 64625Sbill long o; 65625Sbill register n; 66625Sbill struct nlist sym; 67625Sbill 68625Sbill fread((char *)&exp, 1, sizeof(struct exec), fi); 69625Sbill if (N_BADMAG(exp)) 70625Sbill continue; 71*17423Sralph if (!strncmp(tempnm, archdr.ar_name, sizeof(archdr.ar_name))) 72*17423Sralph continue; 73625Sbill if (exp.a_syms == 0) { 74625Sbill fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name); 753607Ssklower continue; 76625Sbill } 77625Sbill o = N_STROFF(exp) - sizeof (struct exec); 78625Sbill if (ftell(fi)+o+sizeof(ssiz) >= off) { 79*17423Sralph fprintf(stderr, "ranlib: warning: %s(%s): old format .o file\n", *argv, archdr.ar_name); 80*17423Sralph continue; 81625Sbill } 82625Sbill fseek(fi, o, 1); 83625Sbill fread((char *)&ssiz, 1, sizeof (ssiz), fi); 849343Srt if (ssiz < sizeof ssiz){ 859343Srt /* sanity check */ 86*17423Sralph fprintf(stderr, "ranlib: warning: %s(%s): mangled string table\n", *argv, archdr.ar_name); 87*17423Sralph continue; 889343Srt } 89625Sbill strtab = (char *)calloc(1, ssiz); 90625Sbill if (strtab == 0) { 91625Sbill fprintf(stderr, "ranlib: ran out of memory\n"); 92625Sbill exit(1); 93625Sbill } 94625Sbill fread(strtab+sizeof(ssiz), ssiz - sizeof(ssiz), 1, fi); 95625Sbill fseek(fi, -(exp.a_syms+ssiz), 1); 96625Sbill n = exp.a_syms / sizeof(struct nlist); 97625Sbill while (--n >= 0) { 98625Sbill fread((char *)&sym, 1, sizeof(sym), fi); 99625Sbill if (sym.n_un.n_strx == 0) 100625Sbill continue; 101625Sbill sym.n_un.n_name = strtab + sym.n_un.n_strx; 102625Sbill if ((sym.n_type&N_EXT)==0) 103625Sbill continue; 104625Sbill switch (sym.n_type&N_TYPE) { 105625Sbill 106625Sbill case N_UNDF: 107625Sbill if (sym.n_value!=0) 108625Sbill stash(&sym); 109625Sbill continue; 110625Sbill 111625Sbill default: 112625Sbill stash(&sym); 113625Sbill continue; 114625Sbill } 115625Sbill } 116625Sbill } while(nextel(fi)); 117625Sbill new = fixsize(); 118625Sbill fclose(fi); 119625Sbill fo = fopen(tempnm, "w"); 120625Sbill if(fo == NULL) { 121625Sbill fprintf(stderr, "can't create temporary\n"); 122625Sbill exit(1); 123625Sbill } 124625Sbill tnum *= sizeof (struct ranlib); 125625Sbill fwrite(&tnum, 1, sizeof (tnum), fo); 126625Sbill tnum /= sizeof (struct ranlib); 127625Sbill fwrite((char *)tab, tnum, sizeof(struct ranlib), fo); 128625Sbill fwrite(&tssiz, 1, sizeof (tssiz), fo); 129625Sbill fwrite(tstrtab, tssiz, 1, fo); 130625Sbill fclose(fo); 131625Sbill if(new) 132899Sbill sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm); 133625Sbill else 134899Sbill sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm); 135625Sbill if(system(cmdbuf)) 136625Sbill fprintf(stderr, "ranlib: ``%s'' failed\n", cmdbuf); 137625Sbill else 138625Sbill fixdate(*argv); 139625Sbill unlink(tempnm); 140625Sbill } 141625Sbill exit(0); 142625Sbill } 143625Sbill 144625Sbill nextel(af) 145625Sbill FILE *af; 146625Sbill { 147625Sbill register r; 148625Sbill register char *cp; 149625Sbill 150625Sbill oldoff = off; 151625Sbill fseek(af, off, 0); 152625Sbill r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); 153625Sbill if (r != sizeof(struct ar_hdr)) 154625Sbill return(0); 155625Sbill for (cp=archdr.ar_name; cp < & archdr.ar_name[sizeof(archdr.ar_name)]; cp++) 156625Sbill if (*cp == ' ') 157625Sbill *cp = '\0'; 158625Sbill arsize = atol(archdr.ar_size); 159625Sbill if (arsize & 1) 160625Sbill arsize++; 161625Sbill off = ftell(af) + arsize; 162625Sbill return(1); 163625Sbill } 164625Sbill 165625Sbill stash(s) 166625Sbill struct nlist *s; 167625Sbill { 168625Sbill int i; 169625Sbill register char *cp; 170625Sbill 171625Sbill if(tnum >= TABSZ) { 172625Sbill fprintf(stderr, "ranlib: symbol table overflow\n"); 173625Sbill exit(1); 174625Sbill } 175625Sbill tab[tnum].ran_un.ran_strx = tssiz; 176625Sbill tab[tnum].ran_off = oldoff; 177625Sbill for (cp = s->n_un.n_name; tstrtab[tssiz++] = *cp++;) 178625Sbill if (tssiz > STRTABSZ) { 179625Sbill fprintf(stderr, "ranlib: string table overflow\n"); 180625Sbill exit(1); 181625Sbill } 182625Sbill tnum++; 183625Sbill } 184625Sbill 185625Sbill fixsize() 186625Sbill { 187625Sbill int i; 188625Sbill off_t offdelta; 189625Sbill 190625Sbill if (tssiz&1) 191625Sbill tssiz++; 192625Sbill offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) + 193625Sbill sizeof (tssiz) + tssiz; 194625Sbill off = SARMAG; 195625Sbill nextel(fi); 196625Sbill if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) { 197625Sbill new = 0; 198625Sbill offdelta -= sizeof(archdr) + arsize; 199625Sbill } else { 200625Sbill new = 1; 201625Sbill strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name)); 202625Sbill } 203625Sbill for(i=0; i<tnum; i++) 204625Sbill tab[i].ran_off += offdelta; 205625Sbill return(new); 206625Sbill } 207625Sbill 208625Sbill /* patch time */ 209625Sbill fixdate(s) 210625Sbill char *s; 211625Sbill { 212625Sbill long time(); 213625Sbill char buf[24]; 214625Sbill int fd; 215625Sbill 216625Sbill fd = open(s, 1); 217625Sbill if(fd < 0) { 218625Sbill fprintf(stderr, "ranlib: can't reopen %s\n", s); 219625Sbill return; 220625Sbill } 221625Sbill sprintf(buf, "%-*ld", sizeof(archdr.ar_date), time((long *)NULL)+5); 222625Sbill lseek(fd, (long)SARMAG + ((char *)archdr.ar_date-(char *)&archdr), 0); 223625Sbill write(fd, buf, sizeof(archdr.ar_date)); 224625Sbill close(fd); 225625Sbill } 226