xref: /plan9/sys/src/cmd/mk/archive.c (revision 7f49a7ff54b1fd29a638d67350c7ceb952fbe2d6)
17dd7cddfSDavid du Colombier #include	"mk.h"
27dd7cddfSDavid du Colombier #include	<ar.h>
37dd7cddfSDavid du Colombier 
47dd7cddfSDavid du Colombier static void atimes(char *);
57dd7cddfSDavid du Colombier static char *split(char*, char**);
67dd7cddfSDavid du Colombier 
7*7f49a7ffSDavid du Colombier ulong
atimeof(int force,char * name)87dd7cddfSDavid du Colombier atimeof(int force, char *name)
97dd7cddfSDavid du Colombier {
107dd7cddfSDavid du Colombier 	Symtab *sym;
11*7f49a7ffSDavid du Colombier 	ulong t;
127dd7cddfSDavid du Colombier 	char *archive, *member, buf[512];
137dd7cddfSDavid du Colombier 
147dd7cddfSDavid du Colombier 	archive = split(name, &member);
157dd7cddfSDavid du Colombier 	if(archive == 0)
167dd7cddfSDavid du Colombier 		Exit();
177dd7cddfSDavid du Colombier 
187dd7cddfSDavid du Colombier 	t = mtime(archive);
197dd7cddfSDavid du Colombier 	sym = symlook(archive, S_AGG, 0);
207dd7cddfSDavid du Colombier 	if(sym){
214de34a7eSDavid du Colombier 		if(force || t > sym->u.value){
227dd7cddfSDavid du Colombier 			atimes(archive);
234de34a7eSDavid du Colombier 			sym->u.value = t;
247dd7cddfSDavid du Colombier 		}
257dd7cddfSDavid du Colombier 	}
267dd7cddfSDavid du Colombier 	else{
277dd7cddfSDavid du Colombier 		atimes(archive);
287dd7cddfSDavid du Colombier 		/* mark the aggegate as having been done */
294de34a7eSDavid du Colombier 		symlook(strdup(archive), S_AGG, "")->u.value = t;
307dd7cddfSDavid du Colombier 	}
317dd7cddfSDavid du Colombier 		/* truncate long member name to sizeof of name field in archive header */
3259cc4ca5SDavid du Colombier 	snprint(buf, sizeof(buf), "%s(%.*s)", archive, utfnlen(member, SARNAME), member);
337dd7cddfSDavid du Colombier 	sym = symlook(buf, S_TIME, 0);
347dd7cddfSDavid du Colombier 	if (sym)
354de34a7eSDavid du Colombier 		return sym->u.value;
367dd7cddfSDavid du Colombier 	return 0;
377dd7cddfSDavid du Colombier }
387dd7cddfSDavid du Colombier 
397dd7cddfSDavid du Colombier void
atouch(char * name)407dd7cddfSDavid du Colombier atouch(char *name)
417dd7cddfSDavid du Colombier {
427dd7cddfSDavid du Colombier 	char *archive, *member;
437dd7cddfSDavid du Colombier 	int fd, i;
447dd7cddfSDavid du Colombier 	struct ar_hdr h;
457dd7cddfSDavid du Colombier 	long t;
467dd7cddfSDavid du Colombier 
477dd7cddfSDavid du Colombier 	archive = split(name, &member);
487dd7cddfSDavid du Colombier 	if(archive == 0)
497dd7cddfSDavid du Colombier 		Exit();
507dd7cddfSDavid du Colombier 
517dd7cddfSDavid du Colombier 	fd = open(archive, ORDWR);
527dd7cddfSDavid du Colombier 	if(fd < 0){
537dd7cddfSDavid du Colombier 		fd = create(archive, OWRITE, 0666);
547dd7cddfSDavid du Colombier 		if(fd < 0){
557dd7cddfSDavid du Colombier 			perror(archive);
567dd7cddfSDavid du Colombier 			Exit();
577dd7cddfSDavid du Colombier 		}
587dd7cddfSDavid du Colombier 		write(fd, ARMAG, SARMAG);
597dd7cddfSDavid du Colombier 	}
607dd7cddfSDavid du Colombier 	if(symlook(name, S_TIME, 0)){
617dd7cddfSDavid du Colombier 		/* hoon off and change it in situ */
627dd7cddfSDavid du Colombier 		LSEEK(fd, SARMAG, 0);
637dd7cddfSDavid du Colombier 		while(read(fd, (char *)&h, sizeof(h)) == sizeof(h)){
647dd7cddfSDavid du Colombier 			for(i = SARNAME-1; i > 0 && h.name[i] == ' '; i--)
657dd7cddfSDavid du Colombier 					;
667dd7cddfSDavid du Colombier 			h.name[i+1]=0;
677dd7cddfSDavid du Colombier 			if(strcmp(member, h.name) == 0){
687dd7cddfSDavid du Colombier 				t = SARNAME-sizeof(h);	/* ughgghh */
697dd7cddfSDavid du Colombier 				LSEEK(fd, t, 1);
707dd7cddfSDavid du Colombier 				fprint(fd, "%-12ld", time(0));
717dd7cddfSDavid du Colombier 				break;
727dd7cddfSDavid du Colombier 			}
737dd7cddfSDavid du Colombier 			t = atol(h.size);
747dd7cddfSDavid du Colombier 			if(t&01) t++;
757dd7cddfSDavid du Colombier 			LSEEK(fd, t, 1);
767dd7cddfSDavid du Colombier 		}
777dd7cddfSDavid du Colombier 	}
787dd7cddfSDavid du Colombier 	close(fd);
797dd7cddfSDavid du Colombier }
807dd7cddfSDavid du Colombier 
817dd7cddfSDavid du Colombier static void
atimes(char * ar)827dd7cddfSDavid du Colombier atimes(char *ar)
837dd7cddfSDavid du Colombier {
847dd7cddfSDavid du Colombier 	struct ar_hdr h;
85*7f49a7ffSDavid du Colombier 	ulong at, t;
867dd7cddfSDavid du Colombier 	int fd, i;
877dd7cddfSDavid du Colombier 	char buf[BIGBLOCK];
884de34a7eSDavid du Colombier 	Dir *d;
897dd7cddfSDavid du Colombier 
907dd7cddfSDavid du Colombier 	fd = open(ar, OREAD);
917dd7cddfSDavid du Colombier 	if(fd < 0)
927dd7cddfSDavid du Colombier 		return;
937dd7cddfSDavid du Colombier 
947dd7cddfSDavid du Colombier 	if(read(fd, buf, SARMAG) != SARMAG){
957dd7cddfSDavid du Colombier 		close(fd);
967dd7cddfSDavid du Colombier 		return;
977dd7cddfSDavid du Colombier 	}
984de34a7eSDavid du Colombier 	if((d = dirfstat(fd)) == nil){
994de34a7eSDavid du Colombier 		close(fd);
1004de34a7eSDavid du Colombier 		return;
1014de34a7eSDavid du Colombier 	}
1024de34a7eSDavid du Colombier 	at = d->mtime;
1034de34a7eSDavid du Colombier 	free(d);
1049b7bf7dfSDavid du Colombier 	while(read(fd, (char *)&h, SAR_HDR) == SAR_HDR){
105*7f49a7ffSDavid du Colombier 		t = strtoul(h.date, nil, 0);
1064de34a7eSDavid du Colombier 		if(t >= at)	/* new things in old archives confuses mk */
1074de34a7eSDavid du Colombier 			t = at-1;
108*7f49a7ffSDavid du Colombier 		if(t == 0)	/* as it sometimes happens; thanks ken */
1097dd7cddfSDavid du Colombier 			t = 1;
1107dd7cddfSDavid du Colombier 		for(i = sizeof(h.name)-1; i > 0 && h.name[i] == ' '; i--)
1117dd7cddfSDavid du Colombier 			;
1127dd7cddfSDavid du Colombier 		if(h.name[i] == '/')		/* system V bug */
1137dd7cddfSDavid du Colombier 			i--;
1147dd7cddfSDavid du Colombier 		h.name[i+1]=0;		/* can stomp on date field */
115d1da931cSDavid du Colombier 		snprint(buf, sizeof buf, "%s(%s)", ar, h.name);
1164de34a7eSDavid du Colombier 		symlook(strdup(buf), S_TIME, (void*)t)->u.value = t;
1177dd7cddfSDavid du Colombier 		t = atol(h.size);
1187dd7cddfSDavid du Colombier 		if(t&01) t++;
1197dd7cddfSDavid du Colombier 		LSEEK(fd, t, 1);
1207dd7cddfSDavid du Colombier 	}
1217dd7cddfSDavid du Colombier 	close(fd);
1227dd7cddfSDavid du Colombier }
1237dd7cddfSDavid du Colombier 
1247dd7cddfSDavid du Colombier static int
type(char * file)1257dd7cddfSDavid du Colombier type(char *file)
1267dd7cddfSDavid du Colombier {
1277dd7cddfSDavid du Colombier 	int fd;
1287dd7cddfSDavid du Colombier 	char buf[SARMAG];
1297dd7cddfSDavid du Colombier 
1307dd7cddfSDavid du Colombier 	fd = open(file, OREAD);
1317dd7cddfSDavid du Colombier 	if(fd < 0){
1327dd7cddfSDavid du Colombier 		if(symlook(file, S_BITCH, 0) == 0){
1337dd7cddfSDavid du Colombier 			Bprint(&bout, "%s doesn't exist: assuming it will be an archive\n", file);
1347dd7cddfSDavid du Colombier 			symlook(file, S_BITCH, (void *)file);
1357dd7cddfSDavid du Colombier 		}
1367dd7cddfSDavid du Colombier 		return 1;
1377dd7cddfSDavid du Colombier 	}
1387dd7cddfSDavid du Colombier 	if(read(fd, buf, SARMAG) != SARMAG){
1397dd7cddfSDavid du Colombier 		close(fd);
1407dd7cddfSDavid du Colombier 		return 0;
1417dd7cddfSDavid du Colombier 	}
1427dd7cddfSDavid du Colombier 	close(fd);
143*7f49a7ffSDavid du Colombier 	return strncmp(ARMAG, buf, SARMAG) == 0;
1447dd7cddfSDavid du Colombier }
1457dd7cddfSDavid du Colombier 
1467dd7cddfSDavid du Colombier static char*
split(char * name,char ** member)1477dd7cddfSDavid du Colombier split(char *name, char **member)
1487dd7cddfSDavid du Colombier {
1497dd7cddfSDavid du Colombier 	char *p, *q;
1507dd7cddfSDavid du Colombier 
1517dd7cddfSDavid du Colombier 	p = strdup(name);
1527dd7cddfSDavid du Colombier 	q = utfrune(p, '(');
1537dd7cddfSDavid du Colombier 	if(q){
1547dd7cddfSDavid du Colombier 		*q++ = 0;
1557dd7cddfSDavid du Colombier 		if(member)
1567dd7cddfSDavid du Colombier 			*member = q;
1577dd7cddfSDavid du Colombier 		q = utfrune(q, ')');
1587dd7cddfSDavid du Colombier 		if (q)
1597dd7cddfSDavid du Colombier 			*q = 0;
1607dd7cddfSDavid du Colombier 		if(type(p))
1617dd7cddfSDavid du Colombier 			return p;
1627dd7cddfSDavid du Colombier 		free(p);
1637dd7cddfSDavid du Colombier 		fprint(2, "mk: '%s' is not an archive\n", name);
1647dd7cddfSDavid du Colombier 	}
1657dd7cddfSDavid du Colombier 	return 0;
1667dd7cddfSDavid du Colombier }
167