BSD 4 release
[unix-history] / usr / src / cmd / ranlib.c
CommitLineData
31cef89c 1static char sccsid[] = "@(#)ranlib.c 4.2 11/8/80";
1372f8b5
BJ
2/*
3 * ranlib - create table of contents for archive; string table version
4 */
5#include <sys/types.h>
2785c759 6#include <ar.h>
1372f8b5
BJ
7#include <ranlib.h>
8#include <pagsiz.h>
2785c759 9#include <a.out.h>
1372f8b5
BJ
10#include <stdio.h>
11
12struct ar_hdr archdr;
13#define OARMAG 0177545
14long arsize;
15struct exec exp;
16FILE *fi, *fo;
17long off, oldoff;
18long atol(), ftell();
56834dbc 19#define TABSZ 5000
1372f8b5
BJ
20struct ranlib tab[TABSZ];
21int tnum;
56834dbc 22#define STRTABSZ 75000
1372f8b5
BJ
23char tstrtab[STRTABSZ];
24int tssiz;
25char *strtab;
26int ssiz;
27int new;
28char tempnm[] = "__.SYMDEF";
29char firstname[17];
30
31main(argc, argv)
32char **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 exit(1);
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)
2785c759 122 sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm);
1372f8b5 123 else
2785c759 124 sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm);
1372f8b5
BJ
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
134nextel(af)
135FILE *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
155stash(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
175fixsize()
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 */
199fixdate(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}