Signed-off-by: Alexey Gladkov <[email protected]>
---
Makefile.am | 4 +++
configure.ac | 22 +++++++++++++++-
depmod.c | 2 +-
grabfile.c | 16 +++++++++++
grabfile.h | 3 +-
grabfile_lzma.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
grabfile_lzma.h | 9 ++++++
7 files changed, 129 insertions(+), 3 deletions(-)
create mode 100644 grabfile_lzma.c
create mode 100644 grabfile_lzma.h
diff --git a/Makefile.am b/Makefile.am
index 114d670..1f6bcee 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,6 +6,10 @@ if WITH_ZLIB
grabfile_SOURCES += grabfile_zlib.c grabfile_zlib.h
endif
+if WITH_LZMA
+grabfile_SOURCES += grabfile_lzma.c grabfile_lzma.h
+endif
+
insmod_SOURCES = insmod.c testing.h
lsmod_SOURCES = lsmod.c testing.h
modprobe_SOURCES = modprobe.c testing.h $(grabfile_SOURCES)
diff --git a/configure.ac b/configure.ac
index 42629fa..4921d84 100644
--- a/configure.ac
+++ b/configure.ac
@@ -31,6 +31,26 @@ AC_ARG_ENABLE(zlib-dynamic,
fi])
AM_CONDITIONAL(WITH_ZLIB, test "$WITH_ZLIB" = "yes")
+WITH_LZMA=no
+
+AC_ARG_ENABLE(lzma,
+[ --enable-lzma Handle lzma compressed modules],
+[if test "$enableval" = "yes"; then
+ WITH_LZMA=yes
+ AC_DEFINE(CONFIG_USE_LZMA)
+ lzma_flags="-Wl,-Bstatic -llzma -Wl,-Bdynamic"
+fi])
+
+AC_ARG_ENABLE(lzma,
+[ --enable-lzma-dynamic Handle xz compressed modules, lzma will be
linked
+ dynamically.],
+[if test "$enableval" = "yes"; then
+ WITH_LZMA=yes
+ AC_DEFINE(CONFIG_USE_LZMA)
+ lzma_flags="-llzma"
+fi])
+AM_CONDITIONAL(WITH_LZMA, test "$WITH_LZMA" = "yes")
+
AC_PROG_CC
AC_PROG_RANLIB
@@ -44,7 +64,7 @@ fi
# Delay adding the zlib_flags until after AC_PROG_CC, so we can distinguish
# between a broken cc and a working cc but missing libz.a.
-LDADD="$LDADD $zlib_flags"
+LDADD="$LDADD $zlib_flags $lzma_flags"
AC_SUBST(LDADD)
case $target in
diff --git a/depmod.c b/depmod.c
index 3b5592e..3899513 100644
--- a/depmod.c
+++ b/depmod.c
@@ -698,7 +698,7 @@ static int output_deps_bin(struct module *modules,
*/
static int smells_like_module(const char *name)
{
- return ends_in(name,".ko") || ends_in(name, ".ko.gz");
+ return ends_in(name,".ko") || ends_in(name, ".ko.gz") || ends_in(name,
".ko.xz");
}
typedef struct module *(*do_module_t)(const char *dirname,
diff --git a/grabfile.c b/grabfile.c
index d5a09ad..f402275 100644
--- a/grabfile.c
+++ b/grabfile.c
@@ -12,6 +12,10 @@
#include "grabfile_zlib.h"
#endif
+#ifdef CONFIG_USE_LZMA
+#include "grabfile_lzma.h"
+#endif
+
static int compress_type(const char *filename)
{
int fd;
@@ -27,6 +31,9 @@ static int compress_type(const char *filename)
close(fd);
+ if (buf[0] == 0xFD && buf[1] == '7' && buf[2] == 'z' && buf[3] == 'X'
&& buf[4] == 'Z' && buf[5] == 0x00)
+ return LZMA_FILE;
+
if (buf[0] == 0x1F && buf[1] == 0x8B)
return GZIP_FILE;
@@ -40,6 +47,10 @@ int grab_file(const char *filename, struct grab_data *fdata)
case GZIP_FILE:
return gzip_grab_file(filename, fdata);
#endif
+#ifdef CONFIG_USE_LZMA
+ case LZMA_FILE:
+ return lzma_grab_file(filename, fdata);
+#endif
case PLAIN_FILE:
return plain_grab_file(filename, fdata);
}
@@ -55,6 +66,11 @@ void release_file(struct grab_data *fdata)
gzip_release_file(fdata);
return;
#endif
+#ifdef CONFIG_USE_LZMA
+ case LZMA_FILE:
+ lzma_release_file(fdata);
+ return;
+#endif
case PLAIN_FILE:
plain_release_file(fdata);
return;
diff --git a/grabfile.h b/grabfile.h
index 99565db..c9b9545 100644
--- a/grabfile.h
+++ b/grabfile.h
@@ -4,7 +4,8 @@
enum file_type
{
PLAIN_FILE,
- GZIP_FILE
+ GZIP_FILE,
+ LZMA_FILE
};
struct grab_data
diff --git a/grabfile_lzma.c b/grabfile_lzma.c
new file mode 100644
index 0000000..9418ac1
--- /dev/null
+++ b/grabfile_lzma.c
@@ -0,0 +1,76 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "grabfile_lzma.h"
+#include "logging.h"
+#include "testing.h"
+
+#include <lzma.h>
+
+#define IN_BUF_MAX 1024
+#define OUT_BUF_MAX 4096
+
+int lzma_grab_file(const char *filename, struct grab_data *fdata)
+{
+ int fd;
+ unsigned char *buffer = NULL;
+ unsigned char buf[IN_BUF_MAX];
+ size_t len;
+ lzma_ret ret;
+ lzma_stream strm = LZMA_STREAM_INIT;
+
+ fdata->data = NULL;
+ fdata->size = 0;
+
+ if ((fd = open(filename, O_RDONLY)) == -1) {
+ error("open: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if ((ret = lzma_auto_decoder(&strm, UINT64_MAX, 0)) != LZMA_OK)
+ fatal("lzma_auto_decoder: return code = %d\n", (int) ret);
+
+ do {
+ if ((len = read(fd, &buf, IN_BUF_MAX)) == -1) {
+ if (errno == EINTR)
+ continue;
+ fatal("read: %s\n", strerror(errno));
+ }
+
+ strm.next_in = buf;
+ strm.avail_in = len;
+
+ do {
+ buffer = NOFAIL(realloc(buffer, strm.total_out +
OUT_BUF_MAX));
+
+ strm.next_out = buffer + strm.total_out;
+ strm.avail_out = OUT_BUF_MAX;
+
+ ret = lzma_code(&strm, (len == 0 ? LZMA_FINISH :
LZMA_RUN));
+
+ if (ret != LZMA_OK && ret != LZMA_STREAM_END)
+ fatal("lzma_code: return code = %d\n", (int)
ret);
+
+ } while (ret == LZMA_OK && strm.avail_in > 0);
+
+ } while (len > 0);
+
+ lzma_end(&strm);
+
+ fdata->type = LZMA_FILE;
+ fdata->data = buffer;
+ fdata->size = strm.total_out;
+
+ close(fd);
+ return 0;
+}
+
+void lzma_release_file(struct grab_data *fdata)
+{
+ free(fdata->data);
+}
diff --git a/grabfile_lzma.h b/grabfile_lzma.h
new file mode 100644
index 0000000..a6234cb
--- /dev/null
+++ b/grabfile_lzma.h
@@ -0,0 +1,9 @@
+#ifndef _GRABFILE_LZMA_H
+#define _GRABFILE_LZMA_H
+
+#include "grabfile.h"
+
+extern int lzma_grab_file(const char *filename, struct grab_data *fdata);
+extern void lzma_release_file(struct grab_data *fdata);
+
+#endif /* _GRABFILE_LZMA_H */
--
1.7.3.5
--
To unsubscribe from this list: send the line "unsubscribe linux-modules" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html