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