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