|
|
1.1 root 1: /*
2: * Make libraries more accessible to the loader
3: * by copying all the globally defined symbols
4: * into a special module at the front of the archive.
5: * Speed up by simply overwriting the header in the archive
6: * if it fits, which it will more often than not.
7: */
8: #include <stdio.h>
9: #include <ar.h>
10: #include <canon.h>
11:
12: static struct ldheader ldh;
13:
14: main(argc, argv)
15: int argc;
16: char *argv[];
17: {
18: register int i, errors = 0;
19:
20: if (argc==1) {
21: fprintf(stderr, "Usage: %s [ archive]+\n", argv[0]);
22: exit(1);
23: }
24: for (i=1; i<argc; i++) {
25: errors += ranlib(argv[i]);
26: }
27: unlink(HDRNAME);
28: exit(errors);
29: }
30:
31: static
32: void
33: complain(plaint)
34: char *plaint;
35: {
36: fprintf(stderr, "ranlib: %r\n", &plaint);
37: }
38:
39: static
40: void
41: xwrite(sym, fp)
42: ar_sym *sym;
43: FILE *fp;
44: {
45: if (fwrite(sym, sizeof(ar_sym), 1, fp)!=1) {
46: complain("write error on header file");
47: exit(1);
48: }
49: }
50:
51: static
52: void
53: addhdr(base, arhp, hdrfp, arfp, archive)
54: fsize_t base;
55: struct ar_hdr *arhp;
56: FILE *hdrfp, *arfp;
57: char *archive;
58: {
59: fsize_t off;
60: int seg, nsym;
61: fsize_t offset;
62:
63: cansize(arhp->ar_size);
64: arhp->ar_size += off = ftell(arfp);
65: off -= base;
66: ldh.l_magic = 0; /* in case fread fails */
67: if (fread(&ldh, sizeof ldh, 1, arfp)!=1)
68: goto done;
69: canshort(ldh.l_magic);
70: if (ldh.l_magic!=L_MAGIC)
71: goto done;
72: canshort(ldh.l_flag);
73: if ((ldh.l_flag & LF_32) == 0)
74: ldh.l_tbase = sizeof(ldh) - 2*sizeof(short);
75: else
76: canshort(ldh.l_tbase);
77: offset = ldh.l_tbase - (fsize_t)sizeof(ldh);
78: for (seg=0; seg<L_SYM; seg++) {
79: if (seg==L_BSSI || seg==L_BSSD)
80: continue;
81: cansize(ldh.l_ssize[seg]);
82: offset += ldh.l_ssize[seg];
83: }
84: fseek(arfp, offset, 1);
85: cansize(ldh.l_ssize[L_SYM]);
86: if ((ldh.l_flag & LF_32) == 0)
87: nsym = ldh.l_ssize[L_SYM]
88: / (sizeof(struct ldsym) - sizeof(short));
89: else
90: nsym = ldh.l_ssize[L_SYM]/sizeof(struct ldsym);
91: while (nsym--) {
92: union {struct ldsym u_ldsym; ar_sym u_ar_sym;} sym;
93:
94: if (readsym((struct ldsym *)&sym, arfp) == 0) {
95: complain("truncated module %.*s in %s",
96: DIRSIZ, arhp->ar_name, archive);
97: exit(1);
98: }
99: if ((sym.ls_type&L_GLOBAL) == 0)
100: continue;
101: if ((sym.ls_type&LR_SEG) != L_REF) {
102: sym.ar_off = off;
103: cansize(sym.ar_off);
104: xwrite(&sym, hdrfp);
105: }
106: }
107: done:
108: fseek(arfp, arhp->ar_size, 0); /* to end of module */
109: return;
110: }
111:
112: static
113: readsym(sp, fp)
114: register struct ldsym *sp;
115: FILE *fp;
116: {
117: register int r;
118: union { long l; unsigned u[2]; } u;
119:
120: if ((ldh.l_flag & LF_32) == 0) {
121: r = fread(sp, sizeof(struct ldsym)-sizeof(short), 1, fp);
122: u.l = sp->ls_addr;
123: canshort(u.u[0]);
124: sp->ls_addr = u.u[0];
125: } else {
126: r = fread(sp, sizeof(struct ldsym), 1, fp);
127: canlong(sp->ls_addr);
128: }
129: canshort(sp->ls_type);
130: return (r);
131: }
132:
133: static
134: int
135: ranlib(archive)
136: char *archive;
137: {
138: FILE *arfile, *hdrfile;
139: char arcmd[256];
140: struct ar_hdr arhdr;
141: struct ar_sym arsym;
142: fsize_t ohdrsize, nhdrsize;
143: int armagic = 0;
144: fsize_t arbase = sizeof armagic+sizeof arhdr;
145: extern time_t time();
146:
147: if ((arfile=fopen(archive, "rb"))==NULL) {
148: complain("can't open archive %s", archive);
149: return (1);
150: }
151: fread(&armagic, sizeof armagic, 1, arfile);
152: canint(armagic);
153: if (armagic!=ARMAG) {
154: complain("%s is not an archive", archive);
155: fclose(arfile);
156: return (1);
157: }
158: if (fread(&arhdr, sizeof arhdr, 1, arfile)!=1) {
159: fclose(arfile); /* void archive */
160: return (0);
161: }
162: if ((hdrfile=fopen(HDRNAME, "wb"))==NULL) {
163: complain("can't create header file");
164: fclose(arfile);
165: exit(1);
166: }
167: if (strncmp(arhdr.ar_name, HDRNAME, DIRSIZ)==0) {
168: sprintf(arcmd, "ar ru %s %s", archive, HDRNAME);
169: cansize(arhdr.ar_size);
170: ohdrsize = arhdr.ar_size;
171: fseek(arfile, arhdr.ar_size, 1);
172: arbase += arhdr.ar_size+sizeof arhdr;
173: } else {
174: sprintf(arcmd, "ar rub %.*s %s %s", DIRSIZ, arhdr.ar_name,
175: archive, HDRNAME);
176: ohdrsize = 0;
177: addhdr(arbase, &arhdr, hdrfile, arfile, archive);
178: }
179: while(fread(&arhdr, sizeof arhdr, 1, arfile)==1)
180: addhdr(arbase, &arhdr, hdrfile, arfile, archive);
181: nhdrsize = ftell(hdrfile);
182: if (fclose(hdrfile)==EOF) {
183: complain("close error on header file");
184: exit(1);
185: }
186: if (ferror(arfile)) {
187: complain("read error on archive %s", archive);
188: fclose(arfile);
189: return (1);
190: }
191: fclose(arfile);
192: if (ohdrsize < nhdrsize)
193: return system(arcmd);
194: if (ohdrsize == 0) {
195: complain("zero length header file");
196: return (0);
197: }
198: if ((arfile=fopen(archive, "rwb"))==NULL) {
199: complain("can't reopen archive %s", archive);
200: return (1);
201: }
202: fread(&armagic, sizeof armagic, 1, arfile);
203: canint(armagic);
204: if (armagic!=ARMAG) {
205: complain("%s is no longer an archive", archive);
206: fclose(arfile);
207: return (1);
208: }
209: if ((hdrfile=fopen(HDRNAME, "rb"))==NULL) {
210: complain("can't reopen header file");
211: fclose(arfile);
212: exit(1);
213: }
214: if (fread(&arhdr, sizeof arhdr, 1, arfile)!=1) {
215: complain("can't read archive: %s", archive);
216: fclose(arfile);
217: fclose(hdrfile);
218: return (1);
219: }
220: arhdr.ar_date = time(NULL);
221: cantime(arhdr.ar_date);
222: fseek(arfile, (long)-sizeof arhdr, 1);
223: fwrite(&arhdr, sizeof arhdr, 1, arfile);
224: while (fread(&arsym, sizeof arsym, 1, hdrfile) == 1) {
225: fwrite(&arsym, sizeof arsym, 1, arfile);
226: ohdrsize -= sizeof arsym;
227: }
228: while (ohdrsize > 0) {
229: fwrite(&arsym, sizeof arsym, 1, arfile);
230: ohdrsize -= sizeof arsym;
231: }
232: if (fclose(arfile) == EOF)
233: complain("close error on overwritten archive: %s", archive);
234: if (fclose(hdrfile) == EOF)
235: complain("close error on reread header file");
236: return (0);
237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.