1 #ifndef lint 2 static char sccsid[] = "@(#)ranlib.c 4.6 05/22/83"; 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 (exp.a_syms == 0) { 72 fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name); 73 continue; 74 } 75 o = N_STROFF(exp) - sizeof (struct exec); 76 if (ftell(fi)+o+sizeof(ssiz) >= off) { 77 fprintf(stderr, "ranlib: %s(%s): old format .o file\n", *argv, archdr.ar_name); 78 exit(1); 79 } 80 fseek(fi, o, 1); 81 fread((char *)&ssiz, 1, sizeof (ssiz), fi); 82 if (ssiz < sizeof ssiz){ 83 /* sanity check */ 84 fprintf(stderr, "ranlib: %s(%s): mangled string table\n", *argv, archdr.ar_name); 85 exit(1); 86 } 87 strtab = (char *)calloc(1, ssiz); 88 if (strtab == 0) { 89 fprintf(stderr, "ranlib: ran out of memory\n"); 90 exit(1); 91 } 92 fread(strtab+sizeof(ssiz), ssiz - sizeof(ssiz), 1, fi); 93 fseek(fi, -(exp.a_syms+ssiz), 1); 94 n = exp.a_syms / sizeof(struct nlist); 95 while (--n >= 0) { 96 fread((char *)&sym, 1, sizeof(sym), fi); 97 if (sym.n_un.n_strx == 0) 98 continue; 99 sym.n_un.n_name = strtab + sym.n_un.n_strx; 100 if ((sym.n_type&N_EXT)==0) 101 continue; 102 switch (sym.n_type&N_TYPE) { 103 104 case N_UNDF: 105 if (sym.n_value!=0) 106 stash(&sym); 107 continue; 108 109 default: 110 stash(&sym); 111 continue; 112 } 113 } 114 } while(nextel(fi)); 115 new = fixsize(); 116 fclose(fi); 117 fo = fopen(tempnm, "w"); 118 if(fo == NULL) { 119 fprintf(stderr, "can't create temporary\n"); 120 exit(1); 121 } 122 tnum *= sizeof (struct ranlib); 123 fwrite(&tnum, 1, sizeof (tnum), fo); 124 tnum /= sizeof (struct ranlib); 125 fwrite((char *)tab, tnum, sizeof(struct ranlib), fo); 126 fwrite(&tssiz, 1, sizeof (tssiz), fo); 127 fwrite(tstrtab, tssiz, 1, fo); 128 fclose(fo); 129 if(new) 130 sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm); 131 else 132 sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm); 133 if(system(cmdbuf)) 134 fprintf(stderr, "ranlib: ``%s'' failed\n", cmdbuf); 135 else 136 fixdate(*argv); 137 unlink(tempnm); 138 } 139 exit(0); 140 } 141 142 nextel(af) 143 FILE *af; 144 { 145 register r; 146 register char *cp; 147 148 oldoff = off; 149 fseek(af, off, 0); 150 r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); 151 if (r != sizeof(struct ar_hdr)) 152 return(0); 153 for (cp=archdr.ar_name; cp < & archdr.ar_name[sizeof(archdr.ar_name)]; cp++) 154 if (*cp == ' ') 155 *cp = '\0'; 156 arsize = atol(archdr.ar_size); 157 if (arsize & 1) 158 arsize++; 159 off = ftell(af) + arsize; 160 return(1); 161 } 162 163 stash(s) 164 struct nlist *s; 165 { 166 int i; 167 register char *cp; 168 169 if(tnum >= TABSZ) { 170 fprintf(stderr, "ranlib: symbol table overflow\n"); 171 exit(1); 172 } 173 tab[tnum].ran_un.ran_strx = tssiz; 174 tab[tnum].ran_off = oldoff; 175 for (cp = s->n_un.n_name; tstrtab[tssiz++] = *cp++;) 176 if (tssiz > STRTABSZ) { 177 fprintf(stderr, "ranlib: string table overflow\n"); 178 exit(1); 179 } 180 tnum++; 181 } 182 183 fixsize() 184 { 185 int i; 186 off_t offdelta; 187 188 if (tssiz&1) 189 tssiz++; 190 offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) + 191 sizeof (tssiz) + tssiz; 192 off = SARMAG; 193 nextel(fi); 194 if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) { 195 new = 0; 196 offdelta -= sizeof(archdr) + arsize; 197 } else { 198 new = 1; 199 strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name)); 200 } 201 for(i=0; i<tnum; i++) 202 tab[i].ran_off += offdelta; 203 return(new); 204 } 205 206 /* patch time */ 207 fixdate(s) 208 char *s; 209 { 210 long time(); 211 char buf[24]; 212 int fd; 213 214 fd = open(s, 1); 215 if(fd < 0) { 216 fprintf(stderr, "ranlib: can't reopen %s\n", s); 217 return; 218 } 219 sprintf(buf, "%-*ld", sizeof(archdr.ar_date), time((long *)NULL)+5); 220 lseek(fd, (long)SARMAG + ((char *)archdr.ar_date-(char *)&archdr), 0); 221 write(fd, buf, sizeof(archdr.ar_date)); 222 close(fd); 223 } 224