Charles.Forsyth20060303644188019 years agoHistory
169 lines · 3.1 KB · C
RawDownload
#include	"mk.h"#include	<ar.h> static int dolong; static void atimes(char *);static char *split(char*, char**); longatimeof(int force, char *name){	Symtab *sym;	long t;	char *archive, *member, buf[512]; 	archive = split(name, &member);	if(archive == 0)		Exit(); 	t = mtime(archive);	sym = symlook(archive, S_AGG, 0);	if(sym){		if(force || (t > (long)sym->value)){			atimes(archive);			sym->value = (void *)t;		}	}	else{		atimes(archive);		/* mark the aggegate as having been done */		symlook(strdup(archive), S_AGG, "")->value = (void *)t;	}		/* truncate long member name to sizeof of name field in archive header */	if(dolong)		snprint(buf, sizeof(buf), "%s(%s)", archive, member);	else		snprint(buf, sizeof(buf), "%s(%.*s)", archive, SARNAME, member);	sym = symlook(buf, S_TIME, 0);	if (sym)		return (long)sym->value;	/* uggh */	return 0;} voidatouch(char *name){	char *archive, *member;	int fd, i;	struct ar_hdr h;	long t; 	archive = split(name, &member);	if(archive == 0)		Exit(); 	fd = open(archive, ORDWR);	if(fd < 0){		fd = create(archive, OWRITE, 0666);		if(fd < 0){			perror(archive);			Exit();		}		write(fd, ARMAG, SARMAG);	}	if(symlook(name, S_TIME, 0)){		/* hoon off and change it in situ */		LSEEK(fd, SARMAG, 0);		while(read(fd, (char *)&h, sizeof(h)) == sizeof(h)){			for(i = SARNAME-1; i > 0 && h.name[i] == ' '; i--)					;			h.name[i+1]=0;			if(strcmp(member, h.name) == 0){				t = SARNAME-sizeof(h);	/* ughgghh */				LSEEK(fd, t, 1);				fprint(fd, "%-12ld", time(0));				break;			}			t = atol(h.size);			if(t&01) t++;			LSEEK(fd, t, 1);		}	}	close(fd);} static voidatimes(char *ar){	struct ar_hdr h;	long t;	int fd, i;	char buf[BIGBLOCK];	char *n, name[sizeof(h.name)+1]; 	fd = open(ar, OREAD);	if(fd < 0)		return; 	if(read(fd, buf, SARMAG) != SARMAG){		close(fd);		return;	}	while(read(fd, (char *)&h, sizeof(h)) == sizeof(h)){		t = atol(h.date);		if(t == 0)	/* as it sometimes happens; thanks ken */			t = 1;		strncpy(name, h.name, sizeof(h.name));		for(i = sizeof(h.name)-1; i > 0 && name[i] == ' '; i--)				;		if(name[i] == '/')		/* system V bug */			i--;		name[i+1]=0;		n = membername(name, fd, h.size);		if(n == nil){			dolong = 1;			continue;		}		sprint(buf, "%s(%s)", ar, n);		symlook(strdup(buf), S_TIME, (void *)t)->value = (void *)t;		t = atol(h.size);		if(t&01) t++;		LSEEK(fd, t, 1);	}	close(fd);} static inttype(char *file){	int fd;	char buf[SARMAG]; 	fd = open(file, OREAD);	if(fd < 0){		if(symlook(file, S_BITCH, 0) == 0){			Bprint(&bout, "%s doesn't exist: assuming it will be an archive\n", file);			symlook(file, S_BITCH, (void *)file);		}		return 1;	}	if(read(fd, buf, SARMAG) != SARMAG){		close(fd);		return 0;	}	close(fd);	return !strncmp(ARMAG, buf, SARMAG);} static char*split(char *name, char **member){	char *p, *q; 	p = strdup(name);	q = utfrune(p, '(');	if(q){		*q++ = 0;		if(member)			*member = q;		q = utfrune(q, ')');		if (q)			*q = 0;		if(type(p))			return p;		free(p);		fprint(2, "mk: '%s' is not an archive\n", name);	}	return 0;}