tar: add support for compressing with an external tool
... and add xz, compress and lzma as options
This commit is contained in:
parent
7dff7d4c83
commit
1d9d17eba2
13
tar.1
13
tar.1
|
@ -7,12 +7,13 @@
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl C Ar dir
|
.Op Fl C Ar dir
|
||||||
.Op Fl j | Fl z
|
.Op Fl J | Fl Z | Fl a | Fl j | Fl z
|
||||||
.Fl x Op Fl m | Fl t
|
.Fl x Op Fl m | Fl t
|
||||||
.Op Fl f Ar file
|
.Op Fl f Ar file
|
||||||
.Op Ar file ...
|
.Op Ar file ...
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl C Ar dir
|
.Op Fl C Ar dir
|
||||||
|
.Op Fl J | Fl Z | Fl a | Fl j | Fl z
|
||||||
.Op Fl h
|
.Op Fl h
|
||||||
.Fl c Ar path ...
|
.Fl c Ar path ...
|
||||||
.Op Fl f Ar file
|
.Op Fl f Ar file
|
||||||
|
@ -40,16 +41,14 @@ List all files in the archive.
|
||||||
Extract archive.
|
Extract archive.
|
||||||
.It Fl h
|
.It Fl h
|
||||||
Always dereference symbolic links while recursively traversing directories.
|
Always dereference symbolic links while recursively traversing directories.
|
||||||
.It Fl j | Fl z
|
.It Fl J | Fl Z | Fl a | Fl j | Fl z
|
||||||
Use bzip2 | gzip decompression. The
|
Use xz | compress | lzma | bzip2 | gzip decompression. These
|
||||||
.Xr bzip2 1 |
|
|
||||||
.Xr gzip 1
|
|
||||||
utilities must be installed separately.
|
utilities must be installed separately.
|
||||||
Using these flags is discouraged in favour of the flexibility
|
Using these flags is discouraged in favour of the flexibility
|
||||||
and clarity of pipes:
|
and clarity of pipes:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
$ bzcat archive.tar.bz2 | tar -x
|
$ bzip2 -cd archive.tar.bz2 | tar -x
|
||||||
$ zcat archive.tar.gz | tar -x
|
$ gzip -cd archive.tar.gz | tar -x
|
||||||
.Ed
|
.Ed
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
$ tar -c file ... | bzip2 > archive.tar.bz2
|
$ tar -c file ... | bzip2 > archive.tar.bz2
|
||||||
|
|
65
tar.c
65
tar.c
|
@ -67,6 +67,15 @@ static dev_t tardev;
|
||||||
|
|
||||||
static int mflag, vflag;
|
static int mflag, vflag;
|
||||||
static int filtermode;
|
static int filtermode;
|
||||||
|
static const char *filtertool;
|
||||||
|
|
||||||
|
static const char *filtertools[] = {
|
||||||
|
['J'] = "xz",
|
||||||
|
['Z'] = "compress",
|
||||||
|
['a'] = "lzma",
|
||||||
|
['j'] = "bzip2",
|
||||||
|
['z'] = "gzip",
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pushent(char *name, time_t mtime)
|
pushent(char *name, time_t mtime)
|
||||||
|
@ -88,10 +97,34 @@ popent(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
decomp(int fd)
|
comp(int fd, const char *tool, const char *flags)
|
||||||
|
{
|
||||||
|
int fds[2];
|
||||||
|
|
||||||
|
if (pipe(fds) < 0)
|
||||||
|
eprintf("pipe:");
|
||||||
|
|
||||||
|
switch (fork()) {
|
||||||
|
case -1:
|
||||||
|
eprintf("fork:");
|
||||||
|
case 0:
|
||||||
|
dup2(fd, 1);
|
||||||
|
dup2(fds[0], 0);
|
||||||
|
close(fds[0]);
|
||||||
|
close(fds[1]);
|
||||||
|
|
||||||
|
execlp(tool, tool, flags, NULL);
|
||||||
|
weprintf("execlp %s:", tool);
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
close(fds[0]);
|
||||||
|
return fds[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
decomp(int fd, const char *tool, const char *flags)
|
||||||
{
|
{
|
||||||
int fds[2];
|
int fds[2];
|
||||||
char *tool;
|
|
||||||
|
|
||||||
if (pipe(fds) < 0)
|
if (pipe(fds) < 0)
|
||||||
eprintf("pipe:");
|
eprintf("pipe:");
|
||||||
|
@ -105,8 +138,7 @@ decomp(int fd)
|
||||||
close(fds[0]);
|
close(fds[0]);
|
||||||
close(fds[1]);
|
close(fds[1]);
|
||||||
|
|
||||||
tool = (filtermode == 'j') ? "bzip2" : "gzip";
|
execlp(tool, tool, flags, NULL);
|
||||||
execlp(tool, tool, "-cd", NULL);
|
|
||||||
weprintf("execlp %s:", tool);
|
weprintf("execlp %s:", tool);
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
@ -390,7 +422,7 @@ bad:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xt(int argc, char *argv[], int (*fn)(char *, ssize_t, char[BLKSIZ]))
|
xt(int argc, char *argv[], int mode)
|
||||||
{
|
{
|
||||||
char b[BLKSIZ], fname[256 + 1], *p;
|
char b[BLKSIZ], fname[256 + 1], *p;
|
||||||
struct timeval times[2];
|
struct timeval times[2];
|
||||||
|
@ -398,6 +430,7 @@ xt(int argc, char *argv[], int (*fn)(char *, ssize_t, char[BLKSIZ]))
|
||||||
struct ent *ent;
|
struct ent *ent;
|
||||||
long size;
|
long size;
|
||||||
int i, n;
|
int i, n;
|
||||||
|
int (*fn)(char *, ssize_t, char[BLKSIZ]) = (mode == 'x') ? unarchive : print;
|
||||||
|
|
||||||
while (eread(tarfd, b, BLKSIZ) > 0 && h->name[0]) {
|
while (eread(tarfd, b, BLKSIZ) > 0 && h->name[0]) {
|
||||||
chktar(h);
|
chktar(h);
|
||||||
|
@ -451,8 +484,8 @@ xt(int argc, char *argv[], int (*fn)(char *, ssize_t, char[BLKSIZ]))
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
eprintf("usage: %s [-C dir] [-j | -z] -x [-m | -t] [-f file] [file ...]\n"
|
eprintf("usage: %s [-C dir] [-J | -Z | -a | -j | -z] -x [-m | -t] [-f file] [file ...]\n"
|
||||||
" %s [-C dir] [-h] -c path ... [-f file]\n", argv0, argv0);
|
" %s [-C dir] [-J | -Z | -a | -j | -z] [-h] -c path ... [-f file]\n", argv0, argv0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -479,9 +512,13 @@ main(int argc, char *argv[])
|
||||||
case 'm':
|
case 'm':
|
||||||
mflag = 1;
|
mflag = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'J':
|
||||||
|
case 'Z':
|
||||||
|
case 'a':
|
||||||
case 'j':
|
case 'j':
|
||||||
case 'z':
|
case 'z':
|
||||||
filtermode = ARGC();
|
filtermode = ARGC();
|
||||||
|
filtertool = filtertools[filtermode];
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
r.follow = 'L';
|
r.follow = 'L';
|
||||||
|
@ -496,7 +533,7 @@ main(int argc, char *argv[])
|
||||||
if (!mode)
|
if (!mode)
|
||||||
usage();
|
usage();
|
||||||
if (mode == 'c')
|
if (mode == 'c')
|
||||||
if (!argc || filtermode)
|
if (!argc)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
@ -512,6 +549,9 @@ main(int argc, char *argv[])
|
||||||
tardev = st.st_dev;
|
tardev = st.st_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filtertool)
|
||||||
|
tarfd = comp(tarfd, filtertool, "-cf");
|
||||||
|
|
||||||
if (chdir(dir) < 0)
|
if (chdir(dir) < 0)
|
||||||
eprintf("chdir %s:", dir);
|
eprintf("chdir %s:", dir);
|
||||||
for (; *argv; argc--, argv++)
|
for (; *argv; argc--, argv++)
|
||||||
|
@ -526,18 +566,15 @@ main(int argc, char *argv[])
|
||||||
eprintf("open %s:", file);
|
eprintf("open %s:", file);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (filtermode) {
|
if (filtertool) {
|
||||||
case 'j':
|
|
||||||
case 'z':
|
|
||||||
fd = tarfd;
|
fd = tarfd;
|
||||||
tarfd = decomp(tarfd);
|
tarfd = decomp(tarfd, filtertool, "-cd");
|
||||||
close(fd);
|
close(fd);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chdir(dir) < 0)
|
if (chdir(dir) < 0)
|
||||||
eprintf("chdir %s:", dir);
|
eprintf("chdir %s:", dir);
|
||||||
xt(argc, argv, (mode == 'x') ? unarchive : print);
|
xt(argc, argv, mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user