]> git.ipfire.org Git - pakfire.git/commitdiff
compress: Add transparent gzip compression
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 30 Jan 2025 08:17:22 +0000 (08:17 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 30 Jan 2025 08:25:34 +0000 (08:25 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Jenkinsfile
Makefile.am
debian/control
src/pakfire/compress.c
src/pakfire/compress.h
tests/data/compress/data.gz [new file with mode: 0644]
tests/libpakfire/compress.c

index 224eb31c19a3dcf7712f13a276ae859dbe1636ec..d69b15978c04a97ea6085f81456224416db5664e 100644 (file)
@@ -568,7 +568,8 @@ def installBuildDepsRedHat(distro, compier) {
                        python3-devel \
                        sqlite-devel \
                        systemd-devel \
-                       xz-devel
+                       xz-devel \
+                       zlib-devel
        """
 }
 
@@ -604,7 +605,8 @@ def installBuildDepsArchLinux(distro, compiler) {
                        systemd \
                        util-linux-libs \
                        xz \
-                       zstd
+                       zstd \
+                       zlib
        """
 }
 
@@ -648,7 +650,8 @@ def installBuildDepsDebian(distro, compiler, arch) {
                        libsqlite3-dev \
                        libsystemd-dev \
                        libzstd-dev \
-                       uuid-dev
+                       uuid-dev \
+                       libz-dev
        """
 }
 
index e28b66cc8d30b4cdffd9d2f997dd11eafce85a71..4f242028753f8863ff1bbb462b9a9f9db9758372 100644 (file)
@@ -1253,6 +1253,7 @@ EXTRA_DIST += \
        tests/data/beep.nm \
        tests/data/kernel.nm \
        \
+       tests/data/compress/data.gz \
        tests/data/compress/data.xz \
        tests/data/compress/data.zst \
        \
index 2754baaed0756aff219a6476ccf254b38a02b0bf..34db9e67530ec4dfdc14ccc1cc046fc3a56ccaf8 100644 (file)
@@ -35,6 +35,7 @@ Build-Depends:
  libzstd-dev,
  pkg-config,
  uuid-dev,
+ libz-dev
 Standards-Version: 4.6.2
 Homepage: https://pakfire.ipfire.org
 Vcs-Browser: https://git.ipfire.org/?p=pakfire.git;a=summary
index 287b2ba1017e6aea551dba5d2572e158bc1c6789..2a3ae4dded893654a12955d3e8b0e09a16df45d4 100644 (file)
@@ -26,6 +26,7 @@
 #include <archive.h>
 #include <lzma.h>
 #include <zstd.h>
+#include <zlib.h>
 
 #include <pakfire/ctx.h>
 #include <pakfire/compress.h>
@@ -121,6 +122,64 @@ FILE* pakfire_xfopen(FILE* f, const char* mode) {
        return f;
 }
 
+/*
+       gzip
+*/
+
+static ssize_t gz_read(void* cookie, char* buffer, size_t size) {
+       return gzread((gzFile)cookie, buffer, size);
+}
+
+static ssize_t gz_write(void* cookie, const char* buffer, size_t size) {
+       return gzwrite((gzFile)cookie, buffer, size);
+}
+
+static int gz_close(void* cookie) {
+       return gzclose((gzFile)cookie);
+}
+
+FILE* pakfire_gzfopen(FILE* f, const char* mode) {
+       gzFile cookie = NULL;
+       int fd = -EBADF;
+
+       // Check for a valid file descriptor
+       if (!f) {
+               errno = EBADF;
+               return NULL;
+       }
+
+       // Fetch the file descriptor
+       fd = fileno(f);
+       if (fd < 0) {
+               errno = EBADF;
+               return NULL;
+       }
+
+       // Duplicate the file descriptor to pass it to gzip
+       fd = dup(fd);
+       if (fd < 0)
+               return NULL;
+
+       // Close the original file handle
+       fclose(f);
+
+       // Open the stream
+       cookie = gzdopen(fd, mode);
+       if (!cookie)
+               return NULL;
+
+       // Increase the buffer size for faster reading
+       gzbuffer(cookie, 128 * 1024);
+
+       static cookie_io_functions_t gz_functions = {
+               .read  = gz_read,
+               .write = gz_write,
+               .close = gz_close,
+       };
+
+       return fopencookie(cookie, mode, gz_functions);
+}
+
 struct xz_cookie {
        FILE* f;
        char mode;
index 88394e214185858112c0c58ce1720be58d4ce84e..f275aebb4569c5b597b2b661b2eac64f1751a40a 100644 (file)
@@ -30,6 +30,9 @@
 // Automatically detect
 FILE* pakfire_xfopen(FILE* f, const char* mode);
 
+// gzip
+FILE* pakfire_gzfopen(FILE* f, const char* mode);
+
 // XZ
 FILE* pakfire_xzfopen(FILE* f, const char* mode);
 
diff --git a/tests/data/compress/data.gz b/tests/data/compress/data.gz
new file mode 100644 (file)
index 0000000..1fc3093
Binary files /dev/null and b/tests/data/compress/data.gz differ
index 557f743a0b0dbdabccea6216b57080193e77f73d..3673f7d6c80b9374fd1588c70fea5c2f7ab1c1f4 100644 (file)
@@ -92,6 +92,14 @@ FAIL:
        return r;
 }
 
+static int test_gzfopen_read(const struct test* t) {
+       return read_test(t, pakfire_gzfopen, "data/compress/data.gz");
+}
+
+static int test_gzfopen_write(const struct test* t) {
+       return write_test(t, pakfire_gzfopen);
+}
+
 static int test_xzfopen_read(const struct test* t) {
        return read_test(t, pakfire_xzfopen, "data/compress/data.xz");
 }
@@ -119,6 +127,10 @@ FAIL:
 }
 
 int main(int argc, const char* argv[]) {
+       // Gzip
+       testsuite_add_test(test_gzfopen_read, 0);
+       testsuite_add_test(test_gzfopen_write, 0);
+
        // XZ
        testsuite_add_test(test_xzfopen_read, 0);
        testsuite_add_test(test_xzfopen_write, 0);