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