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