|
|
1.1 root 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:
7: #ifndef lint
8: char 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
14: static char sccsid[] = "@(#)ranlib.c 5.4 (Berkeley) 4/6/87";
15: #endif not lint
16:
17: /*
18: * ranlib - create table of contents for archive; string table version
19: */
20: #include <sys/types.h>
21: #include <ar.h>
22: #include <ranlib.h>
23: #include <a.out.h>
24: #include <stdio.h>
25:
26: struct ar_hdr archdr;
27: #define OARMAG 0177545
28: long arsize;
29: struct exec exp;
30: FILE *fi, *fo;
31: long off, oldoff;
32: long atol(), ftell();
33: #define TABSZ 3000
34: int tnum;
35: #define STRTABSZ 30000
36: int tssiz;
37: char *strtab;
38: int ssiz;
39: int new;
40: char tempnm[] = RANLIBMAG;
41: char firstname[17];
42: void stash();
43: char *malloc(), *calloc();
44:
45: /*
46: * table segment definitions
47: */
48: char *segalloc();
49: void segclean();
50: struct tabsegment {
51: struct tabsegment *pnext;
52: unsigned nelem;
53: struct ranlib tab[TABSZ];
54: } tabbase, *ptabseg;
55: struct strsegment {
56: struct strsegment *pnext;
57: unsigned nelem;
58: char stab[STRTABSZ];
59: } strbase, *pstrseg;
60:
61: main(argc, argv)
62: char **argv;
63: {
64: char cmdbuf[BUFSIZ];
65: /* magbuf must be an int array so it is aligned on an int-ish
66: boundary, so that we may access its first word as an int! */
67: int magbuf[(SARMAG+sizeof(int))/sizeof(int)];
68: register int just_touch = 0;
69: register struct tabsegment *ptab;
70: register struct strsegment *pstr;
71:
72: /* check for the "-t" flag" */
73: if (argc > 1 && strcmp(argv[1], "-t") == 0) {
74: just_touch++;
75: argc--;
76: argv++;
77: }
78:
79: --argc;
80: while(argc--) {
81: fi = fopen(*++argv,"r");
82: if (fi == NULL) {
83: fprintf(stderr, "ranlib: cannot open %s\n", *argv);
84: continue;
85: }
86: off = SARMAG;
87: fread((char *)magbuf, 1, SARMAG, fi);
88: if (strncmp((char *)magbuf, ARMAG, SARMAG)) {
89: if (magbuf[0] == OARMAG)
90: fprintf(stderr, "old format ");
91: else
92: fprintf(stderr, "not an ");
93: fprintf(stderr, "archive: %s\n", *argv);
94: continue;
95: }
96: if (just_touch) {
97: register int len;
98:
99: fseek(fi, (long) SARMAG, 0);
100: if (fread(cmdbuf, sizeof archdr.ar_name, 1, fi) != 1) {
101: fprintf(stderr, "malformed archive: %s\n",
102: *argv);
103: continue;
104: }
105: len = strlen(tempnm);
106: if (bcmp(cmdbuf, tempnm, len) != 0 ||
107: cmdbuf[len] != ' ') {
108: fprintf(stderr, "no symbol table: %s\n", *argv);
109: continue;
110: }
111: fclose(fi);
112: fixdate(*argv);
113: continue;
114: }
115: fseek(fi, 0L, 0);
116: new = tssiz = tnum = 0;
117: segclean();
118: if (nextel(fi) == 0) {
119: fclose(fi);
120: continue;
121: }
122: do {
123: long o;
124: register n;
125: struct nlist sym;
126:
127: fread((char *)&exp, 1, sizeof(struct exec), fi);
128: if (N_BADMAG(exp))
129: continue;
130: if (!strncmp(tempnm, archdr.ar_name, sizeof(archdr.ar_name)))
131: continue;
132: if (exp.a_syms == 0) {
133: fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name);
134: continue;
135: }
136: o = N_STROFF(exp) - sizeof (struct exec);
137: if (ftell(fi)+o+sizeof(ssiz) >= off) {
138: fprintf(stderr, "ranlib: warning: %s(%s): old format .o file\n", *argv, archdr.ar_name);
139: continue;
140: }
141: fseek(fi, o, 1);
142: fread((char *)&ssiz, 1, sizeof (ssiz), fi);
143: if (ssiz < sizeof ssiz){
144: /* sanity check */
145: fprintf(stderr, "ranlib: warning: %s(%s): mangled string table\n", *argv, archdr.ar_name);
146: continue;
147: }
148: strtab = (char *)calloc(1, ssiz);
149: if (strtab == 0) {
150: fprintf(stderr, "ranlib: ran out of memory\n");
151: exit(1);
152: }
153: fread(strtab+sizeof(ssiz), ssiz - sizeof(ssiz), 1, fi);
154: fseek(fi, -(exp.a_syms+ssiz), 1);
155: n = exp.a_syms / sizeof(struct nlist);
156: while (--n >= 0) {
157: fread((char *)&sym, 1, sizeof(sym), fi);
158: if (sym.n_un.n_strx == 0)
159: continue;
160: sym.n_un.n_name = strtab + sym.n_un.n_strx;
161: if ((sym.n_type&N_EXT)==0)
162: continue;
163: switch (sym.n_type&N_TYPE) {
164:
165: case N_UNDF:
166: if (sym.n_value!=0)
167: stash(&sym);
168: continue;
169:
170: default:
171: stash(&sym);
172: continue;
173: }
174: }
175: free(strtab);
176: } while(nextel(fi));
177: new = fixsize();
178: fclose(fi);
179: fo = fopen(tempnm, "w");
180: if(fo == NULL) {
181: fprintf(stderr, "can't create temporary\n");
182: exit(1);
183: }
184: tnum *= sizeof (struct ranlib);
185: fwrite(&tnum, 1, sizeof (tnum), fo);
186: tnum /= sizeof (struct ranlib);
187: ptab = &tabbase;
188: do {
189: fwrite((char *)ptab->tab, ptab->nelem,
190: sizeof(struct ranlib), fo);
191: } while (ptab = ptab->pnext);
192: fwrite(&tssiz, 1, sizeof (tssiz), fo);
193: pstr = &strbase;
194: do {
195: fwrite(pstr->stab, pstr->nelem, 1, fo);
196: tssiz -= pstr->nelem;
197: } while (pstr = pstr->pnext);
198: /* pad with nulls */
199: while (tssiz--) putc('\0', fo);
200: fclose(fo);
201: if(new)
202: sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm);
203: else
204: sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm);
205: if(system(cmdbuf))
206: fprintf(stderr, "ranlib: ``%s'' failed\n", cmdbuf);
207: else
208: fixdate(*argv);
209: unlink(tempnm);
210: }
211: exit(0);
212: }
213:
214: nextel(af)
215: FILE *af;
216: {
217: register r;
218: register char *cp;
219:
220: oldoff = off;
221: fseek(af, off, 0);
222: r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af);
223: if (r != sizeof(struct ar_hdr))
224: return(0);
225: for (cp=archdr.ar_name; cp < & archdr.ar_name[sizeof(archdr.ar_name)]; cp++)
226: if (*cp == ' ')
227: *cp = '\0';
228: arsize = atol(archdr.ar_size);
229: if (arsize & 1)
230: arsize++;
231: off = ftell(af) + arsize;
232: return(1);
233: }
234:
235: void
236: stash(s)
237: struct nlist *s;
238: {
239: register char *cp;
240: register char *strtab;
241: register strsiz;
242: register struct ranlib *tab;
243: register tabsiz;
244:
245: if (ptabseg->nelem >= TABSZ) {
246: /* allocate a new symbol table segment */
247: ptabseg = ptabseg->pnext =
248: (struct tabsegment *) segalloc(sizeof(struct tabsegment));
249: ptabseg->pnext = NULL;
250: ptabseg->nelem = 0;
251: }
252: tabsiz = ptabseg->nelem;
253: tab = ptabseg->tab;
254:
255: if (pstrseg->nelem >= STRTABSZ) {
256: /* allocate a new string table segment */
257: pstrseg = pstrseg->pnext =
258: (struct strsegment *) segalloc(sizeof(struct strsegment));
259: pstrseg->pnext = NULL;
260: pstrseg->nelem = 0;
261: }
262: strsiz = pstrseg->nelem;
263: strtab = pstrseg->stab;
264:
265: tab[tabsiz].ran_un.ran_strx = tssiz;
266: tab[tabsiz].ran_off = oldoff;
267: redo:
268: for (cp = s->n_un.n_name; strtab[strsiz++] = *cp++;)
269: if (strsiz >= STRTABSZ) {
270: /* allocate a new string table segment */
271: pstrseg = pstrseg->pnext =
272: (struct strsegment *) segalloc(sizeof(struct strsegment));
273: pstrseg->pnext = NULL;
274: strsiz = pstrseg->nelem = 0;
275: strtab = pstrseg->stab;
276: goto redo;
277: }
278:
279: tssiz += strsiz - pstrseg->nelem; /* length of the string */
280: pstrseg->nelem = strsiz;
281: tnum++;
282: ptabseg->nelem++;
283: }
284:
285: /* allocate a zero filled segment of size bytes */
286: char *
287: segalloc(size)
288: unsigned size;
289: {
290: char *pseg = NULL;
291:
292: pseg = malloc(size);
293: if (pseg == NULL) {
294: fprintf(stderr, "ranlib: ran out of memeory\n");
295: exit(1);
296: }
297: return(pseg);
298: }
299:
300: /* free segments */
301: void
302: segclean()
303: {
304: register struct tabsegment *ptab;
305: register struct strsegment *pstr;
306:
307: /*
308: * symbol table
309: *
310: * The first entry is static.
311: */
312: ptabseg = &tabbase;
313: ptab = ptabseg->pnext;
314: while (ptabseg = ptab) {
315: ptab = ptabseg->pnext;
316: free((char *)ptabseg);
317: }
318: ptabseg = &tabbase;
319: ptabseg->pnext = NULL;
320: ptabseg->nelem = 0;
321:
322: /*
323: * string table
324: *
325: * The first entry is static.
326: */
327: pstrseg = &strbase;
328: pstr = pstrseg->pnext;
329: while (pstrseg = pstr) {
330: pstr = pstrseg->pnext;
331: free((char *)pstrseg);
332: }
333: pstrseg = &strbase;
334: pstrseg->pnext = NULL;
335: pstrseg->nelem = 0;
336: }
337:
338: fixsize()
339: {
340: int i;
341: off_t offdelta;
342: register struct tabsegment *ptab;
343:
344: if (tssiz&1)
345: tssiz++;
346: offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) +
347: sizeof (tssiz) + tssiz;
348: off = SARMAG;
349: nextel(fi);
350: if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) {
351: new = 0;
352: offdelta -= sizeof(archdr) + arsize;
353: } else {
354: new = 1;
355: strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name));
356: }
357: ptab = &tabbase;
358: do {
359: for (i = 0; i < ptab->nelem; i++)
360: ptab->tab[i].ran_off += offdelta;
361: } while (ptab = ptab->pnext);
362: return(new);
363: }
364:
365: /* patch time */
366: fixdate(s)
367: char *s;
368: {
369: long time();
370: char buf[24];
371: int fd;
372:
373: fd = open(s, 1);
374: if(fd < 0) {
375: fprintf(stderr, "ranlib: can't reopen %s\n", s);
376: return;
377: }
378: sprintf(buf, "%-*ld", sizeof(archdr.ar_date), time((long *)NULL)+5);
379: lseek(fd, (long)SARMAG + ((char *)archdr.ar_date-(char *)&archdr), 0);
380: write(fd, buf, sizeof(archdr.ar_date));
381: close(fd);
382: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.