1*1753Sbill static char sccsid[] = "@(#)ranlib.c 4.2 11/08/80"; 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(); 19*1753Sbill #define TABSZ 5000 20625Sbill struct ranlib tab[TABSZ]; 21625Sbill int tnum; 22*1753Sbill #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]; 35625Sbill char magbuf[SARMAG+1]; 36625Sbill 37625Sbill --argc; 38625Sbill while(argc--) { 39625Sbill fi = fopen(*++argv,"r"); 40625Sbill if (fi == NULL) { 41625Sbill fprintf(stderr, "ranlib: cannot open %s\n", *argv); 42625Sbill continue; 43625Sbill } 44625Sbill off = SARMAG; 45625Sbill fread(magbuf, 1, SARMAG, fi); 46625Sbill if (strncmp(magbuf, ARMAG, SARMAG)) { 47625Sbill if (*(int *)magbuf == OARMAG) 48625Sbill fprintf(stderr, "old format "); 49625Sbill else 50625Sbill fprintf(stderr, "not an "); 51625Sbill fprintf(stderr, "archive: %s\n", *argv); 52625Sbill continue; 53625Sbill } 54625Sbill fseek(fi, 0L, 0); 55625Sbill new = tnum = 0; 56625Sbill if (nextel(fi) == 0) { 57625Sbill fclose(fi); 58625Sbill continue; 59625Sbill } 60625Sbill do { 61625Sbill long o; 62625Sbill register n; 63625Sbill struct nlist sym; 64625Sbill 65625Sbill fread((char *)&exp, 1, sizeof(struct exec), fi); 66625Sbill if (N_BADMAG(exp)) 67625Sbill continue; 68625Sbill if (exp.a_syms == 0) { 69625Sbill fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name); 70625Sbill exit(1); 71625Sbill } 72625Sbill o = N_STROFF(exp) - sizeof (struct exec); 73625Sbill if (ftell(fi)+o+sizeof(ssiz) >= off) { 74625Sbill fprintf(stderr, "ranlib: %s(%s): old format .o file\n", *argv, archdr.ar_name); 75625Sbill exit(1); 76625Sbill } 77625Sbill fseek(fi, o, 1); 78625Sbill fread((char *)&ssiz, 1, sizeof (ssiz), fi); 79625Sbill strtab = (char *)calloc(1, ssiz); 80625Sbill if (strtab == 0) { 81625Sbill fprintf(stderr, "ranlib: ran out of memory\n"); 82625Sbill exit(1); 83625Sbill } 84625Sbill fread(strtab+sizeof(ssiz), ssiz - sizeof(ssiz), 1, fi); 85625Sbill fseek(fi, -(exp.a_syms+ssiz), 1); 86625Sbill n = exp.a_syms / sizeof(struct nlist); 87625Sbill while (--n >= 0) { 88625Sbill fread((char *)&sym, 1, sizeof(sym), fi); 89625Sbill if (sym.n_un.n_strx == 0) 90625Sbill continue; 91625Sbill sym.n_un.n_name = strtab + sym.n_un.n_strx; 92625Sbill if ((sym.n_type&N_EXT)==0) 93625Sbill continue; 94625Sbill switch (sym.n_type&N_TYPE) { 95625Sbill 96625Sbill case N_UNDF: 97625Sbill if (sym.n_value!=0) 98625Sbill stash(&sym); 99625Sbill continue; 100625Sbill 101625Sbill default: 102625Sbill stash(&sym); 103625Sbill continue; 104625Sbill } 105625Sbill } 106625Sbill } while(nextel(fi)); 107625Sbill new = fixsize(); 108625Sbill fclose(fi); 109625Sbill fo = fopen(tempnm, "w"); 110625Sbill if(fo == NULL) { 111625Sbill fprintf(stderr, "can't create temporary\n"); 112625Sbill exit(1); 113625Sbill } 114625Sbill tnum *= sizeof (struct ranlib); 115625Sbill fwrite(&tnum, 1, sizeof (tnum), fo); 116625Sbill tnum /= sizeof (struct ranlib); 117625Sbill fwrite((char *)tab, tnum, sizeof(struct ranlib), fo); 118625Sbill fwrite(&tssiz, 1, sizeof (tssiz), fo); 119625Sbill fwrite(tstrtab, tssiz, 1, fo); 120625Sbill fclose(fo); 121625Sbill if(new) 122899Sbill sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm); 123625Sbill else 124899Sbill sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm); 125625Sbill if(system(cmdbuf)) 126625Sbill fprintf(stderr, "ranlib: ``%s'' failed\n", cmdbuf); 127625Sbill else 128625Sbill fixdate(*argv); 129625Sbill unlink(tempnm); 130625Sbill } 131625Sbill exit(0); 132625Sbill } 133625Sbill 134625Sbill nextel(af) 135625Sbill FILE *af; 136625Sbill { 137625Sbill register r; 138625Sbill register char *cp; 139625Sbill 140625Sbill oldoff = off; 141625Sbill fseek(af, off, 0); 142625Sbill r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); 143625Sbill if (r != sizeof(struct ar_hdr)) 144625Sbill return(0); 145625Sbill for (cp=archdr.ar_name; cp < & archdr.ar_name[sizeof(archdr.ar_name)]; cp++) 146625Sbill if (*cp == ' ') 147625Sbill *cp = '\0'; 148625Sbill arsize = atol(archdr.ar_size); 149625Sbill if (arsize & 1) 150625Sbill arsize++; 151625Sbill off = ftell(af) + arsize; 152625Sbill return(1); 153625Sbill } 154625Sbill 155625Sbill stash(s) 156625Sbill struct nlist *s; 157625Sbill { 158625Sbill int i; 159625Sbill register char *cp; 160625Sbill 161625Sbill if(tnum >= TABSZ) { 162625Sbill fprintf(stderr, "ranlib: symbol table overflow\n"); 163625Sbill exit(1); 164625Sbill } 165625Sbill tab[tnum].ran_un.ran_strx = tssiz; 166625Sbill tab[tnum].ran_off = oldoff; 167625Sbill for (cp = s->n_un.n_name; tstrtab[tssiz++] = *cp++;) 168625Sbill if (tssiz > STRTABSZ) { 169625Sbill fprintf(stderr, "ranlib: string table overflow\n"); 170625Sbill exit(1); 171625Sbill } 172625Sbill tnum++; 173625Sbill } 174625Sbill 175625Sbill fixsize() 176625Sbill { 177625Sbill int i; 178625Sbill off_t offdelta; 179625Sbill 180625Sbill if (tssiz&1) 181625Sbill tssiz++; 182625Sbill offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) + 183625Sbill sizeof (tssiz) + tssiz; 184625Sbill off = SARMAG; 185625Sbill nextel(fi); 186625Sbill if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) { 187625Sbill new = 0; 188625Sbill offdelta -= sizeof(archdr) + arsize; 189625Sbill } else { 190625Sbill new = 1; 191625Sbill strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name)); 192625Sbill } 193625Sbill for(i=0; i<tnum; i++) 194625Sbill tab[i].ran_off += offdelta; 195625Sbill return(new); 196625Sbill } 197625Sbill 198625Sbill /* patch time */ 199625Sbill fixdate(s) 200625Sbill char *s; 201625Sbill { 202625Sbill long time(); 203625Sbill char buf[24]; 204625Sbill int fd; 205625Sbill 206625Sbill fd = open(s, 1); 207625Sbill if(fd < 0) { 208625Sbill fprintf(stderr, "ranlib: can't reopen %s\n", s); 209625Sbill return; 210625Sbill } 211625Sbill sprintf(buf, "%-*ld", sizeof(archdr.ar_date), time((long *)NULL)+5); 212625Sbill lseek(fd, (long)SARMAG + ((char *)archdr.ar_date-(char *)&archdr), 0); 213625Sbill write(fd, buf, sizeof(archdr.ar_date)); 214625Sbill close(fd); 215625Sbill } 216