Blame


1 76193d7c 2003-09-30 devnull #include "mk.h"
2 f84d54a0 2020-05-08 rsc #if defined(__AIX__)
3 f84d54a0 2020-05-08 rsc #define ARMAG "<bigaf>\n"
4 f84d54a0 2020-05-08 rsc #else
5 76193d7c 2003-09-30 devnull #define ARMAG "!<arch>\n"
6 f84d54a0 2020-05-08 rsc #endif
7 c65d1793 2020-01-08 crossd #define SARMAG (sizeof(ARMAG) - sizeof(""))
8 76193d7c 2003-09-30 devnull
9 76193d7c 2003-09-30 devnull #define ARFMAG "`\n"
10 76193d7c 2003-09-30 devnull #define SARNAME 16
11 76193d7c 2003-09-30 devnull
12 76193d7c 2003-09-30 devnull struct ar_hdr
13 76193d7c 2003-09-30 devnull {
14 76193d7c 2003-09-30 devnull char name[SARNAME];
15 76193d7c 2003-09-30 devnull char date[12];
16 76193d7c 2003-09-30 devnull char uid[6];
17 76193d7c 2003-09-30 devnull char gid[6];
18 76193d7c 2003-09-30 devnull char mode[8];
19 76193d7c 2003-09-30 devnull char size[10];
20 76193d7c 2003-09-30 devnull char fmag[2];
21 76193d7c 2003-09-30 devnull };
22 76193d7c 2003-09-30 devnull #define SAR_HDR (SARNAME+44)
23 76193d7c 2003-09-30 devnull
24 92a0a8b6 2004-04-21 devnull static int dolong = 1;
25 76193d7c 2003-09-30 devnull
26 76193d7c 2003-09-30 devnull static void atimes(char *);
27 76193d7c 2003-09-30 devnull static char *split(char*, char**);
28 76193d7c 2003-09-30 devnull
29 76193d7c 2003-09-30 devnull long
30 2b9172c7 2004-12-27 devnull readn(int f, void *av, long n)
31 2b9172c7 2004-12-27 devnull {
32 2b9172c7 2004-12-27 devnull char *a;
33 2b9172c7 2004-12-27 devnull long m, t;
34 2b9172c7 2004-12-27 devnull
35 2b9172c7 2004-12-27 devnull a = av;
36 2b9172c7 2004-12-27 devnull t = 0;
37 2b9172c7 2004-12-27 devnull while(t < n){
38 2b9172c7 2004-12-27 devnull m = read(f, a+t, n-t);
39 2b9172c7 2004-12-27 devnull if(m <= 0){
40 2b9172c7 2004-12-27 devnull if(t == 0)
41 2b9172c7 2004-12-27 devnull return m;
42 2b9172c7 2004-12-27 devnull break;
43 2b9172c7 2004-12-27 devnull }
44 2b9172c7 2004-12-27 devnull t += m;
45 2b9172c7 2004-12-27 devnull }
46 2b9172c7 2004-12-27 devnull return t;
47 2b9172c7 2004-12-27 devnull }
48 2b9172c7 2004-12-27 devnull long
49 76193d7c 2003-09-30 devnull atimeof(int force, char *name)
50 76193d7c 2003-09-30 devnull {
51 76193d7c 2003-09-30 devnull Symtab *sym;
52 76193d7c 2003-09-30 devnull long t;
53 76193d7c 2003-09-30 devnull char *archive, *member, buf[512];
54 76193d7c 2003-09-30 devnull
55 76193d7c 2003-09-30 devnull archive = split(name, &member);
56 76193d7c 2003-09-30 devnull if(archive == 0)
57 76193d7c 2003-09-30 devnull Exit();
58 76193d7c 2003-09-30 devnull
59 76193d7c 2003-09-30 devnull t = mtime(archive);
60 76193d7c 2003-09-30 devnull sym = symlook(archive, S_AGG, 0);
61 76193d7c 2003-09-30 devnull if(sym){
62 3fe9465a 2006-04-20 devnull if(force || (t > sym->u.value)){
63 76193d7c 2003-09-30 devnull atimes(archive);
64 3fe9465a 2006-04-20 devnull sym->u.value = t;
65 76193d7c 2003-09-30 devnull }
66 76193d7c 2003-09-30 devnull }
67 76193d7c 2003-09-30 devnull else{
68 76193d7c 2003-09-30 devnull atimes(archive);
69 76193d7c 2003-09-30 devnull /* mark the aggegate as having been done */
70 3fe9465a 2006-04-20 devnull symlook(strdup(archive), S_AGG, "")->u.value = t;
71 76193d7c 2003-09-30 devnull }
72 76193d7c 2003-09-30 devnull /* truncate long member name to sizeof of name field in archive header */
73 76193d7c 2003-09-30 devnull if(dolong)
74 76193d7c 2003-09-30 devnull snprint(buf, sizeof(buf), "%s(%s)", archive, member);
75 76193d7c 2003-09-30 devnull else
76 76193d7c 2003-09-30 devnull snprint(buf, sizeof(buf), "%s(%.*s)", archive, SARNAME, member);
77 76193d7c 2003-09-30 devnull sym = symlook(buf, S_TIME, 0);
78 76193d7c 2003-09-30 devnull if (sym)
79 3fe9465a 2006-04-20 devnull return sym->u.value;
80 76193d7c 2003-09-30 devnull return 0;
81 76193d7c 2003-09-30 devnull }
82 76193d7c 2003-09-30 devnull
83 76193d7c 2003-09-30 devnull void
84 76193d7c 2003-09-30 devnull atouch(char *name)
85 76193d7c 2003-09-30 devnull {
86 76193d7c 2003-09-30 devnull char *archive, *member;
87 76193d7c 2003-09-30 devnull int fd, i;
88 76193d7c 2003-09-30 devnull struct ar_hdr h;
89 76193d7c 2003-09-30 devnull long t;
90 76193d7c 2003-09-30 devnull
91 76193d7c 2003-09-30 devnull archive = split(name, &member);
92 76193d7c 2003-09-30 devnull if(archive == 0)
93 76193d7c 2003-09-30 devnull Exit();
94 76193d7c 2003-09-30 devnull
95 76193d7c 2003-09-30 devnull fd = open(archive, ORDWR);
96 76193d7c 2003-09-30 devnull if(fd < 0){
97 76193d7c 2003-09-30 devnull fd = create(archive, OWRITE, 0666);
98 76193d7c 2003-09-30 devnull if(fd < 0){
99 76193d7c 2003-09-30 devnull fprint(2, "create %s: %r\n", archive);
100 76193d7c 2003-09-30 devnull Exit();
101 76193d7c 2003-09-30 devnull }
102 76193d7c 2003-09-30 devnull write(fd, ARMAG, SARMAG);
103 76193d7c 2003-09-30 devnull }
104 76193d7c 2003-09-30 devnull if(symlook(name, S_TIME, 0)){
105 76193d7c 2003-09-30 devnull /* hoon off and change it in situ */
106 76193d7c 2003-09-30 devnull LSEEK(fd, SARMAG, 0);
107 76193d7c 2003-09-30 devnull while(read(fd, (char *)&h, sizeof(h)) == sizeof(h)){
108 76193d7c 2003-09-30 devnull for(i = SARNAME-1; i > 0 && h.name[i] == ' '; i--)
109 c65d1793 2020-01-08 crossd ;
110 76193d7c 2003-09-30 devnull h.name[i+1]=0;
111 76193d7c 2003-09-30 devnull if(strcmp(member, h.name) == 0){
112 76193d7c 2003-09-30 devnull t = SARNAME-sizeof(h); /* ughgghh */
113 76193d7c 2003-09-30 devnull LSEEK(fd, t, 1);
114 76193d7c 2003-09-30 devnull fprint(fd, "%-12ld", time(0));
115 76193d7c 2003-09-30 devnull break;
116 76193d7c 2003-09-30 devnull }
117 76193d7c 2003-09-30 devnull t = atol(h.size);
118 76193d7c 2003-09-30 devnull if(t&01) t++;
119 76193d7c 2003-09-30 devnull LSEEK(fd, t, 1);
120 76193d7c 2003-09-30 devnull }
121 76193d7c 2003-09-30 devnull }
122 76193d7c 2003-09-30 devnull close(fd);
123 c65d1793 2020-01-08 crossd }
124 c65d1793 2020-01-08 crossd
125 c65d1793 2020-01-08 crossd static int
126 c65d1793 2020-01-08 crossd allspaces(char *a, int n)
127 c65d1793 2020-01-08 crossd {
128 c65d1793 2020-01-08 crossd int i;
129 2738cc3c 2020-01-08 cross
130 2738cc3c 2020-01-08 cross for(i=0; i<n; i++)
131 2738cc3c 2020-01-08 cross if(a[i] != ' ')
132 c65d1793 2020-01-08 crossd return 0;
133 2738cc3c 2020-01-08 cross
134 c65d1793 2020-01-08 crossd return 1;
135 76193d7c 2003-09-30 devnull }
136 76193d7c 2003-09-30 devnull
137 76193d7c 2003-09-30 devnull static void
138 76193d7c 2003-09-30 devnull atimes(char *ar)
139 76193d7c 2003-09-30 devnull {
140 76193d7c 2003-09-30 devnull struct ar_hdr h;
141 76193d7c 2003-09-30 devnull long t;
142 d946e4dc 2004-04-21 devnull int fd, i, namelen;
143 d946e4dc 2004-04-21 devnull char buf[2048], *p, *strings;
144 d946e4dc 2004-04-21 devnull char name[1024];
145 d946e4dc 2004-04-21 devnull Symtab *sym;
146 76193d7c 2003-09-30 devnull
147 d946e4dc 2004-04-21 devnull strings = nil;
148 76193d7c 2003-09-30 devnull fd = open(ar, OREAD);
149 76193d7c 2003-09-30 devnull if(fd < 0)
150 76193d7c 2003-09-30 devnull return;
151 76193d7c 2003-09-30 devnull
152 76193d7c 2003-09-30 devnull if(read(fd, buf, SARMAG) != SARMAG){
153 76193d7c 2003-09-30 devnull close(fd);
154 76193d7c 2003-09-30 devnull return;
155 76193d7c 2003-09-30 devnull }
156 d946e4dc 2004-04-21 devnull while(readn(fd, (char *)&h, sizeof(h)) == sizeof(h)){
157 76193d7c 2003-09-30 devnull t = atol(h.date);
158 76193d7c 2003-09-30 devnull if(t == 0) /* as it sometimes happens; thanks ken */
159 76193d7c 2003-09-30 devnull t = 1;
160 d946e4dc 2004-04-21 devnull namelen = 0;
161 d946e4dc 2004-04-21 devnull if(memcmp(h.name, "#1/", 3) == 0){ /* BSD */
162 d946e4dc 2004-04-21 devnull namelen = atoi(h.name+3);
163 d946e4dc 2004-04-21 devnull if(namelen >= sizeof name){
164 d946e4dc 2004-04-21 devnull namelen = 0;
165 d946e4dc 2004-04-21 devnull goto skip;
166 d946e4dc 2004-04-21 devnull }
167 d946e4dc 2004-04-21 devnull if(readn(fd, name, namelen) != namelen)
168 d946e4dc 2004-04-21 devnull break;
169 d946e4dc 2004-04-21 devnull name[namelen] = 0;
170 c65d1793 2020-01-08 crossd }else if(memcmp(h.name, "// ", 3) == 0){ /* GNU */
171 d946e4dc 2004-04-21 devnull /* date, uid, gid, mode all ' ' */
172 c65d1793 2020-01-08 crossd if(!allspaces(&h.name[3], sizeof(h.name) - 3) ||
173 2738cc3c 2020-01-08 cross !allspaces(h.date, sizeof(h.date)) ||
174 2738cc3c 2020-01-08 cross !allspaces(h.uid, sizeof(h.uid)) ||
175 2738cc3c 2020-01-08 cross !allspaces(h.gid, sizeof(h.gid)) ||
176 2738cc3c 2020-01-08 cross !allspaces(h.mode, sizeof(h.mode)))
177 c65d1793 2020-01-08 crossd goto skip;
178 d946e4dc 2004-04-21 devnull t = atol(h.size);
179 d946e4dc 2004-04-21 devnull if(t&01)
180 d946e4dc 2004-04-21 devnull t++;
181 d946e4dc 2004-04-21 devnull free(strings);
182 d946e4dc 2004-04-21 devnull strings = malloc(t+1);
183 d946e4dc 2004-04-21 devnull if(strings){
184 d946e4dc 2004-04-21 devnull if(readn(fd, strings, t) != t){
185 d946e4dc 2004-04-21 devnull free(strings);
186 d946e4dc 2004-04-21 devnull strings = nil;
187 d946e4dc 2004-04-21 devnull break;
188 d946e4dc 2004-04-21 devnull }
189 d946e4dc 2004-04-21 devnull strings[t] = 0;
190 d946e4dc 2004-04-21 devnull continue;
191 d946e4dc 2004-04-21 devnull }
192 d946e4dc 2004-04-21 devnull goto skip;
193 74374cc8 2005-10-31 devnull }else if(strings && h.name[0]=='/' && isdigit((uchar)h.name[1])){
194 d946e4dc 2004-04-21 devnull i = strtol(h.name+1, &p, 10);
195 92a0a8b6 2004-04-21 devnull if(*p != ' ' || i >= strlen(strings))
196 d946e4dc 2004-04-21 devnull goto skip;
197 d946e4dc 2004-04-21 devnull p = strings+i;
198 d946e4dc 2004-04-21 devnull for(; *p && *p != '/'; p++)
199 76193d7c 2003-09-30 devnull ;
200 d946e4dc 2004-04-21 devnull namelen = p-(strings+i);
201 d946e4dc 2004-04-21 devnull if(namelen >= sizeof name){
202 d946e4dc 2004-04-21 devnull namelen = 0;
203 d946e4dc 2004-04-21 devnull goto skip;
204 d946e4dc 2004-04-21 devnull }
205 d946e4dc 2004-04-21 devnull memmove(name, strings+i, namelen);
206 d946e4dc 2004-04-21 devnull name[namelen] = 0;
207 d946e4dc 2004-04-21 devnull namelen = 0;
208 d946e4dc 2004-04-21 devnull }else{
209 fafa622a 2020-01-12 rsc memmove(name, h.name, sizeof(h.name));
210 d946e4dc 2004-04-21 devnull for(i = sizeof(h.name)-1; i > 0 && name[i] == ' '; i--)
211 c65d1793 2020-01-08 crossd ;
212 d946e4dc 2004-04-21 devnull if(name[i] == '/') /* system V bug */
213 d946e4dc 2004-04-21 devnull i--;
214 d946e4dc 2004-04-21 devnull name[i+1]=0;
215 d946e4dc 2004-04-21 devnull }
216 a29753a1 2004-04-21 devnull snprint(buf, sizeof buf, "%s(%s)", ar, name);
217 d946e4dc 2004-04-21 devnull sym = symlook(strdup(buf), S_TIME, (void *)t);
218 3fe9465a 2006-04-20 devnull sym->u.value = t;
219 d946e4dc 2004-04-21 devnull skip:
220 76193d7c 2003-09-30 devnull t = atol(h.size);
221 76193d7c 2003-09-30 devnull if(t&01) t++;
222 d946e4dc 2004-04-21 devnull t -= namelen;
223 76193d7c 2003-09-30 devnull LSEEK(fd, t, 1);
224 76193d7c 2003-09-30 devnull }
225 76193d7c 2003-09-30 devnull close(fd);
226 d946e4dc 2004-04-21 devnull free(strings);
227 76193d7c 2003-09-30 devnull }
228 76193d7c 2003-09-30 devnull
229 76193d7c 2003-09-30 devnull static int
230 76193d7c 2003-09-30 devnull type(char *file)
231 76193d7c 2003-09-30 devnull {
232 76193d7c 2003-09-30 devnull int fd;
233 76193d7c 2003-09-30 devnull char buf[SARMAG];
234 76193d7c 2003-09-30 devnull
235 76193d7c 2003-09-30 devnull fd = open(file, OREAD);
236 76193d7c 2003-09-30 devnull if(fd < 0){
237 76193d7c 2003-09-30 devnull if(symlook(file, S_BITCH, 0) == 0){
238 3842363a 2005-02-02 devnull if(strlen(file) < 2 || strcmp(file+strlen(file)-2, ".a") != 0)
239 3842363a 2005-02-02 devnull Bprint(&bout, "%s doesn't exist: assuming it will be an archive\n", file);
240 76193d7c 2003-09-30 devnull symlook(file, S_BITCH, (void *)file);
241 76193d7c 2003-09-30 devnull }
242 76193d7c 2003-09-30 devnull return 1;
243 76193d7c 2003-09-30 devnull }
244 76193d7c 2003-09-30 devnull if(read(fd, buf, SARMAG) != SARMAG){
245 76193d7c 2003-09-30 devnull close(fd);
246 76193d7c 2003-09-30 devnull return 0;
247 76193d7c 2003-09-30 devnull }
248 76193d7c 2003-09-30 devnull close(fd);
249 76193d7c 2003-09-30 devnull return !strncmp(ARMAG, buf, SARMAG);
250 76193d7c 2003-09-30 devnull }
251 76193d7c 2003-09-30 devnull
252 76193d7c 2003-09-30 devnull static char*
253 76193d7c 2003-09-30 devnull split(char *name, char **member)
254 76193d7c 2003-09-30 devnull {
255 76193d7c 2003-09-30 devnull char *p, *q;
256 76193d7c 2003-09-30 devnull
257 76193d7c 2003-09-30 devnull p = strdup(name);
258 76193d7c 2003-09-30 devnull q = utfrune(p, '(');
259 76193d7c 2003-09-30 devnull if(q){
260 76193d7c 2003-09-30 devnull *q++ = 0;
261 76193d7c 2003-09-30 devnull if(member)
262 76193d7c 2003-09-30 devnull *member = q;
263 76193d7c 2003-09-30 devnull q = utfrune(q, ')');
264 76193d7c 2003-09-30 devnull if (q)
265 76193d7c 2003-09-30 devnull *q = 0;
266 76193d7c 2003-09-30 devnull if(type(p))
267 76193d7c 2003-09-30 devnull return p;
268 76193d7c 2003-09-30 devnull free(p);
269 76193d7c 2003-09-30 devnull fprint(2, "mk: '%s' is not an archive\n", name);
270 76193d7c 2003-09-30 devnull }
271 76193d7c 2003-09-30 devnull return 0;
272 76193d7c 2003-09-30 devnull }