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