]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
libkmod: Move xz-related functions to separate file
authorLucas De Marchi <lucas.de.marchi@gmail.com>
Tue, 9 Jul 2024 06:08:56 +0000 (01:08 -0500)
committerLucas De Marchi <lucas.de.marchi@gmail.com>
Fri, 26 Jul 2024 18:41:13 +0000 (13:41 -0500)
Move xz-related function to a separate file so it's easier to isolate
the dependency on each decompression library.

Declare struct kmod_file in a shared libkmod-internal-file.h that will
be included only by sources implementing kmod_file decompression
routines.

Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Link: https://github.com/kmod-project/kmod/pull/58
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
Makefile.am
configure.ac
libkmod/libkmod-file-xz.c [new file with mode: 0644]
libkmod/libkmod-file.c
libkmod/libkmod-internal-file.h [new file with mode: 0644]

index 3dc769f0a1241e46933e6f24e6dcb5a3d9690000..fbd205de1cda69ede9bfa12def1442f0b101ab9f 100644 (file)
@@ -63,6 +63,7 @@ lib_LTLIBRARIES = libkmod/libkmod.la
 
 libkmod_libkmod_la_SOURCES = \
        libkmod/libkmod.h \
+       libkmod/libkmod-internal-file.h \
        libkmod/libkmod-internal.h \
        libkmod/libkmod.c \
        libkmod/libkmod-builtin.c \
@@ -75,6 +76,10 @@ libkmod_libkmod_la_SOURCES = \
        libkmod/libkmod-elf.c \
        libkmod/libkmod-signature.c
 
+if ENABLE_XZ
+libkmod_libkmod_la_SOURCES += libkmod/libkmod-file-xz.c
+endif
+
 EXTRA_DIST += libkmod/libkmod.sym
 EXTRA_DIST += libkmod/README \
        libkmod/COPYING testsuite/COPYING tools/COPYING COPYING
index 7ff699d9dfc0dd1b3d8a323a2516d2ea5c45097d..5768e5e7c7d7fce5e9dc20cfa84db17cfc21e69e 100644 (file)
@@ -137,6 +137,7 @@ AS_IF([test "x$with_xz" != "xno"], [
        AC_MSG_NOTICE([Xz support not requested])
 ])
 CC_FEATURE_APPEND([with_features], [with_xz], [XZ])
+AM_CONDITIONAL([ENABLE_XZ], [test "x$with_xz" != "xno"])
 
 AC_ARG_WITH([zlib],
        AS_HELP_STRING([--with-zlib], [handle gzipped modules @<:@default=disabled@:>@]),
diff --git a/libkmod/libkmod-file-xz.c b/libkmod/libkmod-file-xz.c
new file mode 100644 (file)
index 0000000..7285c4b
--- /dev/null
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include <errno.h>
+#include <lzma.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <shared/util.h>
+
+#include "libkmod.h"
+#include "libkmod-internal.h"
+#include "libkmod-internal-file.h"
+
+static void xz_uncompress_belch(struct kmod_file *file, lzma_ret ret)
+{
+       switch (ret) {
+       case LZMA_MEM_ERROR:
+               ERR(file->ctx, "xz: %s\n", strerror(ENOMEM));
+               break;
+       case LZMA_FORMAT_ERROR:
+               ERR(file->ctx, "xz: File format not recognized\n");
+               break;
+       case LZMA_OPTIONS_ERROR:
+               ERR(file->ctx, "xz: Unsupported compression options\n");
+               break;
+       case LZMA_DATA_ERROR:
+               ERR(file->ctx, "xz: File is corrupt\n");
+               break;
+       case LZMA_BUF_ERROR:
+               ERR(file->ctx, "xz: Unexpected end of input\n");
+               break;
+       default:
+               ERR(file->ctx, "xz: Internal error (bug)\n");
+               break;
+       }
+}
+
+static int xz_uncompress(lzma_stream *strm, struct kmod_file *file)
+{
+       uint8_t in_buf[BUFSIZ], out_buf[BUFSIZ];
+       lzma_action action = LZMA_RUN;
+       lzma_ret ret;
+       void *p = NULL;
+       size_t total = 0;
+
+       strm->avail_in  = 0;
+       strm->next_out  = out_buf;
+       strm->avail_out = sizeof(out_buf);
+
+       while (true) {
+               if (strm->avail_in == 0) {
+                       ssize_t rdret = read(file->fd, in_buf, sizeof(in_buf));
+                       if (rdret < 0) {
+                               ret = -errno;
+                               goto out;
+                       }
+                       strm->next_in  = in_buf;
+                       strm->avail_in = rdret;
+                       if (rdret == 0)
+                               action = LZMA_FINISH;
+               }
+               ret = lzma_code(strm, action);
+               if (strm->avail_out == 0 || ret != LZMA_OK) {
+                       size_t write_size = BUFSIZ - strm->avail_out;
+                       char *tmp = realloc(p, total + write_size);
+                       if (tmp == NULL) {
+                               ret = -errno;
+                               goto out;
+                       }
+                       memcpy(tmp + total, out_buf, write_size);
+                       total += write_size;
+                       p = tmp;
+                       strm->next_out = out_buf;
+                       strm->avail_out = BUFSIZ;
+               }
+               if (ret == LZMA_STREAM_END)
+                       break;
+               if (ret != LZMA_OK) {
+                       xz_uncompress_belch(file, ret);
+                       ret = -EINVAL;
+                       goto out;
+               }
+       }
+       file->memory = p;
+       file->size = total;
+       return 0;
+ out:
+       free(p);
+       return ret;
+}
+
+int kmod_file_load_xz(struct kmod_file *file)
+{
+       lzma_stream strm = LZMA_STREAM_INIT;
+       lzma_ret lzret;
+       int ret;
+
+       lzret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
+       if (lzret == LZMA_MEM_ERROR) {
+               ERR(file->ctx, "xz: %s\n", strerror(ENOMEM));
+               return -ENOMEM;
+       } else if (lzret != LZMA_OK) {
+               ERR(file->ctx, "xz: Internal error (bug)\n");
+               return -EINVAL;
+       }
+       ret = xz_uncompress(&strm, file);
+       lzma_end(&strm);
+       return ret;
+}
index 52490fbd3c7908fb020f97510c245ee308e7e645..29e89ca21167dcb0e2656bdce08a60b8560fd5ac 100644 (file)
@@ -29,9 +29,6 @@
 #ifdef ENABLE_ZSTD
 #include <zstd.h>
 #endif
-#ifdef ENABLE_XZ
-#include <lzma.h>
-#endif
 #ifdef ENABLE_ZLIB
 #include <zlib.h>
 #endif
 
 #include "libkmod.h"
 #include "libkmod-internal.h"
-
-struct kmod_file {
-       int fd;
-       enum kmod_file_compression_type compression;
-       off_t size;
-       void *memory;
-       int (*load)(struct kmod_file *file);
-       const struct kmod_ctx *ctx;
-       struct kmod_elf *elf;
-};
+#include "libkmod-internal-file.h"
 
 #ifdef ENABLE_ZSTD
 static int zstd_read_block(struct kmod_file *file, size_t block_size,
@@ -186,111 +174,6 @@ static int load_zstd(struct kmod_file *file)
 #endif
 
 static const char magic_zstd[] = {0x28, 0xB5, 0x2F, 0xFD};
-
-#ifdef ENABLE_XZ
-static void xz_uncompress_belch(struct kmod_file *file, lzma_ret ret)
-{
-       switch (ret) {
-       case LZMA_MEM_ERROR:
-               ERR(file->ctx, "xz: %s\n", strerror(ENOMEM));
-               break;
-       case LZMA_FORMAT_ERROR:
-               ERR(file->ctx, "xz: File format not recognized\n");
-               break;
-       case LZMA_OPTIONS_ERROR:
-               ERR(file->ctx, "xz: Unsupported compression options\n");
-               break;
-       case LZMA_DATA_ERROR:
-               ERR(file->ctx, "xz: File is corrupt\n");
-               break;
-       case LZMA_BUF_ERROR:
-               ERR(file->ctx, "xz: Unexpected end of input\n");
-               break;
-       default:
-               ERR(file->ctx, "xz: Internal error (bug)\n");
-               break;
-       }
-}
-
-static int xz_uncompress(lzma_stream *strm, struct kmod_file *file)
-{
-       uint8_t in_buf[BUFSIZ], out_buf[BUFSIZ];
-       lzma_action action = LZMA_RUN;
-       lzma_ret ret;
-       void *p = NULL;
-       size_t total = 0;
-
-       strm->avail_in  = 0;
-       strm->next_out  = out_buf;
-       strm->avail_out = sizeof(out_buf);
-
-       while (true) {
-               if (strm->avail_in == 0) {
-                       ssize_t rdret = read(file->fd, in_buf, sizeof(in_buf));
-                       if (rdret < 0) {
-                               ret = -errno;
-                               goto out;
-                       }
-                       strm->next_in  = in_buf;
-                       strm->avail_in = rdret;
-                       if (rdret == 0)
-                               action = LZMA_FINISH;
-               }
-               ret = lzma_code(strm, action);
-               if (strm->avail_out == 0 || ret != LZMA_OK) {
-                       size_t write_size = BUFSIZ - strm->avail_out;
-                       char *tmp = realloc(p, total + write_size);
-                       if (tmp == NULL) {
-                               ret = -errno;
-                               goto out;
-                       }
-                       memcpy(tmp + total, out_buf, write_size);
-                       total += write_size;
-                       p = tmp;
-                       strm->next_out = out_buf;
-                       strm->avail_out = BUFSIZ;
-               }
-               if (ret == LZMA_STREAM_END)
-                       break;
-               if (ret != LZMA_OK) {
-                       xz_uncompress_belch(file, ret);
-                       ret = -EINVAL;
-                       goto out;
-               }
-       }
-       file->memory = p;
-       file->size = total;
-       return 0;
- out:
-       free(p);
-       return ret;
-}
-
-static int load_xz(struct kmod_file *file)
-{
-       lzma_stream strm = LZMA_STREAM_INIT;
-       lzma_ret lzret;
-       int ret;
-
-       lzret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
-       if (lzret == LZMA_MEM_ERROR) {
-               ERR(file->ctx, "xz: %s\n", strerror(ENOMEM));
-               return -ENOMEM;
-       } else if (lzret != LZMA_OK) {
-               ERR(file->ctx, "xz: Internal error (bug)\n");
-               return -EINVAL;
-       }
-       ret = xz_uncompress(&strm, file);
-       lzma_end(&strm);
-       return ret;
-}
-#else
-static int load_xz(struct kmod_file *file)
-{
-       return -ENOSYS;
-}
-#endif
-
 static const char magic_xz[] = {0xfd, '7', 'z', 'X', 'Z', 0};
 
 #ifdef ENABLE_ZLIB
@@ -387,7 +270,7 @@ static const struct comp_type {
        int (*load)(struct kmod_file *file);
 } comp_types[] = {
        {sizeof(magic_zstd),    KMOD_FILE_COMPRESSION_ZSTD, magic_zstd, load_zstd},
-       {sizeof(magic_xz),      KMOD_FILE_COMPRESSION_XZ, magic_xz, load_xz},
+       {sizeof(magic_xz),      KMOD_FILE_COMPRESSION_XZ, magic_xz, kmod_file_load_xz},
        {sizeof(magic_zlib),    KMOD_FILE_COMPRESSION_ZLIB, magic_zlib, load_zlib},
        {0,                     KMOD_FILE_COMPRESSION_NONE, NULL, load_reg}
 };
diff --git a/libkmod/libkmod-internal-file.h b/libkmod/libkmod-internal-file.h
new file mode 100644 (file)
index 0000000..1d74aed
--- /dev/null
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include <errno.h>
+
+#include <libkmod/libkmod-internal.h>
+
+struct kmod_ctx;
+struct kmod_elf;
+
+struct kmod_file {
+       int fd;
+       enum kmod_file_compression_type compression;
+       off_t size;
+       void *memory;
+       int (*load)(struct kmod_file *file);
+       const struct kmod_ctx *ctx;
+       struct kmod_elf *elf;
+};
+
+#ifdef ENABLE_XZ
+int kmod_file_load_xz(struct kmod_file *file);
+#else
+static inline int kmod_file_load_xz(struct kmod_file *file) { return -ENOSYS; }
+#endif