// Inferno utils/iar/ar.c
// http://code.google.com/p/inferno-os/source/browse/utils/iar/ar.c
//
//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
//	Portions Copyright © 1997-1999 Vita Nuova Limited
//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
//	Portions Copyright © 2004,2006 Bruce Ellis
//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
//	Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

/*
 * ar - portable (ascii) format version
 */

/* protect a couple of our names */
#define select your_select
#define rcmd your_rcmd

#include <u.h>
#include <time.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#include "../../libmach/obj.h"
#include <ar.h>

#undef select
#undef rcmd

/*
 *	The algorithm uses up to 3 temp files.  The "pivot member" is the
 *	archive member specified by and a, b, or i option.  The temp files are
 *	astart - contains existing members up to and including the pivot member.
 *	amiddle - contains new files moved or inserted behind the pivot.
 *	aend - contains the existing members that follow the pivot member.
 *	When all members have been processed, function 'install' streams the
 * 	temp files, in order, back into the archive.
 */

typedef struct	Arsymref
{
	char	*name;
	char *file;
	int	type;
	int	len;
	vlong	offset;
	struct	Arsymref *next;
} Arsymref;

typedef struct	Armember	/* Temp file entry - one per archive member */
{
	struct Armember	*next;
	struct ar_hdr	hdr;
	long		size;
	long		date;
	void		*member;
} Armember;

typedef	struct Arfile		/* Temp file control block - one per tempfile */
{
	int	paged;		/* set when some data paged to disk */
	char	*fname;		/* paging file name */
	int	fd;		/* paging file descriptor */
	vlong	size;
	Armember *head;		/* head of member chain */
	Armember *tail;		/* tail of member chain */
	Arsymref *sym;		/* head of defined symbol chain */
} Arfile;

typedef struct Hashchain
{
	char	*name;
	char *file;
	struct Hashchain *next;
} Hashchain;

#define	NHASH	1024

/*
 *	macro to portably read/write archive header.
 *	'cmd' is read/write/Bread/Bwrite, etc.
 */
#define	HEADER_IO(cmd, f, h)	cmd(f, h.name, sizeof(h.name)) != sizeof(h.name)\
				|| cmd(f, h.date, sizeof(h.date)) != sizeof(h.date)\
				|| cmd(f, h.uid, sizeof(h.uid)) != sizeof(h.uid)\
				|| cmd(f, h.gid, sizeof(h.gid)) != sizeof(h.gid)\
				|| cmd(f, h.mode, sizeof(h.mode)) != sizeof(h.mode)\
				|| cmd(f, h.size, sizeof(h.size)) != sizeof(h.size)\
				|| cmd(f, h.fmag, sizeof(h.fmag)) != sizeof(h.fmag)

		/* constants and flags */
char	*man =		"mrxtdpq";
char	*opt =		"uvnbailogS";
char	artemp[] =	"/tmp/vXXXXX";
char	movtemp[] =	"/tmp/v1XXXXX";
char	tailtemp[] =	"/tmp/v2XXXXX";
char	symdef[] =	"__.SYMDEF";
char	pkgdef[] =	"__.PKGDEF";

int	aflag;				/* command line flags */
int	bflag;
int	cflag;
int	gflag;
int	oflag;
int	uflag;
int	vflag;
int	Pflag;	/* remove leading file prefix */
int	Sflag;	/* force mark Go package as safe */

int	errors;

Arfile *astart, *amiddle, *aend;	/* Temp file control block pointers */
int	allobj = 1;			/* set when all members are object files of the same type */
int	symdefsize;			/* size of symdef file */
char	*pkgstmt;		/* string "package foo" */
char	*objhdr;		/* string "go object darwin 386 release.2010-01-01 2345+" */
int	dupfound;			/* flag for duplicate symbol */
Hashchain	*hash[NHASH];		/* hash table of text symbols */

#define	ARNAMESIZE	sizeof(astart->tail->hdr.name)

char	poname[ARNAMESIZE+1];		/* name of pivot member */
char	*file;				/* current file or member being worked on */
Biobuf	bout;
Biobuf bar;
char	*prefix;
int	pkgdefsafe;		/* was __.PKGDEF marked safe? */

void	arcopy(Biobuf*, Arfile*, Armember*);
int	arcreate(char*);
void	arfree(Arfile*);
void	arinsert(Arfile*, Armember*);
void	*armalloc(int);
char *arstrdup(char*);
void	armove(Biobuf*, Arfile*, Armember*);
void	arread(Biobuf*, Armember*);
void	arstream(int, Arfile*);
int	arwrite(int, Armember*);
int	bamatch(char*, char*);
int	duplicate(char*, char**);
Armember *getdir(Biobuf*);
void	getpkgdef(char**, int*);
int	getspace(void);
void	install(char*, Arfile*, Arfile*, Arfile*, int);
void	loadpkgdata(char*, int);
void	longt(Armember*);
int	match(int, char**);
void	mesg(int, char*);
Arfile	*newtempfile(char*);
Armember *newmember(void);
void	objsym(Sym*, void*);
int	openar(char*, int, int);
int	page(Arfile*);
void	pmode(long);
void	rl(int);
void	scanobj(Biobuf*, Arfile*, long);
void	scanpkg(Biobuf*, long);
void	select(int*, long);
void	setcom(void(*)(char*, int, char**));
void	skip(Biobuf*, vlong);
void	checksafe(Biobuf*, vlong);
int	symcomp(void*, void*);
void	trim(char*, char*, int);
void	usage(void);
void	wrerr(void);
void	wrsym(Biobuf*, long, Arsymref*);
int	arread_cutprefix(Biobuf*, Armember*);

void	rcmd(char*, int, char**);		/* command processing */
void	dcmd(char*, int, char**);
void	xcmd(char*, int, char**);
void	tcmd(char*, int, char**);
void	pcmd(char*, int, char**);
void	mcmd(char*, int, char**);
void	qcmd(char*, int, char**);
void	(*comfun)(char*, int, char**);

void
main(int argc, char *argv[])
{
	char *cp;

	Binit(&bout, 1, OWRITE);
	if(argc < 3)
		usage();
	for (cp = argv[1]; *cp; cp++) {
		switch(*cp) {
		case 'a':	aflag = 1;	break;
		case 'b':	bflag = 1;	break;
		case 'c':	cflag = 1;	break;
		case 'd':	setcom(dcmd);	break;
		case 'g':	gflag = 1; break;
		case 'i':	bflag = 1;	break;
		case 'l':
				strcpy(artemp, "vXXXXX");
				strcpy(movtemp, "v1XXXXX");
				strcpy(tailtemp, "v2XXXXX");
				break;
		case 'm':	setcom(mcmd);	break;
		case 'o':	oflag = 1;	break;
		case 'p':	setcom(pcmd);	break;
		case 'q':	setcom(qcmd);	break;
		case 'r':	setcom(rcmd);	break;
		case 't':	setcom(tcmd);	break;
		case 'u':	uflag = 1;	break;
		case 'v':	vflag = 1;	break;
		case 'x':	setcom(xcmd);	break;
		case 'S':	Sflag = 1;  break;
		case 'P':	Pflag = 1;  break;
		default:
			fprint(2, "gopack: bad option `%c'\n", *cp);
			exits("error");
		}
	}
	if (aflag && bflag) {
		fprint(2, "gopack: only one of 'a' and 'b' can be specified\n");
		usage();
	}
	if(aflag || bflag) {
		trim(argv[2], poname, sizeof(poname));
		argv++;
		argc--;
		if(argc < 3)
			usage();
	}
	if(Pflag) {
		if(argc < 4) {
			fprint(2, "gopack: P flag requires prefix argument\n");
			usage();
		}
		prefix = argv[2];
		argv++;
		argc--;
	}
	if(comfun == 0) {
		if(uflag == 0) {
			fprint(2, "gopack: one of [%s] must be specified\n", man);
			usage();
		}
		setcom(rcmd);
	}
	cp = argv[2];
	argc -= 3;
	argv += 3;
	(*comfun)(cp, argc, argv);	/* do the command */
	if(errors && cflag)
		remove(cp);
	cp = 0;
	while (argc--) {
		if (*argv) {
			fprint(2, "gopack: %s not found\n", *argv);
			cp = "error";
		}
		argv++;
	}
	if (errors)
		cp = "error";
	exits(cp);
}
/*
 *	select a command
 */
void
setcom(void (*fun)(char *, int, char**))
{

	if(comfun != 0) {
		fprint(2, "gopack: only one of [%s] allowed\n", man);
		usage();
	}
	comfun = fun;
}
/*
 *	perform the 'r' and 'u' commands
 */
void
rcmd(char *arname, int count, char **files)
{
	int fd;
	int i;
	Arfile *ap;
	Armember *bp;
	Dir *d;
	Biobuf *bfile;

	fd = openar(arname, ORDWR, 1);
	if (fd >= 0) {
		Binit(&bar, fd, OREAD);
		Bseek(&bar,seek(fd,0,1), 1);
	}
	astart = newtempfile(artemp);
	ap = astart;
	aend = 0;
	for(i = 0; fd >= 0; i++) {
		bp = getdir(&bar);
		if (!bp)
			break;
		if (bamatch(file, poname)) {		/* check for pivot */
			aend = newtempfile(tailtemp);
			ap = aend;
		}
			/* pitch symdef file */
		if (i == 0 && strcmp(file, symdef) == 0) {
			skip(&bar, bp->size);
			continue;
		}
			/* pitch pkgdef file but remember whether it was marked safe */
		if (gflag && strcmp(file, pkgdef) == 0) {
			checksafe(&bar, bp->size);
			continue;
		}
		/*
		 * the plan 9 ar treats count == 0 as equivalent
		 * to listing all the archive's files on the command line:
		 * it will try to open every file name in the archive
		 * and copy that file into the archive if it exists.
		 * for go we disable that behavior, because we use
		 * r with no files to make changes to the archive itself,
		 * using the S or P flags.
		 */
		if (!match(count, files)) {
			scanobj(&bar, ap, bp->size);
			arcopy(&bar, ap, bp);
			continue;
		}
		bfile = Bopen(file, OREAD);
		if (!bfile) {
			if (count != 0) {
				fprint(2, "gopack: cannot open %s\n", file);
				errors++;
			}
			scanobj(&bar, ap, bp->size);
			arcopy(&bar, ap, bp);
			continue;
		}
		d = dirfstat(Bfildes(bfile));
		if(d == nil)
			fprint(2, "gopack: cannot stat %s: %r\n", file);
		if (uflag && (d==nil || d->mtime <= bp->date)) {
			scanobj(&bar, ap, bp->size);
			arcopy(&bar, ap, bp);
			Bterm(bfile);
			free(d);
			continue;
		}
		mesg('r', file);
		skip(&bar, bp->size);
		scanobj(bfile, ap, d->length);
		free(d);
		armove(bfile, ap, bp);
		Bterm(bfile);
	}
	if(fd >= 0)
		close(fd);
		/* copy in remaining files named on command line */
	for (i = 0; i < count; i++) {
		file = files[i];
		if(file == 0)
			continue;
		files[i] = 0;
		bfile = Bopen(file, OREAD);
		if (!bfile) {
			fprint(2, "gopack: cannot open %s\n", file);
			errors++;
		} else {
			mesg('a', file);
			d = dirfstat(Bfildes(bfile));
			if (d == nil)
				fprint(2, "can't stat %s\n", file);
			else {
				scanobj(bfile, astart, d->length);
				armove(bfile, astart, newmember());
				free(d);
			}
			Bterm(bfile);
		}
	}
	if(fd < 0 && !cflag)
		install(arname, astart, 0, aend, 1);	/* issue 'creating' msg */
	else
		install(arname, astart, 0, aend, 0);
}

void
dcmd(char *arname, int count, char **files)
{
	Armember *bp;
	int fd, i;

	if (!count)
		return;
	fd = openar(arname, ORDWR, 0);
	Binit(&bar, fd, OREAD);
	Bseek(&bar,seek(fd,0,1), 1);
	astart = newtempfile(artemp);
	for (i = 0; bp = getdir(&bar); i++) {
		if(match(count, files)) {
			mesg('d', file);
			skip(&bar, bp->size);
			if (strcmp(file, symdef) == 0)
				allobj = 0;
		} else if (i == 0 && strcmp(file, symdef) == 0) {
			skip(&bar, bp->size);
		} else if (gflag && strcmp(file, pkgdef) == 0) {
			skip(&bar, bp->size);
		} else {
			scanobj(&bar, astart, bp->size);
			arcopy(&bar, astart, bp);
		}
	}
	close(fd);
	install(arname, astart, 0, 0, 0);
}

void
xcmd(char *arname, int count, char **files)
{
	int fd, f, mode, i;
	Armember *bp;
	Dir dx;

	fd = openar(arname, OREAD, 0);
	Binit(&bar, fd, OREAD);
	Bseek(&bar,seek(fd,0,1), 1);
	i = 0;
	while (bp = getdir(&bar)) {
		if(count == 0 || match(count, files)) {
			mode = strtoul(bp->hdr.mode, 0, 8) & 0777;
			f = create(file, OWRITE, mode);
			if(f < 0) {
				fprint(2, "gopack: %s cannot create\n", file);
				skip(&bar, bp->size);
			} else {
				mesg('x', file);
				arcopy(&bar, 0, bp);
				if (write(f, bp->member, bp->size) < 0)
					wrerr();
				if(oflag && bp->date != 0) {
					nulldir(&dx);
					dx.atime = bp->date;
					dx.mtime = bp->date;
					if(dirwstat(file, &dx) < 0)
						perror(file);
				}
				free(bp->member);
				close(f);
			}
			free(bp);
			if (count && ++i >= count)
				break;
		} else {
			skip(&bar, bp->size);
			free(bp);
		}
	}
	close(fd);
}
void
pcmd(char *arname, int count, char **files)
{
	int fd;
	Armember *bp;

	fd = openar(arname, OREAD, 0);
	Binit(&bar, fd, OREAD);
	Bseek(&bar,seek(fd,0,1), 1);
	while(bp = getdir(&bar)) {
		if(count == 0 || match(count, files)) {
			if(vflag)
				print("\n<%s>\n\n", file);
			arcopy(&bar, 0, bp);
			if (write(1, bp->member, bp->size) < 0)
				wrerr();
		} else
			skip(&bar, bp->size);
		free(bp);
	}
	close(fd);
}
void
mcmd(char *arname, int count, char **files)
{
	int fd, i;
	Arfile *ap;
	Armember *bp;

	if (count == 0)
		return;
	fd = openar(arname, ORDWR, 0);
	Binit(&bar, fd, OREAD);
	Bseek(&bar,seek(fd,0,1), 1);
	astart = newtempfile(artemp);
	amiddle = newtempfile(movtemp);
	aend = 0;
	ap = astart;
	for (i = 0; bp = getdir(&bar); i++) {
		if (bamatch(file, poname)) {
			aend = newtempfile(tailtemp);
			ap = aend;
		}
		if(match(count, files)) {
			mesg('m', file);
			scanobj(&bar, amiddle, bp->size);
			arcopy(&bar, amiddle, bp);
		} else if (ap == astart && i == 0 && strcmp(file, symdef) == 0) {
			/*
			 * pitch the symdef file if it is at the beginning
			 * of the archive and we aren't inserting in front
			 * of it (ap == astart).
			 */
			skip(&bar, bp->size);
		} else if (ap == astart && gflag && strcmp(file, pkgdef) == 0) {
			/*
			 * pitch the pkgdef file if we aren't inserting in front
			 * of it (ap == astart).
			 */
			skip(&bar, bp->size);
		} else {
			scanobj(&bar, ap, bp->size);
			arcopy(&bar, ap, bp);
		}
	}
	close(fd);
	if (poname[0] && aend == 0)
		fprint(2, "gopack: %s not found - files moved to end.\n", poname);
	install(arname, astart, amiddle, aend, 0);
}
void
tcmd(char *arname, int count, char **files)
{
	int fd;
	Armember *bp;
	char name[ARNAMESIZE+1];

	fd = openar(arname, OREAD, 0);
	Binit(&bar, fd, OREAD);
	Bseek(&bar,seek(fd,0,1), 1);
	while(bp = getdir(&bar)) {
		if(count == 0 || match(count, files)) {
			if(vflag)
				longt(bp);
			trim(file, name, ARNAMESIZE);
			Bprint(&bout, "%s\n", name);
		}
		skip(&bar, bp->size);
		free(bp);
	}
	close(fd);
}
void
qcmd(char *arname, int count, char **files)
{
	int fd, i;
	Armember *bp;
	Biobuf *bfile;

	if(aflag || bflag) {
		fprint(2, "gopack: abi not allowed with q\n");
		exits("error");
	}
	fd = openar(arname, ORDWR, 1);
	if (fd < 0) {
		if(!cflag)
			fprint(2, "gopack: creating %s\n", arname);
		fd = arcreate(arname);
	}
	Binit(&bar, fd, OREAD);
	Bseek(&bar,seek(fd,0,1), 1);
	/* leave note group behind when writing archive; i.e. sidestep interrupts */
	rfork(RFNOTEG);
	Bseek(&bar, 0, 2);
	bp = newmember();
	for(i=0; i<count && files[i]; i++) {
		file = files[i];
		files[i] = 0;
		bfile = Bopen(file, OREAD);
		if(!bfile) {
			fprint(2, "gopack: cannot open %s\n", file);
			errors++;
		} else {
			mesg('q', file);
			armove(bfile, 0, bp);
			if (!arwrite(fd, bp))
				wrerr();
			free(bp->member);
			bp->member = 0;
			Bterm(bfile);
		}
	}
	free(bp);
	close(fd);
}

/*
 *	does the object header line p match the last one we saw?
 *	update *lastp if it gets more specific.
 */
int
matchhdr(char *p, char **lastp)
{
	int n;
	char *last;
	
	// no information?
	last = *lastp;
	if(last == nil) {
		*lastp = strdup(p);
		return 1;
	}

	// identical match?
	if(strcmp(last, p) == 0)
		return 1;

	// last has extra fields
	n = strlen(p);
	if(n < strlen(last) && last[n] == ' ')
		return 1;

	// p has extra fields - save in last
	n = strlen(last);
	if(n < strlen(p) && p[n] == ' ') {
		free(last);
		*lastp = strdup(p);
		return 1;
	}
	
	return 0;
}	

/*
 *	extract the symbol references from an object file
 */
void
scanobj(Biobuf *b, Arfile *ap, long size)
{
	int obj;
	vlong offset, offset1;
	Dir *d;
	static int lastobj = -1;
	uchar buf[4];
	char *p;

	if (!allobj)			/* non-object file encountered */
		return;
	offset = Boffset(b);
	obj = objtype(b, 0);
	if (obj < 0) {			/* not an object file */
		/* maybe a foreign object file */
		Bseek(b, offset, 0);
		memset(buf, 0, sizeof buf);
		Bread(b, buf, 4);
		
		/* maybe a foreign object file?  that's okay */
		if((buf[0] == 0x7F && buf[1] == 'E' && buf[2] == 'L' && buf[3] == 'F') ||   // ELF
		   (buf[0] == 0x4c && buf[1] == 0x01 || buf[0] == 0x64 && buf[1] == 0x86) || // Windows PE
		   (buf[0] == 0xFE && buf[1] == 0xED && buf[2] == 0xFA && (buf[3]&~1) == 0xCE) ||  // Mach-O big-endian
		   (buf[3] == 0xFE && buf[2] == 0xED && buf[1] == 0xFA && (buf[0]&~1) == 0xCE)) {  // Mach-O little-endian
			Bseek(b, offset, 0);
			return;
		}
		
		if (!gflag || strcmp(file, pkgdef) != 0) {  /* don't clear allobj if it's pkg defs */
			fprint(2, "gopack: non-object file %s\n", file);
			errors++;
			allobj = 0;
		}
		d = dirfstat(Bfildes(b));
		if (d != nil && d->length == 0) {
			fprint(2, "gopack: zero length file %s\n", file);
			errors++;
		}
		free(d);
		Bseek(b, offset, 0);
		return;
	}

	offset1 = Boffset(b);
	Bseek(b, offset, 0);
	p = Brdstr(b, '\n', 1);
	Bseek(b, offset1, 0);
	if(p == nil || strncmp(p, "go object ", 10) != 0) {
		fprint(2, "gopack: malformed object file %s\n", file);
		errors++;
		Bseek(b, offset, 0);
		free(p);
		return;
	}
	
	if (!matchhdr(p, &objhdr)) {
		fprint(2, "gopack: inconsistent object file %s: [%s] vs [%s]\n", file, p, objhdr);
		errors++;
		allobj = 0;
		free(p);
		return;
	}
	free(p);

	// Old check.  Should be impossible since objhdrs match, but keep the check anyway.
	if (lastobj >= 0 && obj != lastobj) {
		fprint(2, "gopack: inconsistent object file %s\n", file);
		errors++;
		allobj = 0;
		return;
	}
	lastobj = obj;
		
	if (!readar(b, obj, offset+size, 0)) {
		fprint(2, "gopack: invalid symbol reference in file %s\n", file);
		errors++;
		allobj = 0;
		Bseek(b, offset, 0);
		return;
	}
	Bseek(b, offset, 0);
	objtraverse(objsym, ap);
	if (gflag) {
		scanpkg(b, size);
		Bseek(b, offset, 0);
	}
}

/*
 *	does line contain substring (length-limited)
 */
int
strstrn(char *line, int len, char *sub)
{
	int i;
	int sublen;

	sublen = strlen(sub);
	for (i = 0; i < len - sublen; i++)
		if (memcmp(line+i, sub, sublen) == 0)
			return 1;
	return 0;
}

/*
 *	package import data
 */
int	safe = 1;
char*	pkgname;
char*	importblock;

void
getpkgdef(char **datap, int *lenp)
{
	char *tag, *hdr;

	if(pkgname == nil) {
		pkgname = "__emptyarchive__";
		importblock = "";
	}
	
	tag = "";
	if(safe || Sflag)
		tag = "safe";

	hdr = "empty archive";
	if(objhdr != nil)
		hdr = objhdr;

	*datap = smprint("%s\nimport\n$$\npackage %s %s\n%s\n$$\n", hdr, pkgname, tag, importblock);
	*lenp = strlen(*datap);
}

/*
 *	extract the package definition data from an object file.
 *	there can be only one.
 */
void
scanpkg(Biobuf *b, long size)
{
	long n;
	int c;
	long start, end, pkgsize;
	char *data, *line, pkgbuf[1024], *pkg;
	int first;

	/*
	 * scan until $$
	 */
	for (n=0; n<size; ) {
		c = Bgetc(b);
		if(c == Beof)
			break;
		n++;
		if(c != '$')
			continue;
		c = Bgetc(b);
		if(c == Beof)
			break;
		n++;
		if(c != '$')
			continue;
		goto foundstart;
	}
	// fprint(2, "gopack: warning: no package import section in %s\n", file);
	if(b != &bar || !pkgdefsafe)
		safe = 0;	// non-Go file (C or assembly)
	return;

foundstart:
	/* found $$; skip rest of line */
	while((c = Bgetc(b)) != '\n')
		if(c == Beof)
			goto bad;

	/* how big is it? */
	pkg = nil;
	first = 1;
	start = end = 0;
	for (n=0; n<size; n+=Blinelen(b)) {
		line = Brdstr(b, '\n', 0);
		if (line == nil)
			goto bad;
		if (first && strstrn(line, Blinelen(b), "package ")) {
			if (Blinelen(b) > sizeof(pkgbuf)-1)
				goto bad;
			memmove(pkgbuf, line, Blinelen(b));
			pkgbuf[Blinelen(b)] = '\0';
			pkg = pkgbuf;
			while(*pkg == ' ' || *pkg == '\t')
				pkg++;
			if(strncmp(pkg, "package ", 8) != 0)
				goto bad;
			pkg += 8;
			data = pkg;
			while(*pkg != ' ' && *pkg != '\n' && *pkg != '\0')
				pkg++;
			pkgname = armalloc(pkg - data + 1);
			memmove(pkgname, data, pkg - data);
			pkgname[pkg-data] = '\0';
			if(strcmp(pkg, " safe\n") != 0 && (b != &bar || !pkgdefsafe))
				safe = 0;
			start = Boffset(b);  // after package statement
			first = 0;
			free(line);
			continue;
		}
		if(line[0] == '$' && line[1] == '$') {
			free(line);
			goto foundend;
		}
		end = Boffset(b);  // before closing $$
		free(line);
	}
bad:
	fprint(2, "gopack: bad package import section in %s\n", file);
	errors++;
	return;

foundend:
	if (start == 0)
		return;
	if (end == 0)
		goto bad;
	if(importblock != nil) {
		fprint(2, "gopack: multiple Go object files\n");
		errors++;
		return;
	}
	pkgsize = end-start;
	data = armalloc(end - start + 1);
	Bseek(b, start, 0);
	if (Bread(b, data, pkgsize) != pkgsize) {
		fprint(2, "gopack: error reading package import section in %s\n", file);
		errors++;
		return;
	}
	data[end-start] = '\0';
	importblock = data;
}

/*
 *	add text and data symbols to the symbol list
 */
void
objsym(Sym *s, void *p)
{
	int n;
	Arsymref *as;
	Arfile *ap;
	char *ofile;

	if (s->type != 'T' &&  s->type != 'D')
		return;
	ap = (Arfile*)p;
	as = armalloc(sizeof(Arsymref));
	as->offset = ap->size;
	as->name = arstrdup(s->name);
	as->file = arstrdup(file);
	if(s->type == 'T' && duplicate(as->name, &ofile)) {
		dupfound = 1;
		fprint(2, "duplicate text symbol: %s and %s: %s\n", as->file, ofile, as->name);
		errors++;
		free(as->name);
		free(as);
		return;
	}
	as->type = s->type;
	n = strlen(s->name);
	symdefsize += 4+(n+1)+1;
	as->len = n;
	as->next = ap->sym;
	ap->sym = as;
}

/*
 *	Check the symbol table for duplicate text symbols
 */
int
hashstr(char *name)
{
	int h;
	char *cp;

	h = 0;
	for(cp = name; *cp; h += *cp++)
		h *= 1119;
	
	// the code used to say
	//	if(h < 0)
	//		h = ~h;
	// but on gcc 4.3 with -O2 on some systems,
	// the if(h < 0) gets compiled away as not possible.
	// use a mask instead, leaving plenty of bits but
	// definitely not the sign bit.

	return h & 0xfffffff;
}

int
duplicate(char *name, char **ofile)
{
	Hashchain *p;
	int h;

	h = hashstr(name) % NHASH;

	for(p = hash[h]; p; p = p->next)
		if(strcmp(p->name, name) == 0) {
			*ofile = p->file;
			return 1;
		}
	p = armalloc(sizeof(Hashchain));
	p->next = hash[h];
	p->name = name;
	p->file = file;
	hash[h] = p;
	*ofile = nil;
	return 0;
}

/*
 *	open an archive and validate its header
 */
int
openar(char *arname, int mode, int errok)
{
	int fd;
	char mbuf[SARMAG];

	fd = open(arname, mode);
	if(fd >= 0){
		if(read(fd, mbuf, SARMAG) != SARMAG || strncmp(mbuf, ARMAG, SARMAG)) {
			fprint(2, "gopack: %s not in archive format\n", arname);
			exits("error");
		}
	}else if(!errok){
		fprint(2, "gopack: cannot open %s: %r\n", arname);
		exits("error");
	}
	return fd;
}

/*
 *	create an archive and set its header
 */
int
arcreate(char *arname)
{
	int fd;

	fd = create(arname, OWRITE, 0664);
	if(fd < 0){
		fprint(2, "gopack: cannot create %s: %r\n", arname);
		exits("error");
	}
	if(write(fd, ARMAG, SARMAG) != SARMAG)
		wrerr();
	return fd;
}

/*
 *		error handling
 */
void
wrerr(void)
{
	perror("gopack: write error");
	exits("error");
}

void
rderr(void)
{
	perror("gopack: read error");
	exits("error");
}

void
phaseerr(int offset)
{
	fprint(2, "gopack: phase error at offset %d\n", offset);
	exits("error");
}

void
usage(void)
{
	fprint(2, "usage: gopack [%s][%s][P prefix] archive files ...\n", opt, man);
	exits("error");
}

/*
 *	read the header for the next archive member
 */
Armember *
getdir(Biobuf *b)
{
	Armember *bp;
	char *cp;
	static char name[ARNAMESIZE+1];

	bp = newmember();
	if(HEADER_IO(Bread, b, bp->hdr)) {
		free(bp);
		return 0;
	}
	if(strncmp(bp->hdr.fmag, ARFMAG, sizeof(bp->hdr.fmag)))
		phaseerr(Boffset(b));
	strncpy(name, bp->hdr.name, sizeof(bp->hdr.name));
	cp = name+sizeof(name)-1;
	while(*--cp==' ')
		;
	cp[1] = '\0';
	file = arstrdup(name);
	bp->date = strtol(bp->hdr.date, 0, 0);
	bp->size = strtol(bp->hdr.size, 0, 0);
	return bp;
}

/*
 *	Copy the file referenced by fd to the temp file
 */
void
armove(Biobuf *b, Arfile *ap, Armember *bp)
{
	char *cp;
	Dir *d;
	vlong n;

	d = dirfstat(Bfildes(b));
	if (d == nil) {
		fprint(2, "gopack: cannot stat %s\n", file);
		return;
	}

	trim(file, bp->hdr.name, sizeof(bp->hdr.name));
	for (cp = strchr(bp->hdr.name, 0);		/* blank pad on right */
		cp < bp->hdr.name+sizeof(bp->hdr.name); cp++)
			*cp = ' ';
	sprint(bp->hdr.date, "%-12ld", 0);  // was d->mtime but removed for idempotent builds
	sprint(bp->hdr.uid, "%-6d", 0);
	sprint(bp->hdr.gid, "%-6d", 0);
	sprint(bp->hdr.mode, "%-8lo", d->mode);
	sprint(bp->hdr.size, "%-10lld", d->length);
	strncpy(bp->hdr.fmag, ARFMAG, 2);
	bp->size = d->length;
	arread(b, bp);
	n = bp->size;
	if (n&1)
		n++;
	if (ap) {
		arinsert(ap, bp);
		ap->size += n+SAR_HDR;
	}
	free(d);
}

/*
 *	Copy the archive member at the current offset into the temp file.
 */
void
arcopy(Biobuf *b, Arfile *ap, Armember *bp)
{
	long n;

	arread(b, bp);
	n = bp->size;
	if (n & 01)
		n++;
	if (ap) {
		arinsert(ap, bp);
		ap->size += n+SAR_HDR;
	}
}

/*
 *	Skip an archive member
 */
void
skip(Biobuf *bp, vlong len)
{
	if (len & 01)
		len++;
	Bseek(bp, len, 1);
}

void
checksafe(Biobuf *bp, vlong len)
{
	char *p;
	vlong end;

	if (len & 01)
		len++;
	end = Boffset(bp) + len;

	p = Brdline(bp, '\n');
	if(p == nil || strncmp(p, "go object ", 10) != 0)
		goto done;
	for(;;) {
		p = Brdline(bp, '\n');
		if(p == nil || Boffset(bp) >= end)
			goto done;
		if(strncmp(p, "$$\n", 3) == 0)
			break;
	}
	p = Brdline(bp, '\n');
	if(p == nil || Boffset(bp) > end)
		goto done;
	if(Blinelen(bp) > 8+6 && strncmp(p, "package ", 8) == 0 && strncmp(p+Blinelen(bp)-6, " safe\n", 6) == 0)
		pkgdefsafe = 1;

done:
	Bseek(bp, end, 0);
}

/*
 *	Stream the three temp files to an archive
 */
void
install(char *arname, Arfile *astart, Arfile *amiddle, Arfile *aend, int createflag)
{
	int fd;

	if(allobj && dupfound) {
		fprint(2, "%s not changed\n", arname);
		return;
	}
	/* leave note group behind when copying back; i.e. sidestep interrupts */
	rfork(RFNOTEG);

	if(createflag)
		fprint(2, "gopack: creating %s\n", arname);
	fd = arcreate(arname);

	if(allobj)
		rl(fd);

	if (astart) {
		arstream(fd, astart);
		arfree(astart);
	}
	if (amiddle) {
		arstream(fd, amiddle);
		arfree(amiddle);
	}
	if (aend) {
		arstream(fd, aend);
		arfree(aend);
	}
	close(fd);
}

void
rl(int fd)
{
	Biobuf b;
	char *cp;
	struct ar_hdr a;
	long len;
	int headlen;
	char *pkgdefdata;
	int pkgdefsize;

	pkgdefdata = nil;
	pkgdefsize = 0;

	Binit(&b, fd, OWRITE);
	Bseek(&b,seek(fd,0,1), 0);

	len = symdefsize;
	if(len&01)
		len++;
	sprint(a.date, "%-12ld", 0);  // time(0)
	sprint(a.uid, "%-6d", 0);
	sprint(a.gid, "%-6d", 0);
	sprint(a.mode, "%-8lo", 0644L);
	sprint(a.size, "%-10ld", len);
	strncpy(a.fmag, ARFMAG, 2);
	strcpy(a.name, symdef);
	for (cp = strchr(a.name, 0);		/* blank pad on right */
		cp < a.name+sizeof(a.name); cp++)
			*cp = ' ';
	if(HEADER_IO(Bwrite, &b, a))
			wrerr();

	headlen = Boffset(&b);
	len += headlen;
	if (gflag) {
		getpkgdef(&pkgdefdata, &pkgdefsize);
		len += SAR_HDR + pkgdefsize;
		if (len & 1)
			len++;
	}
	if (astart) {
		wrsym(&b, len, astart->sym);
		len += astart->size;
	}
	if(amiddle) {
		wrsym(&b, len, amiddle->sym);
		len += amiddle->size;
	}
	if(aend)
		wrsym(&b, len, aend->sym);

	if(symdefsize&0x01)
		Bputc(&b, 0);

	if (gflag) {
		len = pkgdefsize;
		sprint(a.date, "%-12ld", 0);  // time(0)
		sprint(a.uid, "%-6d", 0);
		sprint(a.gid, "%-6d", 0);
		sprint(a.mode, "%-8lo", 0644L);
		sprint(a.size, "%-10ld", (len + 1) & ~1);
		strncpy(a.fmag, ARFMAG, 2);
		strcpy(a.name, pkgdef);
		for (cp = strchr(a.name, 0);		/* blank pad on right */
			cp < a.name+sizeof(a.name); cp++)
				*cp = ' ';
		if(HEADER_IO(Bwrite, &b, a))
				wrerr();

		if (Bwrite(&b, pkgdefdata, pkgdefsize) != pkgdefsize)
			wrerr();
		if(len&0x01)
			Bputc(&b, 0);
	}
	Bterm(&b);
}

/*
 *	Write the defined symbols to the symdef file
 */
void
wrsym(Biobuf *bp, long offset, Arsymref *as)
{
	int off;

	while(as) {
		Bputc(bp, as->type);
		off = as->offset+offset;
		Bputc(bp, off);
		Bputc(bp, off>>8);
		Bputc(bp, off>>16);
		Bputc(bp, off>>24);
		if (Bwrite(bp, as->name, as->len+1) != as->len+1)
			wrerr();
		as = as->next;
	}
}

/*
 *	Check if the archive member matches an entry on the command line.
 */
int
match(int count, char **files)
{
	int i;
	char name[ARNAMESIZE+1];

	for(i=0; i<count; i++) {
		if(files[i] == 0)
			continue;
		trim(files[i], name, ARNAMESIZE);
		if(strncmp(name, file, ARNAMESIZE) == 0) {
			file = files[i];
			files[i] = 0;
			return 1;
		}
	}
	return 0;
}

/*
 *	compare the current member to the name of the pivot member
 */
int
bamatch(char *file, char *pivot)
{
	static int state = 0;

	switch(state)
	{
	case 0:			/* looking for position file */
		if (aflag) {
			if (strncmp(file, pivot, ARNAMESIZE) == 0)
				state = 1;
		} else if (bflag) {
			if (strncmp(file, pivot, ARNAMESIZE) == 0) {
				state = 2;	/* found */
				return 1;
			}
		}
		break;
	case 1:			/* found - after previous file */
		state = 2;
		return 1;
	case 2:			/* already found position file */
		break;
	}
	return 0;
}

/*
 *	output a message, if 'v' option was specified
 */
void
mesg(int c, char *file)
{

	if(vflag)
		Bprint(&bout, "%c - %s\n", c, file);
}

/*
 *	isolate file name by stripping leading directories and trailing slashes
 */
void
trim(char *s, char *buf, int n)
{
	char *p;

	for(;;) {
		p = strrchr(s, '/');
		if (!p) {		/* no slash in name */
			strncpy(buf, s, n);
			return;
		}
		if (p[1] != 0) {	/* p+1 is first char of file name */
			strncpy(buf, p+1, n);
			return;
		}
		*p = 0;			/* strip trailing slash */
	}
}

/*
 *	utilities for printing long form of 't' command
 */
#define	SUID	04000
#define	SGID	02000
#define	ROWN	0400
#define	WOWN	0200
#define	XOWN	0100
#define	RGRP	040
#define	WGRP	020
#define	XGRP	010
#define	ROTH	04
#define	WOTH	02
#define	XOTH	01
#define	STXT	01000

void
longt(Armember *bp)
{
	char *cp;
	time_t date;

	pmode(strtoul(bp->hdr.mode, 0, 8));
	Bprint(&bout, "%3ld/%1ld", strtol(bp->hdr.uid, 0, 0), strtol(bp->hdr.gid, 0, 0));
	Bprint(&bout, "%7ld", bp->size);
	date = bp->date;
	cp = ctime(&date);
	/* using unix ctime, not plan 9 time, so cp+20 for year, not cp+24 */
	Bprint(&bout, " %-12.12s %-4.4s ", cp+4, cp+20);
}

int	m1[] = { 1, ROWN, 'r', '-' };
int	m2[] = { 1, WOWN, 'w', '-' };
int	m3[] = { 2, SUID, 's', XOWN, 'x', '-' };
int	m4[] = { 1, RGRP, 'r', '-' };
int	m5[] = { 1, WGRP, 'w', '-' };
int	m6[] = { 2, SGID, 's', XGRP, 'x', '-' };
int	m7[] = { 1, ROTH, 'r', '-' };
int	m8[] = { 1, WOTH, 'w', '-' };
int	m9[] = { 2, STXT, 't', XOTH, 'x', '-' };

int	*m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};

void
pmode(long mode)
{
	int **mp;

	for(mp = &m[0]; mp < &m[9];)
		select(*mp++, mode);
}

void
select(int *ap, long mode)
{
	int n;

	n = *ap++;
	while(--n>=0 && (mode&*ap++)==0)
		ap++;
	Bputc(&bout, *ap);
}

/*
 *	Temp file I/O subsystem.  We attempt to cache all three temp files in
 *	core.  When we run out of memory we spill to disk.
 *	The I/O model assumes that temp files:
 *		1) are only written on the end
 *		2) are only read from the beginning
 *		3) are only read after all writing is complete.
 *	The architecture uses one control block per temp file.  Each control
 *	block anchors a chain of buffers, each containing an archive member.
 */
Arfile *
newtempfile(char *name)		/* allocate a file control block */
{
	Arfile *ap;

	ap = armalloc(sizeof(Arfile));
	ap->fname = name;
	return ap;
}

Armember *
newmember(void)			/* allocate a member buffer */
{
	return armalloc(sizeof(Armember));
}

void
arread(Biobuf *b, Armember *bp)	/* read an image into a member buffer */
{
	int i;
	vlong off;

	bp->member = armalloc(bp->size);
	
	// If P flag is set, let arread_cutprefix try.
	// If it succeeds, we're done.  If not, fall back
	// to a direct copy.
	off = Boffset(b);
	if(Pflag && arread_cutprefix(b, bp))
		return;
	Bseek(b, off, 0);

	i = Bread(b, bp->member, bp->size);
	if (i < 0) {
		free(bp->member);
		bp->member = 0;
		rderr();
	}
	if(bp->size&1)
		Bgetc(b);
}

/*
 * insert a member buffer into the member chain
 */
void
arinsert(Arfile *ap, Armember *bp)
{
	bp->next = 0;
	if (!ap->tail)
		ap->head = bp;
	else
		ap->tail->next = bp;
	ap->tail = bp;
}

/*
 *	stream the members in a temp file to the file referenced by 'fd'.
 */
void
arstream(int fd, Arfile *ap)
{
	Armember *bp;
	int i;
	char buf[8192];

	if (ap->paged) {		/* copy from disk */
		seek(ap->fd, 0, 0);
		for (;;) {
			i = read(ap->fd, buf, sizeof(buf));
			if (i < 0)
				rderr();
			if (i == 0)
				break;
			if (write(fd, buf, i) != i)
				wrerr();
		}
		close(ap->fd);
		ap->paged = 0;
	}
		/* dump the in-core buffers */
	for (bp = ap->head; bp; bp = bp->next) {
		if (!arwrite(fd, bp))
			wrerr();
	}
}

/*
 *	write a member to 'fd'.
 */
int
arwrite(int fd, Armember *bp)
{
	int len;

	if(HEADER_IO(write, fd, bp->hdr))
		return 0;
	len = bp->size;
	if (len & 01)
		len++;
	if (write(fd, bp->member, len) != len)
		return 0;
	return 1;
}

/*
 *	Spill a member to a disk copy of a temp file
 */
int
page(Arfile *ap)
{
	USED(ap);

	sysfatal("page");
	return 1;
}

/*
 *	try to reclaim space by paging.  we try to spill the start, middle,
 *	and end files, in that order.  there is no particular reason for the
 *	ordering.
 */
int
getspace(void)
{
fprint(2, "IN GETSPACE\n");
	if (astart && astart->head && page(astart))
		return 1;
	if (amiddle && amiddle->head && page(amiddle))
		return 1;
	if (aend && aend->head && page(aend))
		return 1;
	return 0;
}

void
arfree(Arfile *ap)		/* free a member buffer */
{
	Armember *bp, *next;

	for (bp = ap->head; bp; bp = next) {
		next = bp->next;
		if (bp->member)
			free(bp->member);
		free(bp);
	}
	free(ap);
}

/*
 *	allocate space for a control block or member buffer.  if the malloc
 *	fails we try to reclaim space by spilling previously allocated
 *	member buffers.
 */
void *
armalloc(int n)
{
	char *cp;

	// bump so that arwrite can do the same
	if(n&1)
		n++;

	do {
		cp = malloc(n);
		if (cp) {
			memset(cp, 0, n);
			return cp;
		}
	} while (getspace());
	fprint(2, "gopack: out of memory\n");
	exits("malloc");
	return 0;
}

char *
arstrdup(char *s)
{
	char *t;

	t = armalloc(strlen(s) + 1);
	strcpy(t, s);
	return t;
}


/*
 *	Parts of libmach we're not supposed
 *	to look at but need for arread_cutprefix.
 */
extern int _read5(Biobuf*, Prog*);
extern int _read6(Biobuf*, Prog*);
extern int _read8(Biobuf*, Prog*);
int (*reader[256])(Biobuf*, Prog*) = {
	[ObjArm] = _read5,
	[ObjAmd64] = _read6,
	[Obj386] = _read8,
};

/*
 *	copy b into bp->member but rewrite object
 *	during copy to drop prefix from all file names.
 *	return 1 if b was recognized as an object file
 *	and copied successfully, 0 otherwise.
 */
int
arread_cutprefix(Biobuf *b, Armember *bp)
{
	vlong offset, o, end;
	int n, t;
	int (*rd)(Biobuf*, Prog*);
	char *w, *inprefix;
	Prog p;
	
	offset = Boffset(b);
	end = offset + bp->size;
	t = objtype(b, nil);
	if(t < 0)
		return 0;
	if((rd = reader[t]) == nil)
		return 0;
	
	// copy header
	w = bp->member;
	n = Boffset(b) - offset;
	Bseek(b, -n, 1);
	if(Bread(b, w, n) != n)
		return 0;
	offset += n;
	w += n;
	
	// read object file one pseudo-instruction at a time,
	// eliding the file name instructions that refer to
	// the prefix.
	memset(&p, 0, sizeof p);
	inprefix = nil;
	while(Boffset(b) < end && rd(b, &p)) {
		if(p.kind == aName && p.type == UNKNOWN && p.sym == 1 && p.id[0] == '<') {
			// part of a file path.
			// we'll keep continuing (skipping the copy)
			// around the loop until either we get to a
			// name piece that should be kept or we see
			// the whole prefix.

			if(inprefix == nil && prefix[0] == '/' && p.id[1] == '/' && p.id[2] == '\0') {
				// leading /
				inprefix = prefix+1;
			} else if(inprefix != nil) {
				// handle subsequent elements
				n = strlen(p.id+1);
				if(strncmp(p.id+1, inprefix, n) == 0 && (inprefix[n] == '/' || inprefix[n] == '\0')) {
					inprefix += n;
					if(inprefix[0] == '/')
						inprefix++;
				}
			}
			
			if(inprefix && inprefix[0] == '\0') {
				// reached end of prefix.
				// if we another path element follows,
				// nudge the offset to skip over the prefix we saw.
				// if not, leave offset alone, to emit the whole name.
				// additional name elements will not be skipped
				// because inprefix is now nil and we won't see another
				// leading / in this name.
				inprefix = nil;
				o = Boffset(b);
				if(o < end && rd(b, &p) && p.kind == aName && p.type == UNKNOWN && p.sym == 1 && p.id[0] == '<') {
					// print("skip %lld-%lld\n", offset, o);
					offset = o;
				}
			}
		} else {
			// didn't find the whole prefix.
			// give up and let it emit the entire name.
			inprefix = nil;
		}

		// copy instructions
		if(!inprefix) {
			n = Boffset(b) - offset;
			Bseek(b, -n, 1);
			if(Bread(b, w, n) != n)
				return 0;
			offset += n;
			w += n;
		}
	}
	bp->size = w - (char*)bp->member;
	sprint(bp->hdr.size, "%-10lld", (vlong)bp->size);
	strncpy(bp->hdr.fmag, ARFMAG, 2);
	Bseek(b, end, 0);
	if(Boffset(b)&1)
		Bgetc(b);
	return 1;
}
