Research V7 development
[unix-history] / usr / src / cmd / ranlib.c
CommitLineData
9743b07e
KT
1#include <ar.h>
2#include <a.out.h>
3#include <stdio.h>
4#define MAGIC exp.a_magic
5#define BADMAG MAGIC!=A_MAGIC1 && MAGIC!=A_MAGIC2 \
6 && MAGIC!=A_MAGIC3 && MAGIC!=A_MAGIC4
7struct ar_hdr arp;
8struct exec exp;
9FILE *fi, *fo;
10long off, oldoff;
11long ftell();
12#define TABSZ 700
13struct tab
14{ char cname[8];
15 long cloc;
16} tab[TABSZ];
17int tnum;
18int new;
19char tempnm[] = "__.SYMDEF";
20char firstname[17];
21long offdelta;
22
23main(argc, argv)
24char **argv;
25{
26 char buf[256];
27
28 --argc;
29 while(argc--) {
30 fi = fopen(*++argv,"r");
31 if (fi == NULL) {
32 fprintf(stderr, "nm: cannot open %s\n", *argv);
33 continue;
34 }
35 off = sizeof(exp.a_magic);
36 fread((char *)&exp, 1, sizeof(MAGIC), fi); /* get magic no. */
37 if (MAGIC != ARMAG)
38 { fprintf(stderr, "not archive: %s\n", *argv);
39 continue;
40 }
41 fseek(fi, 0L, 0);
42 new = tnum = 0;
43 if(nextel(fi) == 0)
44 { fclose(fi);
45 continue;
46 }
47 do {
48 long o;
49 register n;
50 struct nlist sym;
51
52 fread((char *)&exp, 1, sizeof(struct exec), fi);
53 if (BADMAG) /* archive element not in */
54 continue; /* proper format - skip it */
55 o = (long)exp.a_text + exp.a_data;
56 if ((exp.a_flag & 01) == 0)
57 o *= 2;
58 fseek(fi, o, 1);
59 n = exp.a_syms / sizeof(struct nlist);
60 if (n == 0) {
61 fprintf(stderr, "nm: %s-- no name list\n", arp.ar_name);
62 continue;
63 }
64 while (--n >= 0) {
65 fread((char *)&sym, 1, sizeof(sym), fi);
66 if ((sym.n_type&N_EXT)==0)
67 continue;
68 switch (sym.n_type&N_TYPE) {
69
70 case N_UNDF:
71 continue;
72
73 default:
74 stash(&sym);
75 continue;
76 }
77 }
78 } while(nextel(fi));
79 new = fixsize();
80 fclose(fi);
81 fo = fopen(tempnm, "w");
82 if(fo == NULL)
83 { fprintf(stderr, "can't create temporary\n");
84 exit(1);
85 }
86 fwrite((char *)tab, tnum, sizeof(struct tab), fo);
87 fclose(fo);
88 if(new)
89 sprintf(buf, "ar rlb %s %s %s\n", firstname, *argv, tempnm);
90 else sprintf(buf, "ar rl %s %s\n", *argv, tempnm);
91 if(system(buf))
92 fprintf(stderr, "can't execute %s\n", buf);
93 else fixdate(*argv);
94 unlink(tempnm);
95 }
96 exit(0);
97}
98
99nextel(af)
100FILE *af;
101{
102 register r;
103
104 oldoff = off;
105 fseek(af, off, 0);
106 r = fread((char *)&arp, 1, sizeof(struct ar_hdr), af); /* read archive header */
107 if (r <= 0)
108 return(0);
109 if (arp.ar_size & 1)
110 ++arp.ar_size;
111 off = ftell(af) + arp.ar_size; /* offset to next element */
112 return(1);
113}
114
115stash(s) struct nlist *s;
116{ int i;
117 if(tnum >= TABSZ)
118 { fprintf(stderr, "symbol table overflow\n");
119 exit(1);
120 }
121 for(i=0; i<8; i++)
122 tab[tnum].cname[i] = s->n_name[i];
123 tab[tnum].cloc = oldoff;
124 tnum++;
125}
126
127fixsize()
128{ int i;
129 offdelta = tnum * sizeof(struct tab) + sizeof(arp);
130 off = sizeof(MAGIC);
131 nextel(fi);
132 if(strncmp(arp.ar_name, tempnm, 14) == 0)
133 { new = 0;
134 offdelta -= sizeof(arp) + arp.ar_size;
135 }
136 else
137 { new = 1;
138 strncpy(firstname, arp.ar_name, 14);
139 }
140 for(i=0; i<tnum; i++)
141 tab[i].cloc += offdelta;
142 return(new);
143}
144
145/* patch time */
146fixdate(s) char *s;
147{ long timex, time();
148 int fd;
149 fd = open(s, 1);
150 if(fd < 0)
151 { fprintf(stderr, "can't reopen %s\n", s);
152 return;
153 }
154 timex = time(NULL) + 5; /* should be enough time */
155 lseek(fd, (long)sizeof(exp.a_magic) + ((char *)&arp.ar_date-(char *)&arp), 0);
156 write(fd, (char *)&timex, sizeof(timex));
157 close(fd);
158}