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