#include	"mk.h"
#define	ARMAG	"!<arch>\n"
#define	SARMAG	8

#define	ARFMAG	"`\n"
#define SARNAME	16

struct	ar_hdr
{
	char	name[SARNAME];
	char	date[12];
	char	uid[6];
	char	gid[6];
	char	mode[8];
	char	size[10];
	char	fmag[2];
};
#define	SAR_HDR	(SARNAME+44)

static int dolong = 1;

static void atimes(char *);
static char *split(char*, char**);

long
readn(int f, void *av, long n)
{
	char *a;
	long m, t;

	a = av;
	t = 0;
	while(t < n){
		m = read(f, a+t, n-t);
		if(m <= 0){
			if(t == 0)
				return m;
			break;
		}
		t += m;
	}
	return t;
}
long
atimeof(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;
}

void
atouch(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){
			fprint(2, "create %s: %r\n", 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 void
atimes(char *ar)
{
	struct ar_hdr h;
	long t;
	int fd, i, namelen;
	char buf[2048], *p, *strings;
	char name[1024];
	Symtab *sym;

	strings = nil;
	fd = open(ar, OREAD);
	if(fd < 0)
		return;

	if(read(fd, buf, SARMAG) != SARMAG){
		close(fd);
		return;
	}
	while(readn(fd, (char *)&h, sizeof(h)) == sizeof(h)){
		t = atol(h.date);
		if(t == 0)	/* as it sometimes happens; thanks ken */
			t = 1;
		namelen = 0;
		if(memcmp(h.name, "#1/", 3) == 0){	/* BSD */
			namelen = atoi(h.name+3);
			if(namelen >= sizeof name){
				namelen = 0;
				goto skip;
			}
			if(readn(fd, name, namelen) != namelen)
				break;
			name[namelen] = 0;
		}else if(memcmp(h.name, "// ", 2) == 0){ /* GNU */
			/* date, uid, gid, mode all ' ' */
			for(i=2; i<16+12+6+6+8; i++)
				if(h.name[i] != ' ')
					goto skip;
			t = atol(h.size);
			if(t&01)
				t++;
			free(strings);
			strings = malloc(t+1);
			if(strings){
				if(readn(fd, strings, t) != t){
					free(strings);
					strings = nil;
					break;
				}
				strings[t] = 0;
				continue;
			}
			goto skip;
		}else if(strings && h.name[0]=='/' && isdigit((uchar)h.name[1])){
			i = strtol(h.name+1, &p, 10);
			if(*p != ' ' || i >= strlen(strings))
				goto skip;
			p = strings+i;
			for(; *p && *p != '/'; p++)
				;
			namelen = p-(strings+i);
			if(namelen >= sizeof name){
				namelen = 0;
				goto skip;
			}
			memmove(name, strings+i, namelen);
			name[namelen] = 0;
			namelen = 0;
		}else{
			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;
		}
		snprint(buf, sizeof buf, "%s(%s)", ar, name);
		sym = symlook(strdup(buf), S_TIME, (void *)t);
		sym->value = (void *)t;
	skip:
		t = atol(h.size);
		if(t&01) t++;
		t -= namelen;
		LSEEK(fd, t, 1);
	}
	close(fd);
	free(strings);
}

static int
type(char *file)
{
	int fd;
	char buf[SARMAG];

	fd = open(file, OREAD);
	if(fd < 0){
		if(symlook(file, S_BITCH, 0) == 0){
			if(strlen(file) < 2 || strcmp(file+strlen(file)-2, ".a") != 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;
}
