1*625Sbill static char sccsid[] = "@(#)ranlib.c 3.1 08/15/80"; 2*625Sbill /* 3*625Sbill * ranlib - create table of contents for archive; string table version 4*625Sbill */ 5*625Sbill #include <sys/types.h> 6*625Sbill #include <newar.h> 7*625Sbill #include <ranlib.h> 8*625Sbill #include <pagsiz.h> 9*625Sbill #include <newa.out.h> 10*625Sbill #include <stdio.h> 11*625Sbill 12*625Sbill struct ar_hdr archdr; 13*625Sbill #define OARMAG 0177545 14*625Sbill long arsize; 15*625Sbill struct exec exp; 16*625Sbill FILE *fi, *fo; 17*625Sbill long off, oldoff; 18*625Sbill long atol(), ftell(); 19*625Sbill #define TABSZ 1500 20*625Sbill struct ranlib tab[TABSZ]; 21*625Sbill int tnum; 22*625Sbill #define STRTABSZ 25000 23*625Sbill char tstrtab[STRTABSZ]; 24*625Sbill int tssiz; 25*625Sbill char *strtab; 26*625Sbill int ssiz; 27*625Sbill int new; 28*625Sbill char tempnm[] = "__.SYMDEF"; 29*625Sbill char firstname[17]; 30*625Sbill 31*625Sbill main(argc, argv) 32*625Sbill char **argv; 33*625Sbill { 34*625Sbill char cmdbuf[BUFSIZ]; 35*625Sbill char magbuf[SARMAG+1]; 36*625Sbill 37*625Sbill --argc; 38*625Sbill while(argc--) { 39*625Sbill fi = fopen(*++argv,"r"); 40*625Sbill if (fi == NULL) { 41*625Sbill fprintf(stderr, "ranlib: cannot open %s\n", *argv); 42*625Sbill continue; 43*625Sbill } 44*625Sbill off = SARMAG; 45*625Sbill fread(magbuf, 1, SARMAG, fi); 46*625Sbill if (strncmp(magbuf, ARMAG, SARMAG)) { 47*625Sbill if (*(int *)magbuf == OARMAG) 48*625Sbill fprintf(stderr, "old format "); 49*625Sbill else 50*625Sbill fprintf(stderr, "not an "); 51*625Sbill fprintf(stderr, "archive: %s\n", *argv); 52*625Sbill continue; 53*625Sbill } 54*625Sbill fseek(fi, 0L, 0); 55*625Sbill new = tnum = 0; 56*625Sbill if (nextel(fi) == 0) { 57*625Sbill fclose(fi); 58*625Sbill continue; 59*625Sbill } 60*625Sbill do { 61*625Sbill long o; 62*625Sbill register n; 63*625Sbill struct nlist sym; 64*625Sbill 65*625Sbill fread((char *)&exp, 1, sizeof(struct exec), fi); 66*625Sbill if (N_BADMAG(exp)) 67*625Sbill continue; 68*625Sbill if (exp.a_syms == 0) { 69*625Sbill fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name); 70*625Sbill exit(1); 71*625Sbill } 72*625Sbill o = N_STROFF(exp) - sizeof (struct exec); 73*625Sbill if (ftell(fi)+o+sizeof(ssiz) >= off) { 74*625Sbill fprintf(stderr, "ranlib: %s(%s): old format .o file\n", *argv, archdr.ar_name); 75*625Sbill exit(1); 76*625Sbill } 77*625Sbill fseek(fi, o, 1); 78*625Sbill fread((char *)&ssiz, 1, sizeof (ssiz), fi); 79*625Sbill strtab = (char *)calloc(1, ssiz); 80*625Sbill if (strtab == 0) { 81*625Sbill fprintf(stderr, "ranlib: ran out of memory\n"); 82*625Sbill exit(1); 83*625Sbill } 84*625Sbill fread(strtab+sizeof(ssiz), ssiz - sizeof(ssiz), 1, fi); 85*625Sbill fseek(fi, -(exp.a_syms+ssiz), 1); 86*625Sbill n = exp.a_syms / sizeof(struct nlist); 87*625Sbill while (--n >= 0) { 88*625Sbill fread((char *)&sym, 1, sizeof(sym), fi); 89*625Sbill if (sym.n_un.n_strx == 0) 90*625Sbill continue; 91*625Sbill sym.n_un.n_name = strtab + sym.n_un.n_strx; 92*625Sbill if ((sym.n_type&N_EXT)==0) 93*625Sbill continue; 94*625Sbill switch (sym.n_type&N_TYPE) { 95*625Sbill 96*625Sbill case N_UNDF: 97*625Sbill if (sym.n_value!=0) 98*625Sbill stash(&sym); 99*625Sbill continue; 100*625Sbill 101*625Sbill default: 102*625Sbill stash(&sym); 103*625Sbill continue; 104*625Sbill } 105*625Sbill } 106*625Sbill } while(nextel(fi)); 107*625Sbill new = fixsize(); 108*625Sbill fclose(fi); 109*625Sbill fo = fopen(tempnm, "w"); 110*625Sbill if(fo == NULL) { 111*625Sbill fprintf(stderr, "can't create temporary\n"); 112*625Sbill exit(1); 113*625Sbill } 114*625Sbill tnum *= sizeof (struct ranlib); 115*625Sbill fwrite(&tnum, 1, sizeof (tnum), fo); 116*625Sbill tnum /= sizeof (struct ranlib); 117*625Sbill fwrite((char *)tab, tnum, sizeof(struct ranlib), fo); 118*625Sbill fwrite(&tssiz, 1, sizeof (tssiz), fo); 119*625Sbill fwrite(tstrtab, tssiz, 1, fo); 120*625Sbill fclose(fo); 121*625Sbill if(new) 122*625Sbill sprintf(cmdbuf, "/usr/new/ar rlb %s %s %s\n", firstname, *argv, tempnm); 123*625Sbill else 124*625Sbill sprintf(cmdbuf, "/usr/new/ar rl %s %s\n", *argv, tempnm); 125*625Sbill if(system(cmdbuf)) 126*625Sbill fprintf(stderr, "ranlib: ``%s'' failed\n", cmdbuf); 127*625Sbill else 128*625Sbill fixdate(*argv); 129*625Sbill unlink(tempnm); 130*625Sbill } 131*625Sbill exit(0); 132*625Sbill } 133*625Sbill 134*625Sbill nextel(af) 135*625Sbill FILE *af; 136*625Sbill { 137*625Sbill register r; 138*625Sbill register char *cp; 139*625Sbill 140*625Sbill oldoff = off; 141*625Sbill fseek(af, off, 0); 142*625Sbill r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); 143*625Sbill if (r != sizeof(struct ar_hdr)) 144*625Sbill return(0); 145*625Sbill for (cp=archdr.ar_name; cp < & archdr.ar_name[sizeof(archdr.ar_name)]; cp++) 146*625Sbill if (*cp == ' ') 147*625Sbill *cp = '\0'; 148*625Sbill arsize = atol(archdr.ar_size); 149*625Sbill if (arsize & 1) 150*625Sbill arsize++; 151*625Sbill off = ftell(af) + arsize; 152*625Sbill return(1); 153*625Sbill } 154*625Sbill 155*625Sbill stash(s) 156*625Sbill struct nlist *s; 157*625Sbill { 158*625Sbill int i; 159*625Sbill register char *cp; 160*625Sbill 161*625Sbill if(tnum >= TABSZ) { 162*625Sbill fprintf(stderr, "ranlib: symbol table overflow\n"); 163*625Sbill exit(1); 164*625Sbill } 165*625Sbill tab[tnum].ran_un.ran_strx = tssiz; 166*625Sbill tab[tnum].ran_off = oldoff; 167*625Sbill for (cp = s->n_un.n_name; tstrtab[tssiz++] = *cp++;) 168*625Sbill if (tssiz > STRTABSZ) { 169*625Sbill fprintf(stderr, "ranlib: string table overflow\n"); 170*625Sbill exit(1); 171*625Sbill } 172*625Sbill tnum++; 173*625Sbill } 174*625Sbill 175*625Sbill fixsize() 176*625Sbill { 177*625Sbill int i; 178*625Sbill off_t offdelta; 179*625Sbill 180*625Sbill if (tssiz&1) 181*625Sbill tssiz++; 182*625Sbill offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) + 183*625Sbill sizeof (tssiz) + tssiz; 184*625Sbill off = SARMAG; 185*625Sbill nextel(fi); 186*625Sbill if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) { 187*625Sbill new = 0; 188*625Sbill offdelta -= sizeof(archdr) + arsize; 189*625Sbill } else { 190*625Sbill new = 1; 191*625Sbill strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name)); 192*625Sbill } 193*625Sbill for(i=0; i<tnum; i++) 194*625Sbill tab[i].ran_off += offdelta; 195*625Sbill return(new); 196*625Sbill } 197*625Sbill 198*625Sbill /* patch time */ 199*625Sbill fixdate(s) 200*625Sbill char *s; 201*625Sbill { 202*625Sbill long time(); 203*625Sbill char buf[24]; 204*625Sbill int fd; 205*625Sbill 206*625Sbill fd = open(s, 1); 207*625Sbill if(fd < 0) { 208*625Sbill fprintf(stderr, "ranlib: can't reopen %s\n", s); 209*625Sbill return; 210*625Sbill } 211*625Sbill sprintf(buf, "%-*ld", sizeof(archdr.ar_date), time((long *)NULL)+5); 212*625Sbill lseek(fd, (long)SARMAG + ((char *)archdr.ar_date-(char *)&archdr), 0); 213*625Sbill write(fd, buf, sizeof(archdr.ar_date)); 214*625Sbill close(fd); 215*625Sbill } 216