xref: /inferno-os/utils/mk/archive-AIX.c (revision 871e0f01ca6cdef953c81d1a5018d90fbd01838a)
1 #include	"mk.h"
2 #include	<ar.h>
3 
4 static int dolong;
5 
6 static void atimes(char *);
7 static char *split(char*, char**);
8 
9 long
10 atimeof(int force, char *name)
11 {
12 	Symtab *sym;
13 	long t;
14 	char *archive, *member, buf[512];
15 
16 	archive = split(name, &member);
17 	if(archive == 0)
18 		Exit();
19 
20 	t = mtime(archive);
21 	sym = symlook(archive, S_AGG, 0);
22 	if(sym){
23 		if(force || (t > (long)sym->value)){
24 			atimes(archive);
25 			sym->value = (void *)t;
26 		}
27 	}
28 	else{
29 		atimes(archive);
30 		/* mark the aggegate as having been done */
31 		symlook(strdup(archive), S_AGG, "")->value = (void *)t;
32 	}
33 	snprint(buf, sizeof(buf), "%s(%s)", archive, member);
34 	sym = symlook(buf, S_TIME, 0);
35 	if (sym)
36 		return (long)sym->value;	/* uggh */
37 	return 0;
38 }
39 
40 void
41 atouch(char *name)
42 {
43 	char *archive, *member;
44 	int fd, i, namelen;
45 	struct fl_hdr g;
46 	struct ar_hdr h;
47 	long t;
48 	char memname[256];
49 
50 	archive = split(name, &member);
51 	if(archive == 0)
52 		Exit();
53 
54 	fd = open(archive, ORDWR);
55 	if(fd < 0){
56 		fd = create(archive, OWRITE, 0666);
57 		if(fd < 0){
58 			perror(archive);
59 			Exit();
60 		}
61 		write(fd, ARMAG, SARMAG);
62 		for(i = 0; i < 6; i++)
63 			fprint(fd, "%-20ld", 0);
64 	}
65 	if(symlook(name, S_TIME, 0)){
66 		/* hoon off and change it in situ */
67 		LSEEK(fd, 0, 0);
68 		if(read(fd, &g, SAR_FLHDR) != SAR_FLHDR){
69 			close(fd);
70 			return;
71 		}
72 		t = atol(g.fstmoff);
73 		if(t == 0){
74 			close(fd);
75 			return;
76 		}
77 		for(;;){
78 			LSEEK(fd, t, 0);
79 			if(read(fd, (char *)&h, SAR_HDR) != SAR_HDR)
80 				break;
81 
82 			namelen = atol(h.namlen);
83 			if(namelen == 0 || namelen >= sizeof memname){
84 				namelen = 0;
85 				goto skip;
86 			}
87 			if(read(fd, memname, namelen) != namelen)
88 				break;
89 			memname[namelen] = 0;
90 
91 			if(strcmp(member, memname) == 0){
92 				snprint(h.date, sizeof(h.date), "%-12ld", time(0));
93 				LSEEK(fd, t, 0);
94 				write(fd, (char *)&h, SAR_HDR);
95 				break;
96 			}
97 		skip:
98 			t = atol(h.nxtmem);
99 			if(t == 0)
100 				break;
101 		}
102 	}
103 	close(fd);
104 }
105 
106 static void
107 atimes(char *ar)
108 {
109 	struct fl_hdr g;
110 	struct ar_hdr h;
111 	long o, t;
112 	int fd, i, namelen;
113 	char buf[2048], *p, *strings;
114 	char name[1024];
115 	Symtab *sym;
116 
117 	strings = nil;
118 	fd = open(ar, OREAD);
119 	if(fd < 0)
120 		return;
121 
122 	if(read(fd, &g, SAR_FLHDR) != SAR_FLHDR){
123 		close(fd);
124 		return;
125 	}
126 	o = atol(g.fstmoff);
127 	if(o == 0){
128 		close(fd);
129 		return;
130 	}
131 	for(;;){
132 		LSEEK(fd, o, 0);
133 		if(read(fd, (char *)&h, SAR_HDR) != SAR_HDR)
134 			break;
135 
136 		t = atol(h.date);
137 		if(t == 0)	/* as it sometimes happens; thanks ken */
138 			t = 1;
139 
140 		namelen = atol(h.namlen);
141 		if(namelen == 0 || namelen >= sizeof name){
142 			namelen = 0;
143 			goto skip;
144 		}
145 		if(read(fd, name, namelen) != namelen)
146 			break;
147 		name[namelen] = 0;
148 
149 		snprint(buf, sizeof buf, "%s(%s)", ar, name);
150 		sym = symlook(strdup(buf), S_TIME, (void *)t);
151 		sym->value = (void *)t;
152 	skip:
153 		o = atol(h.nxtmem);
154 		if(o == 0)
155 			break;
156 	}
157 	close(fd);
158 	free(strings);
159 }
160 
161 static int
162 type(char *file)
163 {
164 	int fd;
165 	char buf[SARMAG];
166 
167 	fd = open(file, OREAD);
168 	if(fd < 0){
169 		if(symlook(file, S_BITCH, 0) == 0){
170 			Bprint(&bout, "%s doesn't exist: assuming it will be an archive\n", file);
171 			symlook(file, S_BITCH, (void *)file);
172 		}
173 		return 1;
174 	}
175 	if(read(fd, buf, SARMAG) != SARMAG){
176 		close(fd);
177 		return 0;
178 	}
179 	close(fd);
180 	return strncmp(ARMAG, buf, SARMAG) == 0;
181 }
182 
183 static char*
184 split(char *name, char **member)
185 {
186 	char *p, *q;
187 
188 	p = strdup(name);
189 	q = utfrune(p, '(');
190 	if(q){
191 		*q++ = 0;
192 		if(member)
193 			*member = q;
194 		q = utfrune(q, ')');
195 		if (q)
196 			*q = 0;
197 		if(type(p))
198 			return p;
199 		free(p);
200 		fprint(2, "mk: '%s' is not an archive\n", name);
201 	}
202 	return 0;
203 }
204