diff --git a/src/cmd/tar.c b/src/cmd/tar.c
new file mode 100644
index 0000000..aabc25e
--- /dev/null
+++ b/src/cmd/tar.c
@@ -0,0 +1,1043 @@
+/*
+ * 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 <String.h>
+
+/*
+ * modified versions of those in libc.h; scans only the first arg for
+ * keyletters and options.
+ */
+#define	TARGBEGIN {\
+	(argv0 || (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 union {
+	uchar	data[Tblock];
+	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->data, 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 = hp->data;
+	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->data, 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(hbp->data + 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->data, 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);
+}
