#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(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;
}
