[PATCH] dpkg-deb: add .xz compression support
Use the xz command to support xz-compressed binary packages.
(dpkg-source already does this for source packages.)
The xz format is very similar to the lzma format, but it fixes
some omissions in the latter, most notably a magic number for
identification by file(1).
Do not update the Debian packaging dependencies for xz support,
since they will have to be updated again anyway to use liblzma.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
This patch requires the memory limit and default compression
level patches to apply. Please let me know if you'd like a
version that applies without them.
dpkg-deb/build.c | 3 +++
dpkg-deb/dpkg-deb.h | 2 ++
dpkg-deb/extract.c | 5 +++++
dpkg-deb/main.c | 5 ++++-
lib/dpkg/compression-backend.c | 15 +++++++++++++++
lib/dpkg/compression-backend.h | 4 ++++
lib/dpkg/compression.c | 4 ++++
lib/dpkg/dpkg.h | 2 ++
man/deb.5 | 5 +++--
man/dpkg-deb.1 | 4 ++--
scripts/dpkg-buildpackage.pl | 2 +-
11 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/dpkg-deb/build.c b/dpkg-deb/build.c
index daaf1f9..a046f3c 100644
--- a/dpkg-deb/build.c
+++ b/dpkg-deb/build.c
@@ -546,6 +546,9 @@ void do_build(const char *const *argv) {
case compress_type_lzma:
datamember = DATAMEMBER_LZMA;
break;
+ case compress_type_xz:
+ datamember = DATAMEMBER_XZ;
+ break;
case compress_type_cat:
datamember = DATAMEMBER_CAT;
break;
diff --git a/dpkg-deb/dpkg-deb.h b/dpkg-deb/dpkg-deb.h
index edb8a8f..e3b2492 100644
--- a/dpkg-deb/dpkg-deb.h
+++ b/dpkg-deb/dpkg-deb.h
@@ -65,6 +65,8 @@ extern uint64_t compress_memlimit;
#define DATAMEMBER_COMPAT_BZ2 "data.tar.bz2/ "
#define DATAMEMBER_LZMA "data.tar.lzma "
#define DATAMEMBER_COMPAT_LZMA "data.tar.lzma/ "
+#define DATAMEMBER_XZ "data.tar.xz "
+#define DATAMEMBER_COMPAT_XZ "data.tar.xz/ "
#define DATAMEMBER_CAT "data.tar "
#define DATAMEMBER_COMPAT_CAT "data.tar/ "
diff --git a/dpkg-deb/extract.c b/dpkg-deb/extract.c
index f0abce8..067f910 100644
--- a/dpkg-deb/extract.c
+++ b/dpkg-deb/extract.c
@@ -185,6 +185,11 @@ void extracthalf(const char *debar, const char *directory,
!memcmp(arh.ar_name, DATAMEMBER_COMPAT_LZMA, sizeof(arh.ar_name))) {
adminmember = 0;
compress_type = compress_type_lzma;
+ } else if (!memcmp(arh.ar_name, DATAMEMBER_XZ, sizeof(arh.ar_name)) ||
+ !memcmp(arh.ar_name, DATAMEMBER_COMPAT_XZ,
+ sizeof(arh.ar_name))) {
+ adminmember = 0;
+ compress_type = compress_type_xz;
} else if (!memcmp(arh.ar_name,DATAMEMBER_CAT,sizeof(arh.ar_name)) ||
!memcmp(arh.ar_name,DATAMEMBER_COMPAT_CAT,sizeof(arh.ar_name))) {
adminmember= 0;
diff --git a/dpkg-deb/main.c b/dpkg-deb/main.c
index 0f2ef19..7721a3a 100644
--- a/dpkg-deb/main.c
+++ b/dpkg-deb/main.c
@@ -107,7 +107,8 @@ usage(const struct cmdinfo *cip, const char *value)
" packages).\n"
" -z# Set the compression level when building.\n"
" -Z<type> Set the compression type used when building.\n"
-" Allowed values: gzip, bzip2, lzma, none.\n"
+" Allowed values: gzip, bzip2, lzma, xz,\n"
+" none.\n"
" -M, --memlimit=<bytes> Set the memory usage limit used when\n"
" examining lzma compressed packages.\n"
"\n"));
@@ -206,6 +207,8 @@ static void setcompresstype(const struct cmdinfo *cip, const char *value) {
compress_type = compress_type_bzip2;
else if (!strcmp(value, "lzma"))
compress_type = compress_type_lzma;
+ else if (!strcmp(value, "xz"))
+ compress_type = compress_type_xz;
else if (!strcmp(value, "none"))
compress_type = compress_type_cat;
else
diff --git a/lib/dpkg/compression-backend.c b/lib/dpkg/compression-backend.c
index 3cf561b..5932aca 100644
--- a/lib/dpkg/compression-backend.c
+++ b/lib/dpkg/compression-backend.c
@@ -289,6 +289,21 @@ compress_lzma(int fd_in, int fd_out, char compression, const char *desc)
}
void
+decompress_xz(int fd_in, int fd_out, uint64_t memlimit, const char *desc)
+{
+ if (memlimit == 0)
+ memlimit = default_memlimit();
+
+ fd_fd_filter(fd_in, fd_out, desc, XZ, "xz", "-dcM%" PRIu64, memlimit);
+}
+
+void
+compress_xz(int fd_in, int fd_out, char compression, const char *desc)
+{
+ compress_cmd(fd_in, fd_out, XZ, "xz", compression, desc);
+}
+
+void
decompress_noop(int fd_in, int fd_out, const char *desc)
{
fd_fd_copy(fd_in, fd_out, -1, _("%s: decompression"), desc);
diff --git a/lib/dpkg/compression-backend.h b/lib/dpkg/compression-backend.h
index 86c55f2..8caba73 100644
--- a/lib/dpkg/compression-backend.h
+++ b/lib/dpkg/compression-backend.h
@@ -22,6 +22,8 @@ void decompress_bzip2(int fd_in, int fd_out, const char *desc)
DPKG_ATTR_NORET;
void decompress_lzma(int fd_in, int fd_out, uint64_t memlimit,
const char *desc) DPKG_ATTR_NORET;
+void decompress_xz(int fd_in, int fd_out, uint64_t memlimit,
+ const char *desc) DPKG_ATTR_NORET;
void decompress_noop(int fd_in, int fd_out, const char *desc)
DPKG_ATTR_NORET;
@@ -31,6 +33,8 @@ void compress_bzip2(int fd_in, int fd_out,
char compression, const char *desc) DPKG_ATTR_NORET;
void compress_lzma(int fd_in, int fd_out,
char compression, const char *desc) DPKG_ATTR_NORET;
+void compress_xz(int fd_in, int fd_out,
+ char compression, const char *desc) DPKG_ATTR_NORET;
void compress_noop(int fd_in, int fd_out,
const char *desc) DPKG_ATTR_NORET;
diff --git a/lib/dpkg/compression.c b/lib/dpkg/compression.c
index 61068be..664c1c0 100644
--- a/lib/dpkg/compression.c
+++ b/lib/dpkg/compression.c
@@ -25,6 +25,8 @@ void decompress_cat(enum compress_type type, int fd_in, int fd_out,
decompress_bzip2(fd_in, fd_out, v.buf);
case compress_type_lzma:
decompress_lzma(fd_in, fd_out, memlimit, v.buf);
+ case compress_type_xz:
+ decompress_xz(fd_in, fd_out, memlimit, v.buf);
case compress_type_cat:
decompress_noop(fd_in, fd_out, v.buf);
default:
@@ -51,6 +53,8 @@ void compress_cat(enum compress_type type, int fd_in, int fd_out, const char *co
compress_bzip2(fd_in, fd_out, *compression, v.buf);
case compress_type_lzma:
compress_lzma(fd_in, fd_out, *compression, v.buf);
+ case compress_type_xz:
+ compress_xz(fd_in, fd_out, *compression, v.buf);
case compress_type_cat:
compress_noop(fd_in, fd_out, v.buf);
default:
diff --git a/lib/dpkg/dpkg.h b/lib/dpkg/dpkg.h
index 94a5214..6d4ad50 100644
--- a/lib/dpkg/dpkg.h
+++ b/lib/dpkg/dpkg.h
@@ -112,6 +112,7 @@ DPKG_BEGIN_DECLS
#define GZIP "gzip"
#define BZIP2 "bzip2"
#define LZMA "lzma"
+#define XZ "xz"
#define RM "rm"
#define FIND "find"
#define DIFF "diff"
@@ -222,6 +223,7 @@ enum compress_type {
compress_type_gzip,
compress_type_bzip2,
compress_type_lzma,
+ compress_type_xz,
};
void decompress_cat(enum compress_type type, int fd_in, int fd_out,
diff --git a/man/deb.5 b/man/deb.5
index c51ed12..159ea49 100644
--- a/man/deb.5
+++ b/man/deb.5
@@ -56,8 +56,9 @@ The third, last required member is named
It contains the filesystem as a tar archive, either
not compressed (supported since dpkg 1.10.24), or compressed with
gzip (with \fB.gz\fP extension),
-bzip2 (with \fB.bz2\fP extension, supported since dpkg 1.10.24) or
-lzma (with \fB.lzma\fP extension, supported since dpkg 1.13.25).
+bzip2 (with \fB.bz2\fP extension, supported since dpkg 1.10.24),
+lzma (with \fB.lzma\fP extension, supported since dpkg 1.13.25) or
+xz (with \fB.xz\fP extension, supported since dpkg 1.15.5).
.PP
These members must occur in this exact order. Current implementations
should ignore any additional members after
diff --git a/man/dpkg-deb.1 b/man/dpkg-deb.1
index 37b43b3..53c39f0 100644
--- a/man/dpkg-deb.1
+++ b/man/dpkg-deb.1
@@ -194,8 +194,8 @@ when building a package.
.TP
.BI \-Z compress_type
Specify which compression type to use when building a package. Allowed
-values are \fIgzip\fP, \fIbzip2\fP, \fIlzma\fP, and \fInone\fP (default
-is \fIgzip\fP).
+values are \fIgzip\fP, \fIbzip2\fP, \fIlzma\fP, \fIxz\fP, and \fInone\fP
+(default is \fIgzip\fP).
.TP
.BR \-M ", " \-\-memlimit= \fImemory_limit\fP
Specify a maximum in bytes for memory usage when decompressing an lzma
diff --git a/scripts/dpkg-buildpackage.pl b/scripts/dpkg-buildpackage.pl
index 6e383c6..71f4fbc 100755
--- a/scripts/dpkg-buildpackage.pl
+++ b/scripts/dpkg-buildpackage.pl
@@ -67,7 +67,7 @@ Options:
-sn force Debian native source format. }
-s[sAkurKUR] see dpkg-source for explanation. } only passed
-z<level> compression level of source } to dpkg-source
- -Z(gz|bz2|lzma) compression to use for source }
+ -Z(gz|bz2|lzma|xz) compression to use for source }
-nc do not clean source tree (implies -b).
-tc clean source tree when finished.
-ap add pause before starting signature process.
--
1.6.5.rc1.199.g596ec
Reply to: