112673Ssam #ifndef lint 2*19932Smckusick static char sccsid[] = "@(#)ranlib.c 4.8 05/03/85"; 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)]; 39*19932Smckusick register int just_touch = 0; 40625Sbill 41*19932Smckusick /* check for the "-t" flag" */ 42*19932Smckusick if (argc > 1 && strcmp(argv[1], "-t") == 0) { 43*19932Smckusick just_touch++; 44*19932Smckusick argc--; 45*19932Smckusick argv++; 46*19932Smckusick } 47*19932Smckusick 48625Sbill --argc; 49625Sbill while(argc--) { 50*19932Smckusick if (just_touch) { 51*19932Smckusick fixdate(*++argv); 52*19932Smckusick continue; 53*19932Smckusick } 54*19932Smckusick 55625Sbill fi = fopen(*++argv,"r"); 56625Sbill if (fi == NULL) { 57625Sbill fprintf(stderr, "ranlib: cannot open %s\n", *argv); 58625Sbill continue; 59625Sbill } 60625Sbill off = SARMAG; 619343Srt fread((char *)magbuf, 1, SARMAG, fi); 629343Srt if (strncmp((char *)magbuf, ARMAG, SARMAG)) { 639343Srt if (magbuf[0] == OARMAG) 64625Sbill fprintf(stderr, "old format "); 65625Sbill else 66625Sbill fprintf(stderr, "not an "); 67625Sbill fprintf(stderr, "archive: %s\n", *argv); 68625Sbill continue; 69625Sbill } 70625Sbill fseek(fi, 0L, 0); 71625Sbill new = tnum = 0; 72625Sbill if (nextel(fi) == 0) { 73625Sbill fclose(fi); 74625Sbill continue; 75625Sbill } 76625Sbill do { 77625Sbill long o; 78625Sbill register n; 79625Sbill struct nlist sym; 80625Sbill 81625Sbill fread((char *)&exp, 1, sizeof(struct exec), fi); 82625Sbill if (N_BADMAG(exp)) 83625Sbill continue; 8417423Sralph if (!strncmp(tempnm, archdr.ar_name, sizeof(archdr.ar_name))) 8517423Sralph continue; 86625Sbill if (exp.a_syms == 0) { 87625Sbill fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name); 883607Ssklower continue; 89625Sbill } 90625Sbill o = N_STROFF(exp) - sizeof (struct exec); 91625Sbill if (ftell(fi)+o+sizeof(ssiz) >= off) { 9217423Sralph fprintf(stderr, "ranlib: warning: %s(%s): old format .o file\n", *argv, archdr.ar_name); 9317423Sralph continue; 94625Sbill } 95625Sbill fseek(fi, o, 1); 96625Sbill fread((char *)&ssiz, 1, sizeof (ssiz), fi); 979343Srt if (ssiz < sizeof ssiz){ 989343Srt /* sanity check */ 9917423Sralph fprintf(stderr, "ranlib: warning: %s(%s): mangled string table\n", *argv, archdr.ar_name); 10017423Sralph continue; 1019343Srt } 102625Sbill strtab = (char *)calloc(1, ssiz); 103625Sbill if (strtab == 0) { 104625Sbill fprintf(stderr, "ranlib: ran out of memory\n"); 105625Sbill exit(1); 106625Sbill } 107625Sbill fread(strtab+sizeof(ssiz), ssiz - sizeof(ssiz), 1, fi); 108625Sbill fseek(fi, -(exp.a_syms+ssiz), 1); 109625Sbill n = exp.a_syms / sizeof(struct nlist); 110625Sbill while (--n >= 0) { 111625Sbill fread((char *)&sym, 1, sizeof(sym), fi); 112625Sbill if (sym.n_un.n_strx == 0) 113625Sbill continue; 114625Sbill sym.n_un.n_name = strtab + sym.n_un.n_strx; 115625Sbill if ((sym.n_type&N_EXT)==0) 116625Sbill continue; 117625Sbill switch (sym.n_type&N_TYPE) { 118625Sbill 119625Sbill case N_UNDF: 120625Sbill if (sym.n_value!=0) 121625Sbill stash(&sym); 122625Sbill continue; 123625Sbill 124625Sbill default: 125625Sbill stash(&sym); 126625Sbill continue; 127625Sbill } 128625Sbill } 129625Sbill } while(nextel(fi)); 130625Sbill new = fixsize(); 131625Sbill fclose(fi); 132625Sbill fo = fopen(tempnm, "w"); 133625Sbill if(fo == NULL) { 134625Sbill fprintf(stderr, "can't create temporary\n"); 135625Sbill exit(1); 136625Sbill } 137625Sbill tnum *= sizeof (struct ranlib); 138625Sbill fwrite(&tnum, 1, sizeof (tnum), fo); 139625Sbill tnum /= sizeof (struct ranlib); 140625Sbill fwrite((char *)tab, tnum, sizeof(struct ranlib), fo); 141625Sbill fwrite(&tssiz, 1, sizeof (tssiz), fo); 142625Sbill fwrite(tstrtab, tssiz, 1, fo); 143625Sbill fclose(fo); 144625Sbill if(new) 145899Sbill sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm); 146625Sbill else 147899Sbill sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm); 148625Sbill if(system(cmdbuf)) 149625Sbill fprintf(stderr, "ranlib: ``%s'' failed\n", cmdbuf); 150625Sbill else 151625Sbill fixdate(*argv); 152625Sbill unlink(tempnm); 153625Sbill } 154625Sbill exit(0); 155625Sbill } 156625Sbill 157625Sbill nextel(af) 158625Sbill FILE *af; 159625Sbill { 160625Sbill register r; 161625Sbill register char *cp; 162625Sbill 163625Sbill oldoff = off; 164625Sbill fseek(af, off, 0); 165625Sbill r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); 166625Sbill if (r != sizeof(struct ar_hdr)) 167625Sbill return(0); 168625Sbill for (cp=archdr.ar_name; cp < & archdr.ar_name[sizeof(archdr.ar_name)]; cp++) 169625Sbill if (*cp == ' ') 170625Sbill *cp = '\0'; 171625Sbill arsize = atol(archdr.ar_size); 172625Sbill if (arsize & 1) 173625Sbill arsize++; 174625Sbill off = ftell(af) + arsize; 175625Sbill return(1); 176625Sbill } 177625Sbill 178625Sbill stash(s) 179625Sbill struct nlist *s; 180625Sbill { 181625Sbill int i; 182625Sbill register char *cp; 183625Sbill 184625Sbill if(tnum >= TABSZ) { 185625Sbill fprintf(stderr, "ranlib: symbol table overflow\n"); 186625Sbill exit(1); 187625Sbill } 188625Sbill tab[tnum].ran_un.ran_strx = tssiz; 189625Sbill tab[tnum].ran_off = oldoff; 190625Sbill for (cp = s->n_un.n_name; tstrtab[tssiz++] = *cp++;) 191625Sbill if (tssiz > STRTABSZ) { 192625Sbill fprintf(stderr, "ranlib: string table overflow\n"); 193625Sbill exit(1); 194625Sbill } 195625Sbill tnum++; 196625Sbill } 197625Sbill 198625Sbill fixsize() 199625Sbill { 200625Sbill int i; 201625Sbill off_t offdelta; 202625Sbill 203625Sbill if (tssiz&1) 204625Sbill tssiz++; 205625Sbill offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) + 206625Sbill sizeof (tssiz) + tssiz; 207625Sbill off = SARMAG; 208625Sbill nextel(fi); 209625Sbill if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) { 210625Sbill new = 0; 211625Sbill offdelta -= sizeof(archdr) + arsize; 212625Sbill } else { 213625Sbill new = 1; 214625Sbill strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name)); 215625Sbill } 216625Sbill for(i=0; i<tnum; i++) 217625Sbill tab[i].ran_off += offdelta; 218625Sbill return(new); 219625Sbill } 220625Sbill 221625Sbill /* patch time */ 222625Sbill fixdate(s) 223625Sbill char *s; 224625Sbill { 225625Sbill long time(); 226625Sbill char buf[24]; 227625Sbill int fd; 228625Sbill 229625Sbill fd = open(s, 1); 230625Sbill if(fd < 0) { 231625Sbill fprintf(stderr, "ranlib: can't reopen %s\n", s); 232625Sbill return; 233625Sbill } 234625Sbill sprintf(buf, "%-*ld", sizeof(archdr.ar_date), time((long *)NULL)+5); 235625Sbill lseek(fd, (long)SARMAG + ((char *)archdr.ar_date-(char *)&archdr), 0); 236625Sbill write(fd, buf, sizeof(archdr.ar_date)); 237625Sbill close(fd); 238625Sbill } 239