fixup ACULOG to always compile in routines, just not do record w/o
[unix-history] / usr / src / usr.bin / ranlib / ranlib.c
CommitLineData
34aa0635
SL
1#ifndef lint
2static char sccsid[] = "@(#)ranlib.c 4.6 %G%";
3#endif
1372f8b5
BJ
4/*
5 * ranlib - create table of contents for archive; string table version
6 */
7#include <sys/types.h>
2785c759 8#include <ar.h>
1372f8b5 9#include <ranlib.h>
2785c759 10#include <a.out.h>
1372f8b5
BJ
11#include <stdio.h>
12
13struct ar_hdr archdr;
14#define OARMAG 0177545
15long arsize;
16struct exec exp;
17FILE *fi, *fo;
18long off, oldoff;
19long atol(), ftell();
95b5de89 20#define TABSZ 6000
1372f8b5
BJ
21struct ranlib tab[TABSZ];
22int tnum;
56834dbc 23#define STRTABSZ 75000
1372f8b5
BJ
24char tstrtab[STRTABSZ];
25int tssiz;
26char *strtab;
27int ssiz;
28int new;
29char tempnm[] = "__.SYMDEF";
30char firstname[17];
31
32main(argc, argv)
33char **argv;
34{
35 char cmdbuf[BUFSIZ];
2a7750c9 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)];
1372f8b5
BJ
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;
2a7750c9 48 fread((char *)magbuf, 1, SARMAG, fi);
49 if (strncmp((char *)magbuf, ARMAG, SARMAG)) {
50 if (magbuf[0] == OARMAG)
1372f8b5
BJ
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);
fd894872 73 continue;
1372f8b5
BJ
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);
2a7750c9 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 }
1372f8b5
BJ
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)
2785c759 130 sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm);
1372f8b5 131 else
2785c759 132 sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm);
1372f8b5
BJ
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
142nextel(af)
143FILE *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
163stash(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
183fixsize()
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 */
207fixdate(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}