|
|
1.1 root 1: /*
2: * ranlib - create table of contents for archive
3: */
4: #include <sys/types.h>
5: #include <ar.h>
6: #include <ranlib.h>
7: #include <a.out.h>
8: #include <stdio.h>
9:
10: struct ar_hdr archdr;
11: #define OARMAG 0177545
12: long arsize;
13: struct exec exp;
14: FILE *fi, *fo;
15: long off, oldoff;
16: long atol(), ftell();
17: #define TABSZ 5000
18: struct ranlib tab[TABSZ];
19: int tnum;
20: #define STRTABSZ 75000
21: char tstrtab[STRTABSZ];
22: int tssiz;
23: char *strtab;
24: int ssiz;
25: int new;
26: char tempnm[] = "__.SYMDEF";
27: char firstname[17];
28:
29: main(argc, argv)
30: char **argv;
31: {
32: char cmdbuf[BUFSIZ];
33: char magbuf[SARMAG+1];
34:
35: --argc;
36: while(argc--) {
37: fi = fopen(*++argv,"r");
38: if (fi == NULL) {
39: fprintf(stderr, "ranlib: cannot open %s\n", *argv);
40: continue;
41: }
42: off = SARMAG;
43: fread(magbuf, 1, SARMAG, fi);
44: if (strncmp(magbuf, ARMAG, SARMAG)) {
45: if (*(int *)magbuf == OARMAG)
46: fprintf(stderr, "old format ");
47: else
48: fprintf(stderr, "not an ");
49: fprintf(stderr, "archive: %s\n", *argv);
50: continue;
51: }
52: fseek(fi, 0L, 0);
53: new = tnum = 0;
54: if (nextel(fi) == 0) {
55: fclose(fi);
56: continue;
57: }
58: if(strncmp(archdr.ar_name, tempnm, strlen(tempnm)) == 0)
59: nextel(fi);
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: continue;
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)
122: sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm);
123: else
124: sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm);
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:
134: nextel(af)
135: FILE *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:
155: stash(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:
175: fixsize()
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 */
199: fixdate(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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.