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

Reply via email to