/*
 * tar - `tape archiver', actually usable on any medium.
 *	POSIX "ustar" compliant when extracting, and by default when creating.
 *	this tar attempts to read and write multiple Tblock-byte blocks
 *	at once to and from the filesystem, and does not copy blocks
 *	around internally.
 */

#include <u.h>
#include <libc.h>
#include <fcall.h>		/* for %M */
#include <libString.h>

/*
 * modified versions of those in libc.h; scans only the first arg for
 * keyletters and options.
 */
#define	TARGBEGIN {\
	if (argv0 == nil)\
		argv0 = *argv;\
	argv++, argc--;\
	if (argv[0]) {\
		char *_args, *_argt;\
		Rune _argc;\
		_args = &argv[0][0];\
		_argc = 0;\
		while(*_args && (_args += chartorune(&_argc, _args)))\
			switch(_argc)
#define	TARGEND	SET(_argt); USED(_argt);USED(_argc);USED(_args); \
	argc--, argv++; } \
	USED(argv); USED(argc); }
#define	TARGC() (_argc)

#define ROUNDUP(a, b)	(((a) + (b) - 1)/(b))
#define BYTES2TBLKS(bytes) ROUNDUP(bytes, Tblock)

typedef vlong Off;
typedef char *(*Refill)(int ar, char *bufs, int justhdr);

enum { Stdin, Stdout, Stderr };
enum { Rd, Wr };			/* pipe fd-array indices */
enum { Output, Input };
enum { None, Toc, Xtract, Replace };
enum { Alldata, Justnxthdr };
enum {
	Tblock = 512,
	Nblock = 40,		/* maximum blocksize */
	Dblock = 20,		/* default blocksize */
	Namsiz = 100,
	Maxpfx = 155,		/* from POSIX */
	Maxname = Namsiz + 1 + Maxpfx,
	DEBUG = 0,
};

/* POSIX link flags */
enum {
	LF_PLAIN1 =	'\0',
	LF_PLAIN2 =	'0',
	LF_LINK =	'1',
	LF_SYMLINK1 =	'2',
	LF_SYMLINK2 =	's',
	LF_CHR =	'3',
	LF_BLK =	'4',
	LF_DIR =	'5',
	LF_FIFO =	'6',
	LF_CONTIG =	'7',
	/* 'A' - 'Z' are reserved for custom implementations */
};

#define islink(lf)	(isreallink(lf) || issymlink(lf))
#define isreallink(lf)	((lf) == LF_LINK)
#define issymlink(lf)	((lf) == LF_SYMLINK1 || (lf) == LF_SYMLINK2)

typedef struct {
	char	name[Namsiz];
	char	mode[8];
	char	uid[8];
	char	gid[8];
	char	size[12];
	char	mtime[12];
	char	chksum[8];
	char	linkflag;
	char	linkname[Namsiz];

	/* rest are defined by POSIX's ustar format; see p1003.2b */
	char	magic[6];	/* "ustar" */
	char	version[2];
	char	uname[32];
	char	gname[32];
	char	devmajor[8];
	char	devminor[8];
	char	prefix[Maxpfx]; /* if non-null, path= prefix "/" name */
} Hdr;

typedef struct {
	char	*comp;
	char	*decomp;
	char	*sfx[4];
} Compress;

static Compress comps[] = {
	"gzip",		"gunzip",	{ ".tar.gz", ".tgz" },	/* default */
	"compress",	"uncompress",	{ ".tar.Z",  ".tz" },
	"bzip2",	"bunzip2",	{ ".tar.bz", ".tbz",
					  ".tar.bz2",".tbz2" },
};

typedef struct {
	int	kid;
	int	fd;	/* original fd */
	int	rfd;	/* replacement fd */
	int	input;
	int	open;
} Pushstate;

#define OTHER(rdwr) (rdwr == Rd? Wr: Rd)

/* static int debug; */
static int verb;
static int posix = 1;
static int docreate;
static int aruid;
static int argid;
static int relative = 1;
static int settime;
static int verbose;
static int docompress;
static int keepexisting;
static Off blkoff;	/* offset of the current archive block (not Tblock) */
static Off nexthdr;

static int nblock = Dblock;
static char *usefile;
static char origdir[Maxname*2];
static Hdr *tpblk, *endblk;
static Hdr *curblk;

static void
usage(void)
{
	fprint(2, "usage: %s {crtx}[PRTfgkmpuvz] [archive] file1 file2...\n",
		argv0);
	exits("usage");
}

/* compression */

static Compress *
compmethod(char *name)
{
	int i, nmlen = strlen(name), sfxlen;
	Compress *cp;

	for (cp = comps; cp < comps + nelem(comps); cp++)
		for (i = 0; i < nelem(cp->sfx) && cp->sfx[i]; i++) {
			sfxlen = strlen(cp->sfx[i]);
			if (nmlen > sfxlen &&
			    strcmp(cp->sfx[i], name + nmlen - sfxlen) == 0)
				return cp;
		}
	return docompress? comps: nil;
}

/*
 * push a filter, cmd, onto fd.  if input, it's an input descriptor.
 * returns a descriptor to replace fd, or -1 on error.
 */
static int
push(int fd, char *cmd, int input, Pushstate *ps)
{
	int nfd, pifds[2];
	String *s;

	ps->open = 0;
	ps->fd = fd;
	ps->input = input;
	if (fd < 0 || pipe(pifds) < 0)
		return -1;
	ps->kid = fork();
	switch (ps->kid) {
	case -1:
		return -1;
	case 0:
		if (input)
			dup(pifds[Wr], Stdout);
		else
			dup(pifds[Rd], Stdin);
		close(pifds[input? Rd: Wr]);
		dup(fd, (input? Stdin: Stdout));
		s = s_new();
		if (cmd[0] != '/')
			s_append(s, "/bin/");
		s_append(s, cmd);
		execl(s_to_c(s), cmd, nil);
		sysfatal("can't exec %s: %r", cmd);
	default:
		nfd = pifds[input? Rd: Wr];
		close(pifds[input? Wr: Rd]);
		break;
	}
	ps->rfd = nfd;
	ps->open = 1;
	return nfd;
}

static char *
pushclose(Pushstate *ps)
{
	Waitmsg *wm;

	if (ps->fd < 0 || ps->rfd < 0 || !ps->open)
		return "not open";
	close(ps->rfd);
	ps->rfd = -1;
	ps->open = 0;
	while ((wm = wait()) != nil && wm->pid != ps->kid)
		continue;
	return wm? wm->msg: nil;
}

/*
 * block-buffer management
 */

static void
initblks(void)
{
	free(tpblk);
	tpblk = malloc(Tblock * nblock);
	assert(tpblk != nil);
	endblk = tpblk + nblock;
}

/*
 * (re)fill block buffers from archive.  `justhdr' means we don't care
 * about the data before the next header block.
 */
static char *
refill(int ar, char *bufs, int justhdr)
{
	int i, n;
	unsigned bytes = Tblock * nblock;
	static int done, first = 1, seekable;

	if (done)
		return nil;

	if (first)
		seekable = seek(ar, 0, 1) >= 0;
	/* try to size non-pipe input at first read */
	if (first && usefile) {
		blkoff = seek(ar, 0, 1);	/* note position */
		n = read(ar, bufs, bytes);
		if (n <= 0)
			sysfatal("error reading archive: %r");
		i = n;
		if (i % Tblock != 0) {
			fprint(2, "%s: archive block size (%d) error\n",
				argv0, i);
			exits("blocksize");
		}
		i /= Tblock;
		if (i != nblock) {
			nblock = i;
			fprint(2, "%s: blocking = %d\n", argv0, nblock);
			endblk = (Hdr *)bufs + nblock;
			bytes = n;
		}
	} else if (justhdr && seekable && nexthdr - seek(ar, 0, 1) >= bytes) {
		/* optimisation for huge archive members on seekable media */
		if (seek(ar, bytes, 1) < 0)
			sysfatal("can't seek on archive: %r");
		n = bytes;
	} else
		n = readn(ar, bufs, bytes);
	first = 0;

	if (n == 0)
		sysfatal("unexpected EOF reading archive");
	else if (n < 0)
		sysfatal("error reading archive: %r");
	else if (n%Tblock != 0)
		sysfatal("partial block read from archive");
	if (n != bytes) {
		done = 1;
		memset(bufs + n, 0, bytes - n);
	}
	return bufs;
}

static Hdr *
getblk(int ar, Refill rfp, int justhdr)
{
	if (curblk == nil || curblk >= endblk) {  /* input block exhausted? */
		if (rfp != nil && (*rfp)(ar, (char *)tpblk, justhdr) == nil)
			return nil;
		curblk = tpblk;
	}
	return curblk++;
}

static Hdr *
getblkrd(int ar, int justhdr)
{
	return getblk(ar, refill, justhdr);
}

static Hdr *
getblke(int ar)
{
	return getblk(ar, nil, Alldata);
}

static Hdr *
getblkz(int ar)
{
	Hdr *hp = getblke(ar);

	if (hp != nil)
		memset(hp, 0, Tblock);
	return hp;
}

/*
 * how many block buffers are available, starting at the address
 * just returned by getblk*?
 */
static int
gothowmany(int max)
{
	int n = endblk - (curblk - 1);

	return n > max? max: n;
}

/*
 * indicate that one is done with the last block obtained from getblke
 * and it is now available to be written into the archive.
 */
static void
putlastblk(int ar)
{
	unsigned bytes = Tblock * nblock;

	/* if writing end-of-archive, aid compression (good hygiene too) */
	if (curblk < endblk)
		memset(curblk, 0, (char *)endblk - (char *)curblk);
	if (write(ar, tpblk, bytes) != bytes)
		sysfatal("error writing archive: %r");
}

static void
putblk(int ar)
{
	if (curblk >= endblk)
		putlastblk(ar);
}

static void
putbackblk(int ar)
{
	curblk--;
	USED(ar);
}

static void
putreadblks(int ar, int blks)
{
	curblk += blks - 1;
	USED(ar);
}

static void
putblkmany(int ar, int blks)
{
	curblk += blks - 1;
	putblk(ar);
}

/*
 * common routines
 */

/*
 * modifies hp->chksum but restores it; important for the last block of the
 * old archive when updating with `tar rf archive'
 */
long
chksum(Hdr *hp)
{
	int n = Tblock;
	long i = 0;
	uchar *cp = (uchar*)hp;
	char oldsum[sizeof hp->chksum];

	memmove(oldsum, hp->chksum, sizeof oldsum);
	memset(hp->chksum, ' ', sizeof hp->chksum);
	while (n-- > 0)
		i += *cp++;
	memmove(hp->chksum, oldsum, sizeof oldsum);
	return i;
}

static int
isustar(Hdr *hp)
{
	return strcmp(hp->magic, "ustar") == 0;
}

/*
 * s is at most n bytes long, but need not be NUL-terminated.
 * if shorter than n bytes, all bytes after the first NUL must also
 * be NUL.
 */
static int
strnlen(char *s, int n)
{
	return s[n - 1] != '\0'? n: strlen(s);
}

/* set fullname from header */
static char *
name(Hdr *hp)
{
	int pfxlen, namlen;
	static char fullnamebuf[2 + Maxname + 1];	/* 2 at beginning for ./ on relative names */
	char *fullname;

	fullname = fullnamebuf+2;
	namlen = strnlen(hp->name, sizeof hp->name);
	if (hp->prefix[0] == '\0' || !isustar(hp)) {	/* old-style name? */
		memmove(fullname, hp->name, namlen);
		fullname[namlen] = '\0';
		return fullname;
	}

	/* name is in two pieces */
	pfxlen = strnlen(hp->prefix, sizeof hp->prefix);
	memmove(fullname, hp->prefix, pfxlen);
	fullname[pfxlen] = '/';
	memmove(fullname + pfxlen + 1, hp->name, namlen);
	fullname[pfxlen + 1 + namlen] = '\0';
	return fullname;
}

static int
isdir(Hdr *hp)
{
	/* the mode test is ugly but sometimes necessary */
	return hp->linkflag == LF_DIR ||
		strrchr(name(hp), '\0')[-1] == '/' ||
		(strtoul(hp->mode, nil, 8)&0170000) == 040000;
}

static int
eotar(Hdr *hp)
{
	return name(hp)[0] == '\0';
}

Off
hdrsize(Hdr *hp)
{
	Off bytes = strtoull(hp->size, nil, 8);

	if(isdir(hp))
		bytes = 0;
	return bytes;
}

static Hdr *
readhdr(int ar)
{
	long hdrcksum;
	Hdr *hp;

	hp = getblkrd(ar, Alldata);
	if (hp == nil)
		sysfatal("unexpected EOF instead of archive header");
	if (eotar(hp))			/* end-of-archive block? */
		return nil;
	hdrcksum = strtoul(hp->chksum, nil, 8);
	if (chksum(hp) != hdrcksum)
		sysfatal("bad archive header checksum: name %.64s...",
			hp->name);
	nexthdr += Tblock*(1 + BYTES2TBLKS(hdrsize(hp)));
	return hp;
}

/*
 * tar r[c]
 */

/*
 * if name is longer than Namsiz bytes, try to split it at a slash and fit the
 * pieces into hp->prefix and hp->name.
 */
static int
putfullname(Hdr *hp, char *name)
{
	int namlen, pfxlen;
	char *sl, *osl;
	String *slname = nil;

	if (isdir(hp)) {
		slname = s_new();
		s_append(slname, name);
		s_append(slname, "/");		/* posix requires this */
		name = s_to_c(slname);
	}

	namlen = strlen(name);
	if (namlen <= Namsiz) {
		strncpy(hp->name, name, Namsiz);
		hp->prefix[0] = '\0';		/* ustar paranoia */
		return 0;
	}

	if (!posix || namlen > Maxname) {
		fprint(2, "%s: name too long for tar header: %s\n",
			argv0, name);
		return -1;
	}
	/*
	 * try various splits until one results in pieces that fit into the
	 * appropriate fields of the header.  look for slashes from right
	 * to left, in the hopes of putting the largest part of the name into
	 * hp->prefix, which is larger than hp->name.
	 */
	sl = strrchr(name, '/');
	while (sl != nil) {
		pfxlen = sl - name;
		if (pfxlen <= sizeof hp->prefix && namlen-1 - pfxlen <= Namsiz)
			break;
		osl = sl;
		*osl = '\0';
		sl = strrchr(name, '/');
		*osl = '/';
	}
	if (sl == nil) {
		fprint(2, "%s: name can't be split to fit tar header: %s\n",
			argv0, name);
		return -1;
	}
	*sl = '\0';
	strncpy(hp->prefix, name, sizeof hp->prefix);
	*sl++ = '/';
	strncpy(hp->name, sl, sizeof hp->name);
	if (slname)
		s_free(slname);
	return 0;
}

static int
mkhdr(Hdr *hp, Dir *dir, char *file)
{
	/*
	 * these fields run together, so we format them in order and don't use
	 * snprint.
	 */
	sprint(hp->mode, "%6lo ", dir->mode & 0777);
	sprint(hp->uid, "%6o ", aruid);
	sprint(hp->gid, "%6o ", argid);
	/*
	 * files > 2⁳⁳ bytes can't be described
	 * (unless we resort to xustar or exustar formats).
	 */
	if (dir->length >= (Off)1<<33) {
		fprint(2, "%s: %s: too large for tar header format\n",
			argv0, file);
		return -1;
	}
	sprint(hp->size, "%11lluo ", dir->length);
	sprint(hp->mtime, "%11luo ", dir->mtime);
	hp->linkflag = (dir->mode&DMDIR? LF_DIR: LF_PLAIN1);
	putfullname(hp, file);
	if (posix) {
		strncpy(hp->magic, "ustar", sizeof hp->magic);
		strncpy(hp->version, "00", sizeof hp->version);
		strncpy(hp->uname, dir->uid, sizeof hp->uname);
		strncpy(hp->gname, dir->gid, sizeof hp->gname);
	}
	sprint(hp->chksum, "%6luo", chksum(hp));
	return 0;
}

static void addtoar(int ar, char *file, char *shortf);

static void
addtreetoar(int ar, char *file, char *shortf, int fd)
{
	int n;
	Dir *dent, *dirents;
	String *name = s_new();

	n = dirreadall(fd, &dirents);
	close(fd);
	if (n == 0)
		return;

	if (chdir(shortf) < 0)
		sysfatal("chdir %s: %r", file);
	if (DEBUG)
		fprint(2, "chdir %s\t# %s\n", shortf, file);

	for (dent = dirents; dent < dirents + n; dent++) {
		s_reset(name);
		s_append(name, file);
		s_append(name, "/");
		s_append(name, dent->name);
		addtoar(ar, s_to_c(name), dent->name);
	}
	s_free(name);
	free(dirents);

	/*
	 * this assumes that shortf is just one component, which is true
	 * during directory descent, but not necessarily true of command-line
	 * arguments.  Our caller (or addtoar's) must reset the working
	 * directory if necessary.
	 */
	if (chdir("..") < 0)
		sysfatal("chdir %s/..: %r", file);
	if (DEBUG)
		fprint(2, "chdir ..\n");
}

static void
addtoar(int ar, char *file, char *shortf)
{
	int n, fd, isdir;
	long bytes;
	ulong blksleft, blksread;
	Hdr *hbp;
	Dir *dir;

	fd = open(shortf, OREAD);
	if (fd < 0) {
		fprint(2, "%s: can't open %s: %r\n", argv0, file);
		return;
	}
	dir = dirfstat(fd);
	if (dir == nil)
		sysfatal("can't fstat %s: %r", file);

	hbp = getblkz(ar);
	isdir = !!(dir->qid.type&QTDIR);
	if (mkhdr(hbp, dir, file) < 0) {
		putbackblk(ar);
		free(dir);
		close(fd);
		return;
	}
	putblk(ar);

	blksleft = BYTES2TBLKS(dir->length);
	free(dir);

	if (isdir)
		addtreetoar(ar, file, shortf, fd);
	else {
		for (; blksleft > 0; blksleft -= blksread) {
			hbp = getblke(ar);
			blksread = gothowmany(blksleft);
			bytes = blksread * Tblock;
			n = readn(fd, hbp, bytes);
			if (n < 0)
				sysfatal("error reading %s: %r", file);
			/*
			 * ignore EOF.  zero any partial block to aid
			 * compression and emergency recovery of data.
			 */
			if (n < Tblock)
				memset((uchar*)hbp + n, 0, bytes - n);
			putblkmany(ar, blksread);
		}
		close(fd);
		if (verbose)
			fprint(2, "%s\n", file);
	}
}

static char *
replace(char **argv)
{
	int i, ar;
	ulong blksleft, blksread;
	Off bytes;
	Hdr *hp;
	Compress *comp = nil;
	Pushstate ps;

	if (usefile && docreate) {
		ar = create(usefile, OWRITE, 0666);
		if (docompress)
			comp = compmethod(usefile);
	} else if (usefile)
		ar = open(usefile, ORDWR);
	else
		ar = Stdout;
	if (comp)
		ar = push(ar, comp->comp, Output, &ps);
	if (ar < 0)
		sysfatal("can't open archive %s: %r", usefile);

	if (usefile && !docreate) {
		/* skip quickly to the end */
		while ((hp = readhdr(ar)) != nil) {
			bytes = hdrsize(hp);
			for (blksleft = BYTES2TBLKS(bytes);
			     blksleft > 0 && getblkrd(ar, Justnxthdr) != nil;
			     blksleft -= blksread) {
				blksread = gothowmany(blksleft);
				putreadblks(ar, blksread);
			}
		}
		/*
		 * we have just read the end-of-archive Tblock.
		 * now seek back over the (big) archive block containing it,
		 * and back up curblk ptr over end-of-archive Tblock in memory.
		 */
		if (seek(ar, blkoff, 0) < 0)
			sysfatal("can't seek back over end-of-archive: %r");
		curblk--;
	}

	for (i = 0; argv[i] != nil; i++) {
		addtoar(ar, argv[i], argv[i]);
		chdir(origdir);		/* for correctness & profiling */
	}

	/* write end-of-archive marker */
	getblkz(ar);
	putblk(ar);
	getblkz(ar);
	putlastblk(ar);

	if (comp)
		return pushclose(&ps);
	if (ar > Stderr)
		close(ar);
	return nil;
}

/*
 * tar [xt]
 */

/* is pfx a file-name prefix of name? */
static int
prefix(char *name, char *pfx)
{
	int pfxlen = strlen(pfx);
	char clpfx[Maxname+1];

	if (pfxlen > Maxname)
		return 0;
	strcpy(clpfx, pfx);
	cleanname(clpfx);
	return strncmp(pfx, name, pfxlen) == 0 &&
		(name[pfxlen] == '\0' || name[pfxlen] == '/');
}

static int
match(char *name, char **argv)
{
	int i;
	char clname[Maxname+1];

	if (argv[0] == nil)
		return 1;
	strcpy(clname, name);
	cleanname(clname);
	for (i = 0; argv[i] != nil; i++)
		if (prefix(clname, argv[i]))
			return 1;
	return 0;
}

static int
makedir(char *s)
{
	int f;

	if (access(s, AEXIST) == 0)
		return -1;
	f = create(s, OREAD, DMDIR | 0777);
	if (f >= 0)
		close(f);
	return f;
}

static void
mkpdirs(char *s)
{
	int done = 0;
	char *p = s;

	while (!done && (p = strchr(p + 1, '/')) != nil) {
		*p = '\0';
		done = (access(s, AEXIST) < 0 && makedir(s) < 0);
		*p = '/';
	}
}

/* copy a file from the archive into the filesystem */
/* fname is result of name(), so has two extra bytes at beginning */
static void
extract1(int ar, Hdr *hp, char *fname)
{
	int wrbytes, fd = -1, dir = 0;
	long mtime = strtol(hp->mtime, nil, 8);
	ulong mode = strtoul(hp->mode, nil, 8) & 0777;
	Off bytes  = strtoll(hp->size, nil, 8);		/* for printing */
	ulong blksread, blksleft = BYTES2TBLKS(hdrsize(hp));
	Hdr *hbp;

	if (isdir(hp)) {
		mode |= DMDIR|0700;
		dir = 1;
	}
	switch (hp->linkflag) {
	case LF_LINK:
	case LF_SYMLINK1:
	case LF_SYMLINK2:
	case LF_FIFO:
		blksleft = 0;
		break;
	}
	if (relative) {
		if(fname[0] == '/')
			*--fname = '.';
		else if(fname[0] == '#'){
			*--fname = '/';
			*--fname = '.';
		}
	}
	if (verb == Xtract) {
		cleanname(fname);
		switch (hp->linkflag) {
		case LF_LINK:
		case LF_SYMLINK1:
		case LF_SYMLINK2:
			fprint(2, "%s: can't make (sym)link %s\n",
				argv0, fname);
			break;
		case LF_FIFO:
			fprint(2, "%s: can't make fifo %s\n", argv0, fname);
			break;
		default:
			if (!keepexisting || access(fname, AEXIST) < 0) {
				int rw = (dir? OREAD: OWRITE);

				fd = create(fname, rw, mode);
				if (fd < 0) {
					mkpdirs(fname);
					fd = create(fname, rw, mode);
				}
				if (fd < 0 &&
				    (!dir || access(fname, AEXIST) < 0))
					fprint(2, "%s: can't create %s: %r\n",
						argv0, fname);
			}
			if (fd >= 0 && verbose)
				fprint(2, "%s\n", fname);
			break;
		}
	} else if (verbose) {
		char *cp = ctime(mtime);

		print("%M %8lld %-12.12s %-4.4s %s\n",
			mode, bytes, cp+4, cp+24, fname);
	} else
		print("%s\n", fname);

	for (; blksleft > 0; blksleft -= blksread) {
		hbp = getblkrd(ar, (fd >= 0? Alldata: Justnxthdr));
		if (hbp == nil)
			sysfatal("unexpected EOF on archive extracting %s",
				fname);
		blksread = gothowmany(blksleft);
		wrbytes = Tblock*blksread;
		if(wrbytes > bytes)
			wrbytes = bytes;
		if (fd >= 0 && write(fd, hbp, wrbytes) != wrbytes)
			sysfatal("write error on %s: %r", fname);
		putreadblks(ar, blksread);
		bytes -= wrbytes;
	}
	if (fd >= 0) {
		/*
		 * directories should be wstated after we're done
		 * creating files in them.
		 */
		if (settime) {
			Dir nd;

			nulldir(&nd);
			nd.mtime = mtime;
			if (isustar(hp))
				nd.gid = hp->gname;
			dirfwstat(fd, &nd);
		}
		close(fd);
	}
}

static void
skip(int ar, Hdr *hp, char *fname)
{
	ulong blksleft, blksread;
	Hdr *hbp;

	for (blksleft = BYTES2TBLKS(hdrsize(hp)); blksleft > 0;
	     blksleft -= blksread) {
		hbp = getblkrd(ar, Justnxthdr);
		if (hbp == nil)
			sysfatal("unexpected EOF on archive extracting %s",
				fname);
		blksread = gothowmany(blksleft);
		putreadblks(ar, blksread);
	}
}

static char *
extract(char **argv)
{
	int ar;
	char *longname;
	Hdr *hp;
	Compress *comp = nil;
	Pushstate ps;

	if (usefile) {
		ar = open(usefile, OREAD);
		comp = compmethod(usefile);
	} else
		ar = Stdin;
	if (comp)
		ar = push(ar, comp->decomp, Input, &ps);
	if (ar < 0)
		sysfatal("can't open archive %s: %r", usefile);

	while ((hp = readhdr(ar)) != nil) {
		longname = name(hp);
		if (match(longname, argv))
			extract1(ar, hp, longname);
		else
			skip(ar, hp, longname);
	}

	if (comp)
		return pushclose(&ps);
	if (ar > Stderr)
		close(ar);
	return nil;
}

void
main(int argc, char *argv[])
{
	int errflg = 0;
	char *ret = nil;

	quotefmtinstall();
	fmtinstall('M', dirmodefmt);

	TARGBEGIN {
	case 'c':
		docreate++;
		verb = Replace;
		break;
	case 'f':
		usefile = EARGF(usage());
		break;
	case 'g':
		argid = strtoul(EARGF(usage()), 0, 0);
		break;
	case 'k':
		keepexisting++;
		break;
	case 'm':	/* compatibility */
		settime = 0;
		break;
	case 'p':
		posix++;
		break;
	case 'P':
		posix = 0;
		break;
	case 'r':
		verb = Replace;
		break;
	case 'R':
		relative = 0;
		break;
	case 't':
		verb = Toc;
		break;
	case 'T':
		settime++;
		break;
	case 'u':
		aruid = strtoul(EARGF(usage()), 0, 0);
		break;
	case 'v':
		verbose++;
		break;
	case 'x':
		verb = Xtract;
		break;
	case 'z':
		docompress++;
		break;
	case '-':
		break;
	default:
		fprint(2, "tar: unknown letter %C\n", TARGC());
		errflg++;
		break;
	} TARGEND

	if (argc < 0 || errflg)
		usage();

	initblks();
	switch (verb) {
	case Toc:
	case Xtract:
		ret = extract(argv);
		break;
	case Replace:
		if (getwd(origdir, sizeof origdir) == nil)
			strcpy(origdir, "/tmp");
		ret = replace(argv);
		break;
	default:
		usage();
		break;
	}
	exits(ret);
}
