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