diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2011-04-03 01:02:00 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2011-04-03 01:02:00 +0000 |
commit | b5b89c229819414c8bf741fef9d1a9dbb042a2da (patch) | |
tree | 3f02232de53773909d9b65893820367f2c06de25 /tools/squashfs4 | |
parent | 09702f9b6732d6f4ce342eb17c4044fe2f5f462c (diff) |
tools/squashfs4: update to version 4.2 (adds support for xz compression)
Based on a patch by Jonas Gorski
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@26422 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'tools/squashfs4')
-rw-r--r-- | tools/squashfs4/Makefile | 10 | ||||
-rw-r--r-- | tools/squashfs4/patches/100-portability.patch | 30 | ||||
-rw-r--r-- | tools/squashfs4/patches/110-allow_static_liblzma.patch | 30 | ||||
-rw-r--r-- | tools/squashfs4/patches/110-lzma.patch | 2226 | ||||
-rw-r--r-- | tools/squashfs4/patches/120-cygwin_fixes.patch | 73 | ||||
-rw-r--r-- | tools/squashfs4/patches/130-dynamic_lzma_params.patch | 91 | ||||
-rw-r--r-- | tools/squashfs4/patches/140-mode_check.patch | 11 | ||||
-rw-r--r-- | tools/squashfs4/patches/150-freebsd_fixes.patch | 2 | ||||
-rw-r--r-- | tools/squashfs4/patches/160-expose_lzma_xz_options.patch | 926 |
9 files changed, 1025 insertions, 2374 deletions
diff --git a/tools/squashfs4/Makefile b/tools/squashfs4/Makefile index ddbca1140..04a5456f6 100644 --- a/tools/squashfs4/Makefile +++ b/tools/squashfs4/Makefile @@ -7,11 +7,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=squashfs4 -PKG_VERSION:=4.0 +PKG_VERSION:=4.2 PKG_SOURCE:=squashfs$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=@SF/squashfs -PKG_MD5SUM:=a3c23391da4ebab0ac4a75021ddabf96 +PKG_MD5SUM:=1b7a781fb4cf8938842279bd3e8ee852 PKG_CAT:=zcat HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/squashfs$(PKG_VERSION) @@ -20,9 +20,11 @@ include $(INCLUDE_DIR)/host-build.mk define Host/Compile $(MAKE) -C $(HOST_BUILD_DIR)/squashfs-tools \ - USE_LZMA=1 \ - LZMA_CFLAGS="-I$(STAGING_DIR_HOST)/include -DUSE_LZMA" \ + XZ_SUPPORT=1 \ + LZMA_XZ_SUPPORT=1 \ + XATTR_SUPPORT= \ LZMA_LIB="$(STAGING_DIR_HOST)/lib/liblzma.a" \ + EXTRA_CFLAGS="-I$(STAGING_DIR_HOST)/include" \ mksquashfs unsquashfs endef diff --git a/tools/squashfs4/patches/100-portability.patch b/tools/squashfs4/patches/100-portability.patch index 4318c0ca6..ac1349c7a 100644 --- a/tools/squashfs4/patches/100-portability.patch +++ b/tools/squashfs4/patches/100-portability.patch @@ -1,17 +1,19 @@ ---- a/squashfs-tools/global.h -+++ b/squashfs-tools/global.h -@@ -44,4 +44,8 @@ typedef long long squashfs_fragment_inde - typedef squashfs_inode_t squashfs_inode; - typedef squashfs_block_t squashfs_block; +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -60,6 +60,10 @@ + #include <sys/sysinfo.h> + #endif +#ifndef FNM_EXTMATCH +#define FNM_EXTMATCH 0 +#endif + - #endif + #ifdef SQUASHFS_TRACE + #define TRACE(s, args...) \ + do { \ --- a/squashfs-tools/unsquashfs.h +++ b/squashfs-tools/unsquashfs.h -@@ -49,8 +49,10 @@ +@@ -49,8 +49,14 @@ #define __BYTE_ORDER BYTE_ORDER #define __BIG_ENDIAN BIG_ENDIAN #define __LITTLE_ENDIAN LITTLE_ENDIAN @@ -19,6 +21,20 @@ #else #include <endian.h> +#include <sys/sysinfo.h> ++#endif ++ ++#ifndef FNM_EXTMATCH ++#define FNM_EXTMATCH 0 #endif #include "squashfs_fs.h" +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -29,7 +29,6 @@ + #include "compressor.h" + #include "xattr.h" + +-#include <sys/sysinfo.h> + #include <sys/types.h> + + struct cache *fragment_cache, *data_cache; diff --git a/tools/squashfs4/patches/110-allow_static_liblzma.patch b/tools/squashfs4/patches/110-allow_static_liblzma.patch new file mode 100644 index 000000000..9a3a74418 --- /dev/null +++ b/tools/squashfs4/patches/110-allow_static_liblzma.patch @@ -0,0 +1,30 @@ +--- a/squashfs-tools/Makefile ++++ b/squashfs-tools/Makefile +@@ -129,7 +129,6 @@ ifeq ($(LZMA_XZ_SUPPORT),1) + CFLAGS += -DLZMA_SUPPORT + MKSQUASHFS_OBJS += lzma_xz_wrapper.o + UNSQUASHFS_OBJS += lzma_xz_wrapper.o +-LIBS += -llzma + COMPRESSORS += lzma + endif + +@@ -137,10 +136,18 @@ ifeq ($(XZ_SUPPORT),1) + CFLAGS += -DXZ_SUPPORT + MKSQUASHFS_OBJS += xz_wrapper.o + UNSQUASHFS_OBJS += xz_wrapper.o +-LIBS += -llzma + COMPRESSORS += xz + endif + ++ifneq ($(LZMA_XZ_SUPPORT)$(XZ_SUPPORT),) ++ifneq ($(LZMA_LIB),) ++MKSQUASHFS_OBJS += $(LZMA_LIB) ++UNSQUASHFS_OBJS += $(LZMA_LIB) ++else ++LIBS += -llzma ++endif ++endif ++ + ifeq ($(LZO_SUPPORT),1) + CFLAGS += -DLZO_SUPPORT + ifdef LZO_DIR diff --git a/tools/squashfs4/patches/110-lzma.patch b/tools/squashfs4/patches/110-lzma.patch deleted file mode 100644 index 1a86e0585..000000000 --- a/tools/squashfs4/patches/110-lzma.patch +++ /dev/null @@ -1,2226 +0,0 @@ -diff -Nur squashfs4.0/squashfs-tools/compressor.c squashfs4.0-lzma-snapshot/squashfs-tools/compressor.c ---- squashfs4.0/squashfs-tools/compressor.c 1970-01-01 01:00:00.000000000 +0100 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/compressor.c 2009-10-20 06:03:37.000000000 +0200 -@@ -0,0 +1,78 @@ -+/* -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * compressor.c -+ */ -+ -+#include <stdio.h> -+#include <string.h> -+#include "compressor.h" -+#include "squashfs_fs.h" -+ -+extern int gzip_compress(void **, char *, char *, int, int, int *); -+extern int gzip_uncompress(char *, char *, int, int, int *); -+extern int lzma_compress(void **, char *, char *, int, int, int *); -+extern int lzma_uncompress(char *, char *, int, int, int *); -+ -+struct compressor compressor[] = { -+ { gzip_compress, gzip_uncompress, ZLIB_COMPRESSION, "gzip", 1 }, -+#ifdef LZMA_SUPPORT -+ { lzma_compress, lzma_uncompress, LZMA_COMPRESSION, "lzma", 1 }, -+#else -+ { NULL, NULL, LZMA_COMPRESSION, "lzma", 0 }, -+#endif -+ { NULL, NULL , 0, "unknown", 0} -+}; -+ -+ -+struct compressor *lookup_compressor(char *name) -+{ -+ int i; -+ -+ for(i = 0; compressor[i].id; i++) -+ if(strcmp(compressor[i].name, name) == 0) -+ break; -+ -+ return &compressor[i]; -+} -+ -+ -+struct compressor *lookup_compressor_id(int id) -+{ -+ int i; -+ -+ for(i = 0; compressor[i].id; i++) -+ if(id == compressor[i].id) -+ break; -+ -+ return &compressor[i]; -+} -+ -+ -+void display_compressors(char *indent, char *def_comp) -+{ -+ int i; -+ -+ for(i = 0; compressor[i].id; i++) -+ if(compressor[i].supported) -+ fprintf(stderr, "%s\t%s%s\n", indent, -+ compressor[i].name, -+ strcmp(compressor[i].name, def_comp) == 0 ? -+ " (default)" : ""); -+} -diff -Nur squashfs4.0/squashfs-tools/compressor.h squashfs4.0-lzma-snapshot/squashfs-tools/compressor.h ---- squashfs4.0/squashfs-tools/compressor.h 1970-01-01 01:00:00.000000000 +0100 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/compressor.h 2009-10-20 06:03:37.000000000 +0200 -@@ -0,0 +1,33 @@ -+/* -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * compressor.h -+ */ -+ -+struct compressor { -+ int (*compress)(void **, char *, char *, int, int, int *); -+ int (*uncompress)(char *, char *, int, int, int *); -+ int id; -+ char *name; -+ int supported; -+}; -+ -+extern struct compressor *lookup_compressor(char *); -+extern struct compressor *lookup_compressor_id(int); -+extern void display_compressors(char *, char *); -diff -Nur squashfs4.0/squashfs-tools/gzip_wrapper.c squashfs4.0-lzma-snapshot/squashfs-tools/gzip_wrapper.c ---- squashfs4.0/squashfs-tools/gzip_wrapper.c 1970-01-01 01:00:00.000000000 +0100 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/gzip_wrapper.c 2009-10-20 06:03:37.000000000 +0200 -@@ -0,0 +1,80 @@ -+/* -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * gzip_wrapper.c -+ */ -+ -+#include <stdlib.h> -+#include <zlib.h> -+ -+int gzip_compress(void **strm, char *d, char *s, int size, int block_size, -+ int *error) -+{ -+ int res = 0; -+ z_stream *stream = *strm; -+ -+ if(stream == NULL) { -+ if((stream = *strm = malloc(sizeof(z_stream))) == NULL) -+ goto failed; -+ -+ stream->zalloc = Z_NULL; -+ stream->zfree = Z_NULL; -+ stream->opaque = 0; -+ -+ if((res = deflateInit(stream, 9)) != Z_OK) -+ goto failed; -+ } else if((res = deflateReset(stream)) != Z_OK) -+ goto failed; -+ -+ stream->next_in = (unsigned char *) s; -+ stream->avail_in = size; -+ stream->next_out = (unsigned char *) d; -+ stream->avail_out = block_size; -+ -+ res = deflate(stream, Z_FINISH); -+ if(res == Z_STREAM_END) -+ /* -+ * Success, return the compressed size. -+ */ -+ return (int) stream->total_out; -+ if(res == Z_OK) -+ /* -+ * Output buffer overflow. Return out of buffer space -+ */ -+ return 0; -+failed: -+ /* -+ * All other errors return failure, with the compressor -+ * specific error code in *error -+ */ -+ *error = res; -+ return -1; -+} -+ -+ -+int gzip_uncompress(char *d, char *s, int size, int block_size, int *error) -+{ -+ int res; -+ unsigned long bytes = block_size; -+ -+ res = uncompress((unsigned char *) d, &bytes, -+ (const unsigned char *) s, size); -+ -+ *error = res; -+ return res == Z_OK ? (int) bytes : -1; -+} -diff -Nur squashfs4.0/squashfs-tools/lzma_wrapper.c squashfs4.0-lzma-snapshot/squashfs-tools/lzma_wrapper.c ---- squashfs4.0/squashfs-tools/lzma_wrapper.c 1970-01-01 01:00:00.000000000 +0100 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/lzma_wrapper.c 2009-10-14 05:32:57.000000000 +0200 -@@ -0,0 +1,93 @@ -+/* -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * lzma_wrapper.c -+ */ -+ -+#include <LzmaLib.h> -+ -+#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8) -+ -+int lzma_compress(void **strm, char *dest, char *src, int size,int block_size, -+ int *error) -+{ -+ unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src; -+ size_t props_size = LZMA_PROPS_SIZE, -+ outlen = block_size - LZMA_HEADER_SIZE; -+ int res; -+ -+ res = LzmaCompress(d + LZMA_HEADER_SIZE, &outlen, s, size, d, -+ &props_size, 5, block_size, 3, 0, 2, 32, 1); -+ -+ if(res == SZ_ERROR_OUTPUT_EOF) { -+ /* -+ * Output buffer overflow. Return out of buffer space error -+ */ -+ return 0; -+ } -+ -+ if(res != SZ_OK) { -+ /* -+ * All other errors return failure, with the compressor -+ * specific error code in *error -+ */ -+ *error = res; -+ return -1; -+ } -+ -+ /* -+ * Fill in the 8 byte little endian uncompressed size field in the -+ * LZMA header. 8 bytes is excessively large for squashfs but -+ * this is the standard LZMA header and which is expected by the kernel -+ * code -+ */ -+ d[LZMA_PROPS_SIZE] = size & 255; -+ d[LZMA_PROPS_SIZE + 1] = (size >> 8) & 255; -+ d[LZMA_PROPS_SIZE + 2] = (size >> 16) & 255; -+ d[LZMA_PROPS_SIZE + 3] = (size >> 24) & 255; -+ d[LZMA_PROPS_SIZE + 4] = 0; -+ d[LZMA_PROPS_SIZE + 5] = 0; -+ d[LZMA_PROPS_SIZE + 6] = 0; -+ d[LZMA_PROPS_SIZE + 7] = 0; -+ -+ /* -+ * Success, return the compressed size. Outlen returned by the LZMA -+ * compressor does not include the LZMA header space -+ */ -+ return outlen + LZMA_HEADER_SIZE; -+} -+ -+ -+int lzma_uncompress(char *dest, char *src, int size, int block_size, -+ int *error) -+{ -+ unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src; -+ size_t outlen, inlen = size - LZMA_HEADER_SIZE; -+ int res; -+ -+ outlen = s[LZMA_PROPS_SIZE] | -+ (s[LZMA_PROPS_SIZE + 1] << 8) | -+ (s[LZMA_PROPS_SIZE + 2] << 16) | -+ (s[LZMA_PROPS_SIZE + 3] << 24); -+ -+ res = LzmaUncompress(d, &outlen, s + LZMA_HEADER_SIZE, &inlen, -+ s, LZMA_PROPS_SIZE); -+ -+ *error = res; -+ return res == SZ_OK ? outlen : -1; -+} -diff -Nur squashfs4.0/squashfs-tools/Makefile squashfs4.0-lzma-snapshot/squashfs-tools/Makefile ---- squashfs4.0/squashfs-tools/Makefile 2009-04-05 04:03:36.000000000 +0200 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/Makefile 2009-10-22 06:17:12.000000000 +0200 -@@ -1,40 +1,76 @@ -+# -+# Building LZMA support -+# Download LZMA sdk (4.65 used in development, other versions may work), -+# set LZMA_DIR to unpacked source, and uncomment next line -+LZMA_SUPPORT = 1 -+LZMA_DIR = ../../lzma-4.65 -+ -+#Compression default. -+COMP_DEFAULT = gzip -+ -+INCLUDEDIR = -I. - INSTALL_DIR = /usr/local/bin - --INCLUDEDIR = . -+MKSQUASHFS_OBJS = mksquashfs.o read_fs.o sort.o swap.o pseudo.o compressor.o \ -+ gzip_wrapper.o -+ -+UNSQUASHFS_OBJS = unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o \ -+ unsquash-4.o swap.o compressor.o gzip_wrapper.o - --CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -O2 -+CFLAGS = $(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ -+ -D_GNU_SOURCE -DCOMP_DEFAULT=\"$(COMP_DEFAULT)\" -O2 -Wall - -+ifdef LZMA_SUPPORT -+LZMA_OBJS = $(LZMA_DIR)/C/Alloc.o $(LZMA_DIR)/C/LzFind.o \ -+ $(LZMA_DIR)/C/LzmaDec.o $(LZMA_DIR)/C/LzmaEnc.o $(LZMA_DIR)/C/LzmaLib.o -+INCLUDEDIR += -I$(LZMA_DIR)/C -+CFLAGS += -DLZMA_SUPPORT -+MKSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS) -+UNSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS) -+endif -+ -+.PHONY: all - all: mksquashfs unsquashfs - --mksquashfs: mksquashfs.o read_fs.o sort.o swap.o pseudo.o -- $(CC) mksquashfs.o read_fs.o sort.o swap.o pseudo.o -lz -lpthread -lm -o $@ -+mksquashfs: $(MKSQUASHFS_OBJS) -+ $(CC) $(MKSQUASHFS_OBJS) -lz -lpthread -lm -o $@ -+ -+mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h \ -+ squashfs_swap.h - --mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h squashfs_swap.h Makefile -+read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h - --read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h Makefile -+sort.o: sort.c squashfs_fs.h global.h sort.h - --sort.o: sort.c squashfs_fs.h global.h sort.h Makefile -+swap.o: swap.c - --swap.o: swap.c Makefile -+pseudo.o: pseudo.c pseudo.h - --pseudo.o: pseudo.c pseudo.h Makefile -+compressor.o: compressor.c compressor.h - --unsquashfs: unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o -- $(CC) unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o -lz -lpthread -lm -o $@ -+unsquashfs: $(UNSQUASHFS_OBJS) -+ $(CC) $(UNSQUASHFS_OBJS) -lz -lpthread -lm -o $@ - --unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h squashfs_compat.h global.h Makefile -+unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h \ -+ squashfs_compat.h global.h - --unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h global.h Makefile -+unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h \ -+ global.h - --unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h squashfs_compat.h global.h Makefile -+unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h \ -+ squashfs_compat.h global.h - --unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h global.h Makefile -+unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h \ -+ global.h - --unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h global.h Makefile -+unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h \ -+ global.h - -+.PHONY: clean - clean: - -rm -f *.o mksquashfs unsquashfs - -+.PHONY: install - install: mksquashfs unsquashfs - mkdir -p $(INSTALL_DIR) - cp mksquashfs $(INSTALL_DIR) -diff -Nur squashfs4.0/squashfs-tools/mksquashfs.c squashfs4.0-lzma-snapshot/squashfs-tools/mksquashfs.c ---- squashfs4.0/squashfs-tools/mksquashfs.c 2009-04-05 23:22:48.000000000 +0200 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/mksquashfs.c 2009-10-20 06:03:38.000000000 +0200 -@@ -36,7 +36,6 @@ - #include <errno.h> - #include <dirent.h> - #include <string.h> --#include <zlib.h> - #include <stdlib.h> - #include <signal.h> - #include <setjmp.h> -@@ -47,6 +46,7 @@ - #include <math.h> - #include <regex.h> - #include <fnmatch.h> -+#include <sys/wait.h> - - #ifndef linux - #define __BYTE_ORDER BYTE_ORDER -@@ -64,6 +64,7 @@ - #include "global.h" - #include "sort.h" - #include "pseudo.h" -+#include "compressor.h" - - #ifdef SQUASHFS_TRACE - #define TRACE(s, args...) do { \ -@@ -245,10 +246,8 @@ - /* list of root directory entries read from original filesystem */ - int old_root_entries = 0; - struct old_root_entry_info { -- char name[SQUASHFS_NAME_LEN + 1]; -- squashfs_inode inode; -- int type; -- int inode_number; -+ char *name; -+ struct inode_info inode; - }; - struct old_root_entry_info *old_root_entry; - -@@ -371,10 +370,15 @@ - int reader_buffer_size; - int fragment_buffer_size; - -+/* compression operations structure */ -+static struct compressor *comp; -+char *comp_name = COMP_DEFAULT; -+ - char *read_from_disk(long long start, unsigned int avail_bytes); - void add_old_root_entry(char *name, squashfs_inode inode, int inode_number, - int type); --extern int read_super(int fd, squashfs_super_block *sBlk, char *source); -+extern struct compressor *read_super(int fd, squashfs_super_block *sBlk, -+ char *source); - extern long long read_filesystem(char *root_name, int fd, - squashfs_super_block *sBlk, char **cinode_table, char **data_cache, - char **cdirectory_table, char **directory_data_cache, -@@ -831,83 +835,32 @@ - } - - --unsigned int mangle2(z_stream **strm, char *d, char *s, int size, -+int mangle2(void **strm, char *d, char *s, int size, - int block_size, int uncompressed, int data_block) - { -- unsigned long c_byte; -- unsigned int res; -- z_stream *stream = *strm; -- -- if(uncompressed) -- goto notcompressed; -- -- if(stream == NULL) { -- if((stream = *strm = malloc(sizeof(z_stream))) == NULL) -- BAD_ERROR("mangle::compress failed, not enough " -- "memory\n"); -- -- stream->zalloc = Z_NULL; -- stream->zfree = Z_NULL; -- stream->opaque = 0; -- -- if((res = deflateInit(stream, 9)) != Z_OK) { -- if(res == Z_MEM_ERROR) -- BAD_ERROR("zlib::compress failed, not enough " -- "memory\n"); -- else if(res == Z_STREAM_ERROR) -- BAD_ERROR("zlib::compress failed, not a valid " -- "compression level\n"); -- else if(res == Z_VERSION_ERROR) -- BAD_ERROR("zlib::compress failed, incorrect " -- "zlib version\n"); -- else -- BAD_ERROR("zlib::compress failed, unknown " -- "error %d\n", res); -- } -- } else if((res = deflateReset(stream)) != Z_OK) { -- if(res == Z_STREAM_ERROR) -- BAD_ERROR("zlib::compress failed, stream state " -- "inconsistent\n"); -- else -- BAD_ERROR("zlib::compress failed, unknown error %d\n", -- res); -- } -+ int error, c_byte = 0; - -- stream->next_in = (unsigned char *) s; -- stream->avail_in = size; -- stream->next_out = (unsigned char *) d; -- stream->avail_out = block_size; -- -- res = deflate(stream, Z_FINISH); -- if(res != Z_STREAM_END && res != Z_OK) { -- if(res == Z_STREAM_ERROR) -- BAD_ERROR("zlib::compress failed, stream state " -- "inconsistent\n"); -- else if(res == Z_BUF_ERROR) -- BAD_ERROR("zlib::compress failed, no progress possible" -- "\n"); -- else -- BAD_ERROR("zlib::compress failed, unknown error %d\n", -- res); -+ if(!uncompressed) { -+ c_byte = comp->compress(strm, d, s, size, block_size, &error); -+ if(c_byte == -1) -+ BAD_ERROR("mangle2:: %s compress failed with error " -+ "code %d\n", comp->name, error); - } - -- c_byte = stream->total_out; -- -- if(res != Z_STREAM_END || c_byte >= size) { --notcompressed: -+ if(c_byte == 0 || c_byte >= size) { - memcpy(d, s, size); - return size | (data_block ? SQUASHFS_COMPRESSED_BIT_BLOCK : - SQUASHFS_COMPRESSED_BIT); - } - -- return (unsigned int) c_byte; -+ return c_byte; - } - - --unsigned int mangle(char *d, char *s, int size, int block_size, -+int mangle(char *d, char *s, int size, int block_size, - int uncompressed, int data_block) - { -- static z_stream *stream = NULL; -+ static void *stream = NULL; - - return mangle2(&stream, d, s, size, block_size, uncompressed, - data_block); -@@ -1660,8 +1613,7 @@ - pthread_mutex_unlock(&fragment_mutex); - - if(SQUASHFS_COMPRESSED_BLOCK(disk_fragment->size)) { -- int res; -- unsigned long bytes = block_size; -+ int error, res; - char *data; - - if(compressed_buffer) -@@ -1669,19 +1621,11 @@ - else - data = read_from_disk(start_block, size); - -- res = uncompress((unsigned char *) buffer->data, &bytes, -- (const unsigned char *) data, size); -- if(res != Z_OK) { -- if(res == Z_MEM_ERROR) -- BAD_ERROR("zlib::uncompress failed, not enough " -- "memory\n"); -- else if(res == Z_BUF_ERROR) -- BAD_ERROR("zlib::uncompress failed, not enough " -- "room in output buffer\n"); -- else -- BAD_ERROR("zlib::uncompress failed," -- " unknown error %d\n", res); -- } -+ res = comp->uncompress(buffer->data, data, size, block_size, -+ &error); -+ if(res == -1) -+ BAD_ERROR("%s uncompress failed with error code %d\n", -+ comp->name, error); - } else if(compressed_buffer) - memcpy(buffer->data, compressed_buffer->data, size); - else -@@ -1733,9 +1677,7 @@ - entry->buffer->block = bytes; - bytes += compressed_size; - fragments_outstanding --; -- pthread_mutex_unlock(&fragment_mutex); - queue_put(to_writer, entry->buffer); -- pthread_mutex_lock(&fragment_mutex); - TRACE("fragment_locked writing fragment %d, compressed size %d" - "\n", entry->fragment, compressed_size); - free(entry); -@@ -1758,6 +1700,8 @@ - pthread_mutex_lock(&fragment_mutex); - insert_fragment_list(&frag_locked_list, entry); - pthread_mutex_unlock(&fragment_mutex); -+ -+ return TRUE; - } - - -@@ -1824,7 +1768,9 @@ - unsigned short c_byte; - char cbuffer[(SQUASHFS_METADATA_SIZE << 2) + 2]; - -+#ifdef SQUASHFS_TRACE - long long obytes = bytes; -+#endif - - for(i = 0; i < meta_blocks; i++) { - int avail_bytes = length > SQUASHFS_METADATA_SIZE ? -@@ -2170,11 +2116,85 @@ - } - - -+static int seq = 0; -+void reader_read_process(struct dir_ent *dir_ent) -+{ -+ struct file_buffer *prev_buffer = NULL, *file_buffer; -+ int status, res, byte, count = 0; -+ int file = get_pseudo_file(dir_ent->inode->pseudo_id)->fd; -+ int child = get_pseudo_file(dir_ent->inode->pseudo_id)->child; -+ long long bytes = 0; -+ -+ while(1) { -+ file_buffer = cache_get(reader_buffer, 0, 0); -+ file_buffer->sequence = seq ++; -+ -+ byte = read_bytes(file, file_buffer->data, block_size); -+ if(byte == -1) -+ goto read_err; -+ -+ file_buffer->size = byte; -+ file_buffer->file_size = -1; -+ file_buffer->block = count ++; -+ file_buffer->error = FALSE; -+ file_buffer->fragment = FALSE; -+ bytes += byte; -+ -+ if(byte == 0) -+ break; -+ -+ /* -+ * Update estimated_uncompressed block count. This is done -+ * on every block rather than waiting for all blocks to be -+ * read incase write_file_process() is running in parallel -+ * with this. Otherwise cur uncompressed block count may -+ * get ahead of the total uncompressed block count. -+ */ -+ estimated_uncompressed ++; -+ -+ if(prev_buffer) -+ queue_put(from_reader, prev_buffer); -+ prev_buffer = file_buffer; -+ } -+ -+ /* -+ * Update inode file size now that the size of the dynamic pseudo file -+ * is known. This is needed for the -info option. -+ */ -+ dir_ent->inode->buf.st_size = bytes; -+ -+ res = waitpid(child, &status, 0); -+ if(res == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) -+ goto read_err; -+ -+ if(prev_buffer == NULL) -+ prev_buffer = file_buffer; -+ else { -+ cache_block_put(file_buffer); -+ seq --; -+ } -+ prev_buffer->file_size = bytes; -+ prev_buffer->fragment = !no_fragments && -+ (count == 2 || always_use_fragments) && (byte < block_size); -+ queue_put(from_reader, prev_buffer); -+ -+ return; -+ -+read_err: -+ if(prev_buffer) { -+ cache_block_put(file_buffer); -+ seq --; -+ file_buffer = prev_buffer; -+ } -+ file_buffer->error = TRUE; -+ queue_put(from_deflate, file_buffer); -+} -+ -+ - void reader_read_file(struct dir_ent *dir_ent) - { - struct stat *buf = &dir_ent->inode->buf, buf2; - struct file_buffer *file_buffer; -- static int index = 0; - int blocks, byte, count, expected, file, frag_block; - long long bytes, read_size; - -@@ -2202,7 +2222,7 @@ - if(file_buffer) - queue_put(from_reader, file_buffer); - file_buffer = cache_get(reader_buffer, 0, 0); -- file_buffer->sequence = index ++; -+ file_buffer->sequence = seq ++; - - byte = file_buffer->size = read_bytes(file, file_buffer->data, - block_size); -@@ -2238,7 +2258,7 @@ - - read_err: - file_buffer = cache_get(reader_buffer, 0, 0); -- file_buffer->sequence = index ++; -+ file_buffer->sequence = seq ++; - read_err2: - file_buffer->error = TRUE; - queue_put(from_deflate, file_buffer); -@@ -2262,9 +2282,14 @@ - for(i = 0; i < dir->count; i++) { - struct dir_ent *dir_ent = dir->list[i]; - struct stat *buf = &dir_ent->inode->buf; -- if(dir_ent->data) -+ if(dir_ent->inode->root_entry) - continue; - -+ if(dir_ent->inode->pseudo_file) { -+ reader_read_process(dir_ent); -+ continue; -+ } -+ - switch(buf->st_mode & S_IFMT) { - case S_IFREG: - reader_read_file(dir_ent); -@@ -2365,7 +2390,7 @@ - - void *deflator(void *arg) - { -- z_stream *stream = NULL; -+ void *stream = NULL; - int oldstate; - - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); -@@ -2402,7 +2427,7 @@ - - void *frag_deflator(void *arg) - { -- z_stream *stream = NULL; -+ void *stream = NULL; - int oldstate; - - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); -@@ -2426,8 +2451,8 @@ - write_buffer->block = bytes; - bytes += compressed_size; - fragments_outstanding --; -- pthread_mutex_unlock(&fragment_mutex); - queue_put(to_writer, write_buffer); -+ pthread_mutex_unlock(&fragment_mutex); - TRACE("Writing fragment %lld, uncompressed size %d, " - "compressed size %d\n", file_buffer->block, - file_buffer->size, compressed_size); -@@ -2674,6 +2699,98 @@ - } - - -+int write_file_process(squashfs_inode *inode, struct dir_ent *dir_ent, -+ struct file_buffer *read_buffer, int *duplicate_file) -+{ -+ long long read_size, file_bytes, start; -+ struct fragment *fragment; -+ unsigned int *block_list = NULL; -+ int block = 0, status; -+ long long sparse = 0; -+ struct file_buffer *fragment_buffer = NULL; -+ -+ *duplicate_file = FALSE; -+ -+ lock_fragments(); -+ -+ file_bytes = 0; -+ start = bytes; -+ while (1) { -+ read_size = read_buffer->file_size; -+ if(read_buffer->fragment && read_buffer->c_byte) -+ fragment_buffer = read_buffer; -+ else { -+ block_list = realloc(block_list, (block + 1) * -+ sizeof(unsigned int)); -+ if(block_list == NULL) -+ BAD_ERROR("Out of memory allocating block_list" -+ "\n"); -+ block_list[block ++] = read_buffer->c_byte; -+ if(read_buffer->c_byte) { -+ read_buffer->block = bytes; -+ bytes += read_buffer->size; -+ cache_rehash(read_buffer, read_buffer->block); -+ file_bytes += read_buffer->size; -+ queue_put(to_writer, read_buffer); -+ } else { -+ sparse += read_buffer->size; -+ cache_block_put(read_buffer); -+ } -+ } -+ inc_progress_bar(); -+ -+ if(read_size != -1) -+ break; -+ -+ read_buffer = get_file_buffer(from_deflate); -+ if(read_buffer->error) -+ goto read_err; -+ } -+ -+ unlock_fragments(); -+ fragment = get_and_fill_fragment(fragment_buffer); -+ cache_block_put(fragment_buffer); -+ -+ if(duplicate_checking) -+ add_non_dup(read_size, file_bytes, block_list, start, fragment, -+ 0, 0, FALSE); -+ file_count ++; -+ total_bytes += read_size; -+ -+ if(read_size < (1LL << 32) && start < (1LL << 32) && sparse == 0) -+ create_inode(inode, dir_ent, SQUASHFS_FILE_TYPE, read_size, -+ start, block, block_list, fragment, NULL, 0); -+ else -+ create_inode(inode, dir_ent, SQUASHFS_LREG_TYPE, read_size, -+ start, block, block_list, fragment, NULL, sparse); -+ -+ if(duplicate_checking == FALSE) -+ free(block_list); -+ -+ return 0; -+ -+read_err: -+ cur_uncompressed -= block; -+ status = read_buffer->error; -+ bytes = start; -+ if(!block_device) { -+ int res; -+ -+ queue_put(to_writer, NULL); -+ if(queue_get(from_writer) != 0) -+ EXIT_MKSQUASHFS(); -+ res = ftruncate(fd, bytes); -+ if(res != 0) -+ BAD_ERROR("Failed to truncate dest file because %s\n", -+ strerror(errno)); -+ } -+ unlock_fragments(); -+ free(block_list); -+ cache_block_put(read_buffer); -+ return status; -+} -+ -+ - int write_file_blocks(squashfs_inode *inode, struct dir_ent *dir_ent, - long long read_size, struct file_buffer *read_buffer, - int *duplicate_file) -@@ -2941,7 +3058,10 @@ - - read_size = read_buffer->file_size; - -- if(read_size == 0) { -+ if(read_size == -1) -+ status = write_file_process(inode, dir_ent, read_buffer, -+ duplicate_file); -+ else if(read_size == 0) { - write_file_empty(inode, dir_ent, duplicate_file); - cache_block_put(read_buffer); - } else if(read_buffer->fragment && read_buffer->c_byte) -@@ -3036,6 +3156,8 @@ - - memcpy(&inode->buf, buf, sizeof(struct stat)); - inode->read = FALSE; -+ inode->root_entry = FALSE; -+ inode->pseudo_file = FALSE; - inode->inode = SQUASHFS_INVALID_BLK; - inode->nlink = 1; - -@@ -3056,7 +3178,7 @@ - - - inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, -- struct inode_info *inode_info, void *data, struct dir_info *dir) -+ struct inode_info *inode_info, struct dir_info *dir) - { - if((dir->count % DIR_ENTRIES) == 0) { - dir->list = realloc(dir->list, (dir->count + DIR_ENTRIES) * -@@ -3075,8 +3197,7 @@ - NULL; - dir->list[dir->count]->inode = inode_info; - dir->list[dir->count]->dir = sub_dir; -- dir->list[dir->count]->our_dir = dir; -- dir->list[dir->count++]->data = data; -+ dir->list[dir->count++]->our_dir = dir; - dir->byte_count += strlen(name) + sizeof(squashfs_dir_entry); - } - -@@ -3128,10 +3249,10 @@ - - if(dir->count < old_root_entries) - for(i = 0; i < old_root_entries; i++) { -- if(old_root_entry[i].type == SQUASHFS_DIR_TYPE) -+ if(old_root_entry[i].inode.type == SQUASHFS_DIR_TYPE) - dir->directory_count ++; -- add_dir_entry(old_root_entry[i].name, "", NULL, NULL, -- &old_root_entry[i], dir); -+ add_dir_entry(old_root_entry[i].name, "", NULL, -+ &old_root_entry[i].inode, dir); - } - - while(index < source) { -@@ -3167,10 +3288,10 @@ - - if(dir->count < old_root_entries) - for(i = 0; i < old_root_entries; i++) { -- if(old_root_entry[i].type == SQUASHFS_DIR_TYPE) -+ if(old_root_entry[i].inode.type == SQUASHFS_DIR_TYPE) - dir->directory_count ++; -- add_dir_entry(old_root_entry[i].name, "", NULL, NULL, -- &old_root_entry[i], dir); -+ add_dir_entry(old_root_entry[i].name, "", NULL, -+ &old_root_entry[i].inode, dir); - } - - if((d_name = readdir(dir->linuxdir)) != NULL) { -@@ -3215,7 +3336,7 @@ - int current_count; - - while((current_count = dir_info->current_count++) < dir_info->count) -- if(dir_info->list[current_count]->data) -+ if(dir_info->list[current_count]->inode->root_entry) - continue; - else - return dir_info->list[current_count]; -@@ -3240,11 +3361,11 @@ - int current_count; - - while((current_count = dir_info->current_count++) < dir_info->count) -- if(dir_info->list[current_count]->data) -- add_dir(dir_info->list[current_count]->data->inode, -- dir_info->list[current_count]->data->inode_number, -+ if(dir_info->list[current_count]->inode->root_entry) -+ add_dir(dir_info->list[current_count]->inode->inode, -+ dir_info->list[current_count]->inode->inode_number, - dir_info->list[current_count]->name, -- dir_info->list[current_count]->data->type, dir); -+ dir_info->list[current_count]->inode->type, dir); - else - return dir_info->list[current_count]; - return NULL; -@@ -3313,7 +3434,6 @@ - dir_ent->name = dir_ent->pathname = strdup(pathname); - dir_ent->dir = dir_info; - dir_ent->our_dir = NULL; -- dir_ent->data = NULL; - dir_info->dir_ent = dir_ent; - - if(sorted) -@@ -3383,7 +3503,7 @@ - sub_dir = NULL; - - add_dir_entry(dir_name, filename, sub_dir, lookup_inode(&buf), -- NULL, dir); -+ dir); - } - - scan1_freedir(dir); -@@ -3399,7 +3519,7 @@ - struct dir_ent *dir_ent; - struct pseudo_entry *pseudo_ent; - struct stat buf; -- static pseudo_ino = 1; -+ static int pseudo_ino = 1; - - if(dir == NULL && (dir = scan1_opendir("")) == NULL) - return NULL; -@@ -3415,6 +3535,29 @@ - - while((pseudo_ent = pseudo_readdir(pseudo)) != NULL) { - dir_ent = scan2_lookup(dir, pseudo_ent->name); -+ if(pseudo_ent->dev->type == 's') { -+ struct stat *buf; -+ if(dir_ent == NULL) { -+ ERROR("Pseudo set file \"%s\" does not exist " -+ "in source filesystem. Ignoring\n", -+ pseudo_ent->pathname); -+ continue; -+ } -+ if(dir_ent->inode->root_entry) { -+ ERROR("Pseudo set file \"%s\" is a pre-existing" -+ " file in the filesystem being appended" -+ " to. It cannot be modified. " -+ "Ignoring!\n", pseudo_ent->pathname); -+ continue; -+ } -+ buf = &dir_ent->inode->buf; -+ buf->st_mode = (buf->st_mode & S_IFMT) | -+ pseudo_ent->dev->mode; -+ buf->st_uid = pseudo_ent->dev->uid; -+ buf->st_gid = pseudo_ent->dev->gid; -+ continue; -+ } -+ - if(dir_ent) { - ERROR("Pseudo file \"%s\" exists in source filesystem " - "\"%s\"\n", pseudo_ent->pathname, -@@ -3444,8 +3587,29 @@ - buf.st_mtime = time(NULL); - buf.st_ino = pseudo_ino ++; - -- add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, sub_dir, -- lookup_inode(&buf), NULL, dir); -+ if(pseudo_ent->dev->type == 'f') { -+#ifdef USE_TMP_FILE -+ struct stat buf2; -+ int res = stat(pseudo_ent->dev->filename, &buf2); -+ if(res == -1) { -+ ERROR("Stat on pseudo file \"%s\" failed, " -+ "skipping...", pseudo_ent->pathname); -+ continue; -+ } -+ buf.st_size = buf2.st_size; -+ add_dir_entry(pseudo_ent->name, -+ pseudo_ent->dev->filename, sub_dir, -+ lookup_inode(&buf), dir); -+#else -+ struct inode_info *inode = lookup_inode(&buf); -+ inode->pseudo_id = pseudo_ent->dev->pseudo_id; -+ inode->pseudo_file = TRUE; -+ add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, -+ sub_dir, inode, dir); -+#endif -+ } else -+ add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, -+ sub_dir, lookup_inode(&buf), dir); - } - - scan2_freedir(dir); -@@ -3482,8 +3646,9 @@ - &duplicate_file); - INFO("file %s, uncompressed size %lld " - "bytes %s\n", filename, -- buf->st_size, duplicate_file ? -- "DUPLICATE" : ""); -+ (long long) buf->st_size, -+ duplicate_file ? "DUPLICATE" : -+ ""); - break; - - case S_IFDIR: -@@ -3557,6 +3722,7 @@ - INFO("file %s, uncompressed " - "size %lld bytes LINK" - "\n", filename, -+ (long long) - buf->st_size); - break; - case SQUASHFS_SYMLINK_TYPE: -@@ -3667,10 +3833,11 @@ - BAD_ERROR("Out of memory in old root directory entries " - "reallocation\n"); - -- strcpy(old_root_entry[old_root_entries].name, name); -- old_root_entry[old_root_entries].inode = inode; -- old_root_entry[old_root_entries].inode_number = inode_number; -- old_root_entry[old_root_entries++].type = type; -+ old_root_entry[old_root_entries].name = strdup(name); -+ old_root_entry[old_root_entries].inode.inode = inode; -+ old_root_entry[old_root_entries].inode.inode_number = inode_number; -+ old_root_entry[old_root_entries].inode.type = type; -+ old_root_entry[old_root_entries++].inode.root_entry = TRUE; - } - - -@@ -4137,7 +4304,7 @@ - - - #define VERSION() \ -- printf("mksquashfs version 4.0 (2009/04/05)\n");\ -+ printf("mksquashfs version 4.1-CVS (2009/09/20)\n");\ - printf("copyright (C) 2009 Phillip Lougher <phillip@lougher.demon.co.uk>\n\n"); \ - printf("This program is free software; you can redistribute it and/or\n");\ - printf("modify it under the terms of the GNU General Public License\n");\ -@@ -4172,26 +4339,28 @@ - source_path = argv + 1; - source = i - 2; - for(; i < argc; i++) { -- if(strcmp(argv[i], "-pf") == 0) { -+ if(strcmp(argv[i], "-comp") == 0) { - if(++i == argc) { -- ERROR("%s: -pf missing filename\n", argv[0]); -+ ERROR("%s: -comp missing compression type\n", -+ argv[0]); - exit(1); - } -- if(read_pseudo_file(&pseudo, argv[i]) == FALSE) { -- ERROR("Failed to parse pseudo file \"%s\"\n", -- argv[i]); -+ comp_name = argv[i]; -+ } else if(strcmp(argv[i], "-pf") == 0) { -+ if(++i == argc) { -+ ERROR("%s: -pf missing filename\n", argv[0]); - exit(1); - } -+ if(read_pseudo_file(&pseudo, argv[i]) == FALSE) -+ exit(1); - } else if(strcmp(argv[i], "-p") == 0) { - if(++i == argc) { - ERROR("%s: -p missing pseudo file definition\n", - argv[0]); - exit(1); - } -- if(read_pseudo_def(&pseudo, argv[i]) == FALSE) { -- ERROR("Failed to parse pseudo definition\n"); -+ if(read_pseudo_def(&pseudo, argv[i]) == FALSE) - exit(1); -- } - } else if(strcmp(argv[i], "-recover") == 0) { - if(++i == argc) { - ERROR("%s: -recover missing recovery file\n", -@@ -4394,34 +4563,16 @@ - printOptions: - ERROR("SYNTAX:%s source1 source2 ... dest [options] " - "[-e list of exclude\ndirs/files]\n", argv[0]); -- ERROR("\nOptions are\n"); -- ERROR("-version\t\tprint version, licence and " -- "copyright message\n"); -- ERROR("-recover <name>\t\trecover filesystem data " -- "using recovery file <name>\n"); -- ERROR("-no-recovery\t\tdon't generate a recovery " -- "file\n"); -- ERROR("-info\t\t\tprint files written to filesystem\n"); -- ERROR("-no-exports\t\tdon't make the filesystem " -- "exportable via NFS\n"); -- ERROR("-no-progress\t\tdon't display the progress " -- "bar\n"); -- ERROR("-no-sparse\t\tdon't detect sparse files\n"); -+ ERROR("\nFilesystem build options:\n"); -+ ERROR("-comp <comp>\t\tselect <comp> compression\n"); -+ ERROR("\t\t\tCompressors available:\n"); -+ display_compressors("\t\t\t", COMP_DEFAULT); - ERROR("-b <block_size>\t\tset data block to " - "<block_size>. Default %d bytes\n", - SQUASHFS_FILE_SIZE); -- ERROR("-processors <number>\tUse <number> processors." -- " By default will use number of\n"); -- ERROR("\t\t\tprocessors available\n"); -- ERROR("-read-queue <size>\tSet input queue to <size> " -- "Mbytes. Default %d Mbytes\n", -- READER_BUFFER_DEFAULT); -- ERROR("-write-queue <size>\tSet output queue to <size> " -- "Mbytes. Default %d Mbytes\n", -- WRITER_BUFFER_DEFAULT); -- ERROR("-fragment-queue <size>\tSet fagment queue to " -- "<size> Mbytes. Default %d Mbytes\n", -- FRAGMENT_BUFFER_DEFAULT); -+ ERROR("-no-exports\t\tdon't make the filesystem " -+ "exportable via NFS\n"); -+ ERROR("-no-sparse\t\tdon't detect sparse files\n"); - ERROR("-noI\t\t\tdo not compress inode table\n"); - ERROR("-noD\t\t\tdo not compress data blocks\n"); - ERROR("-noF\t\t\tdo not compress fragment blocks\n"); -@@ -4430,13 +4581,34 @@ - "files larger than block size\n"); - ERROR("-no-duplicates\t\tdo not perform duplicate " - "checking\n"); -- ERROR("-noappend\t\tdo not append to existing " -- "filesystem\n"); -+ ERROR("-all-root\t\tmake all files owned by root\n"); -+ ERROR("-force-uid uid\t\tset all file uids to uid\n"); -+ ERROR("-force-gid gid\t\tset all file gids to gid\n"); -+ ERROR("-nopad\t\t\tdo not pad filesystem to a multiple " -+ "of 4K\n"); - ERROR("-keep-as-directory\tif one source directory is " - "specified, create a root\n"); - ERROR("\t\t\tdirectory containing that directory, " - "rather than the\n"); - ERROR("\t\t\tcontents of the directory\n"); -+ ERROR("\nFilesystem filter options:\n"); -+ ERROR("-p <pseudo-definition>\tAdd pseudo file definition\n"); -+ ERROR("-pf <pseudo-file>\tAdd list of pseudo file definitions\n"); -+ ERROR("-sort <sort_file>\tsort files according to " -+ "priorities in <sort_file>. One\n"); -+ ERROR("\t\t\tfile or dir with priority per line. " -+ "Priority -32768 to\n"); -+ ERROR("\t\t\t32767, default priority 0\n"); -+ ERROR("-ef <exclude_file>\tlist of exclude dirs/files." -+ " One per line\n"); -+ ERROR("-wildcards\t\tAllow extended shell wildcards " -+ "(globbing) to be used in\n\t\t\texclude " -+ "dirs/files\n"); -+ ERROR("-regex\t\t\tAllow POSIX regular expressions to " -+ "be used in exclude\n\t\t\tdirs/files\n"); -+ ERROR("\nFilesystem append options:\n"); -+ ERROR("-noappend\t\tdo not append to existing " -+ "filesystem\n"); - ERROR("-root-becomes <name>\twhen appending source " - "files/directories, make the\n"); - ERROR("\t\t\toriginal root become a subdirectory in " -@@ -4444,11 +4616,29 @@ - ERROR("\t\t\tcalled <name>, rather than adding the new " - "source items\n"); - ERROR("\t\t\tto the original root\n"); -- ERROR("-all-root\t\tmake all files owned by root\n"); -- ERROR("-force-uid uid\t\tset all file uids to uid\n"); -- ERROR("-force-gid gid\t\tset all file gids to gid\n"); -- ERROR("-nopad\t\t\tdo not pad filesystem to a multiple " -- "of 4K\n"); -+ ERROR("\nMksquashfs runtime options:\n"); -+ ERROR("-version\t\tprint version, licence and " -+ "copyright message\n"); -+ ERROR("-recover <name>\t\trecover filesystem data " -+ "using recovery file <name>\n"); -+ ERROR("-no-recovery\t\tdon't generate a recovery " -+ "file\n"); -+ ERROR("-info\t\t\tprint files written to filesystem\n"); -+ ERROR("-no-progress\t\tdon't display the progress " -+ "bar\n"); -+ ERROR("-processors <number>\tUse <number> processors." -+ " By default will use number of\n"); -+ ERROR("\t\t\tprocessors available\n"); -+ ERROR("-read-queue <size>\tSet input queue to <size> " -+ "Mbytes. Default %d Mbytes\n", -+ READER_BUFFER_DEFAULT); -+ ERROR("-write-queue <size>\tSet output queue to <size> " -+ "Mbytes. Default %d Mbytes\n", -+ WRITER_BUFFER_DEFAULT); -+ ERROR("-fragment-queue <size>\tSet fagment queue to " -+ "<size> Mbytes. Default %d Mbytes\n", -+ FRAGMENT_BUFFER_DEFAULT); -+ ERROR("\nMiscellaneous options:\n"); - ERROR("-root-owned\t\talternative name for -all-root" - "\n"); - ERROR("-noInodeCompression\talternative name for -noI" -@@ -4457,20 +4647,6 @@ - "\n"); - ERROR("-noFragmentCompression\talternative name for " - "-noF\n"); -- ERROR("-sort <sort_file>\tsort files according to " -- "priorities in <sort_file>. One\n"); -- ERROR("\t\t\tfile or dir with priority per line. " -- "Priority -32768 to\n"); -- ERROR("\t\t\t32767, default priority 0\n"); -- ERROR("-ef <exclude_file>\tlist of exclude dirs/files." -- " One per line\n"); -- ERROR("-wildcards\t\tAllow extended shell wildcards " -- "(globbing) to be used in\n\t\t\texclude " -- "dirs/files\n"); -- ERROR("-regex\t\t\tAllow POSIX regular expressions to " -- "be used in exclude\n\t\t\tdirs/files\n"); -- ERROR("-p <pseudo-definition>\tAdd pseudo file definition\n"); -- ERROR("-pf <pseudo-file>\tAdd list of pseudo file definitions\n"); - exit(1); - } - } -@@ -4548,11 +4724,10 @@ - fclose(fd); - } else if(strcmp(argv[i], "-e") == 0) - break; -- else if(strcmp(argv[i], "-b") == 0 || -- strcmp(argv[i], "-root-becomes") == 0 || -+ else if(strcmp(argv[i], "-root-becomes") == 0 || - strcmp(argv[i], "-sort") == 0 || - strcmp(argv[i], "-pf") == 0 || -- strcmp(argv[i], "-p") == 0) -+ strcmp(argv[i], "-comp") == 0) - i++; - - if(i != argc) { -@@ -4574,11 +4749,10 @@ - sorted ++; - } else if(strcmp(argv[i], "-e") == 0) - break; -- else if(strcmp(argv[i], "-b") == 0 || -- strcmp(argv[i], "-root-becomes") == 0 || -+ else if(strcmp(argv[i], "-root-becomes") == 0 || - strcmp(argv[i], "-ef") == 0 || - strcmp(argv[i], "-pf") == 0 || -- strcmp(argv[i], "-p") == 0) -+ strcmp(argv[i], "-comp") == 0) - i++; - - #ifdef SQUASHFS_TRACE -@@ -4586,7 +4760,8 @@ - #endif - - if(!delete) { -- if(read_super(fd, &sBlk, argv[source + 1]) == 0) { -+ comp = read_super(fd, &sBlk, argv[source + 1]); -+ if(comp == NULL) { - ERROR("Failed to read existing filesystem - will not " - "overwrite - ABORTING!\n"); - ERROR("To force Mksquashfs to write to this block " -@@ -4603,6 +4778,15 @@ - always_use_fragments = SQUASHFS_ALWAYS_FRAGMENTS(sBlk.flags); - duplicate_checking = SQUASHFS_DUPLICATES(sBlk.flags); - exportable = SQUASHFS_EXPORTABLE(sBlk.flags); -+ } else { -+ comp = lookup_compressor(comp_name); -+ if(!comp->supported) { -+ ERROR("FATAL_ERROR: Compressor \"%s\" is not " -+ "supported!\n", comp_name); -+ ERROR("Compressors available:\n"); -+ display_compressors("", COMP_DEFAULT); -+ EXIT_MKSQUASHFS(); -+ } - } - - initialise_threads(); -@@ -4648,8 +4832,8 @@ - "size %d\n", SQUASHFS_MAJOR, s_minor, argv[source + 1], - block_size); - printf("All -b, -noI, -noD, -noF, no-duplicates, no-fragments, " -- "-always-use-fragments and -exportable options ignored" -- "\n"); -+ "-always-use-fragments,\n-exportable and -comp options " -+ "ignored\n"); - printf("\nIf appending is not wanted, please re-run with " - "-noappend specified!\n\n"); - -@@ -4803,8 +4987,7 @@ - - sBlk.bytes_used = bytes; - -- /* Only compression supported */ -- sBlk.compression = ZLIB_COMPRESSION; -+ sBlk.compression = comp->id; - - /* Xattrs are not currently supported */ - sBlk.xattr_table_start = SQUASHFS_INVALID_BLK; -@@ -4820,6 +5003,8 @@ - - close(fd); - -+ delete_pseudo_files(); -+ - if(recovery_file[0] != '\0') - unlink(recovery_file); - -@@ -4827,9 +5012,9 @@ - * sizeof(unsigned short) + guid_count * sizeof(unsigned short) + - sizeof(squashfs_super_block); - -- printf("\n%sSquashfs %d.%d filesystem, data block size %d\n", -- exportable ? "Exportable " : "", SQUASHFS_MAJOR, SQUASHFS_MINOR, -- block_size); -+ printf("\n%sSquashfs %d.%d filesystem, %s compressed, data block size" -+ " %d\n", exportable ? "Exportable " : "", SQUASHFS_MAJOR, -+ SQUASHFS_MINOR, comp->name, block_size); - printf("\t%s data, %s metadata, %s fragments\n", - noD ? "uncompressed" : "compressed", noI ? "uncompressed" : - "compressed", no_fragments ? "no" : noF ? "uncompressed" : -diff -Nur squashfs4.0/squashfs-tools/pseudo.c squashfs4.0-lzma-snapshot/squashfs-tools/pseudo.c ---- squashfs4.0/squashfs-tools/pseudo.c 2009-04-05 04:01:58.000000000 +0200 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/pseudo.c 2009-10-20 06:03:38.000000000 +0200 -@@ -30,6 +30,7 @@ - #include <string.h> - #include <stdlib.h> - #include <sys/types.h> -+#include <sys/wait.h> - - #include "pseudo.h" - -@@ -55,6 +56,9 @@ - #define TRUE 1 - #define FALSE 0 - -+struct pseudo_dev **pseudo_file = NULL; -+int pseudo_count = 0; -+ - static void dump_pseudo(struct pseudo *pseudo, char *string) - { - int i; -@@ -99,7 +103,7 @@ - char *target, char *alltarget) - { - char targname[1024]; -- int i, error; -+ int i; - - target = get_component(target, targname); - -@@ -128,12 +132,8 @@ - if(target[0] == '\0') { - /* at leaf pathname component */ - pseudo->name[i].pseudo = NULL; -- pseudo->name[i].dev = malloc(sizeof(struct pseudo_dev)); -- if(pseudo->name[i].dev == NULL) -- BAD_ERROR("failed to allocate pseudo file\n"); - pseudo->name[i].pathname = strdup(alltarget); -- memcpy(pseudo->name[i].dev, pseudo_dev, -- sizeof(struct pseudo_dev)); -+ pseudo->name[i].dev = pseudo_dev; - } else { - /* recurse adding child components */ - pseudo->name[i].dev = NULL; -@@ -169,15 +169,9 @@ - if(target[0] == '\0') { - if(pseudo->name[i].dev == NULL && - pseudo_dev->type == 'd') { -- pseudo->name[i].dev = -- malloc(sizeof(struct pseudo_dev)); -- if(pseudo->name[i].dev == NULL) -- BAD_ERROR("failed to allocate " -- "pseudo file\n"); - pseudo->name[i].pathname = - strdup(alltarget); -- memcpy(pseudo->name[i].dev, pseudo_dev, -- sizeof(struct pseudo_dev)); -+ pseudo->name[i].dev = pseudo_dev; - } else - ERROR("%s already exists as a " - "directory. Ignoring %s!\n", -@@ -229,16 +223,113 @@ - } - - -+int exec_file(char *command, struct pseudo_dev *dev) -+{ -+ int child, res; -+ static pid_t pid = -1; -+ int pipefd[2]; -+#ifdef USE_TMP_FILE -+ char filename[1024]; -+ int status; -+ static int number = 0; -+#endif -+ -+ if(pid == -1) -+ pid = getpid(); -+ -+#ifdef USE_TMP_FILE -+ sprintf(filename, "/tmp/squashfs_pseudo_%d_%d", pid, number ++); -+ pipefd[1] = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU); -+ if(pipefd[1] == -1) { -+ printf("open failed\n"); -+ return -1; -+ } -+#else -+ res = pipe(pipefd); -+ if(res == -1) { -+ printf("pipe failed\n"); -+ return -1; -+ } -+#endif -+ -+ child = fork(); -+ if(child == -1) { -+ printf("fork failed\n"); -+ goto failed; -+ } -+ -+ if(child == 0) { -+ close(STDOUT_FILENO); -+ res = dup(pipefd[1]); -+ if(res == -1) { -+ printf("dup failed\n"); -+ exit(EXIT_FAILURE); -+ } -+ execl("/bin/sh", "sh", "-c", command, (char *) NULL); -+ printf("execl failed\n"); -+ exit(EXIT_FAILURE); -+ } -+ -+#ifdef USE_TMP_FILE -+ res = waitpid(child, &status, 0); -+ close(pipefd[1]); -+ if(res != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) { -+ dev->filename = strdup(filename); -+ return 0; -+ } -+failed: -+ unlink(filename); -+ return -1; -+#else -+ close(pipefd[1]); -+ dev->fd = pipefd[0]; -+ dev->child = child; -+ return 0; -+failed: -+ return -1; -+#endif -+} -+ -+ -+void add_pseudo_file(struct pseudo_dev *dev) -+{ -+ pseudo_file = realloc(pseudo_file, (pseudo_count + 1) * -+ sizeof(struct pseudo_dev *)); -+ if(pseudo_file == NULL) -+ BAD_ERROR("Failed to realloc pseudo_file\n"); -+ -+ dev->pseudo_id = pseudo_count; -+ pseudo_file[pseudo_count ++] = dev; -+} -+ -+ -+void delete_pseudo_files() -+{ -+#ifdef USE_TMP_FILE -+ int i; -+ -+ for(i = 0; i < pseudo_count; i++) -+ unlink(pseudo_file[i]->filename); -+#endif -+} -+ -+ -+struct pseudo_dev *get_pseudo_file(int pseudo_id) -+{ -+ return pseudo_file[pseudo_id]; -+} -+ -+ - int read_pseudo_def(struct pseudo **pseudo, char *def) - { -- int n; -+ int n, bytes; - unsigned int major = 0, minor = 0, mode; - char filename[2048], type, suid[100], sgid[100], *ptr; - long long uid, gid; -- struct pseudo_dev dev; -+ struct pseudo_dev *dev; - -- n = sscanf(def, "%s %c %o %s %s %u %u", filename, &type, &mode, suid, sgid, -- &major, &minor); -+ n = sscanf(def, "%s %c %o %s %s %n", filename, &type, &mode, suid, -+ sgid, &bytes); - - if(n < 5) { - ERROR("Not enough or invalid arguments in pseudo file " -@@ -249,7 +340,9 @@ - switch(type) { - case 'b': - case 'c': -- if(n < 7) { -+ n = sscanf(def + bytes, "%u %u", &major, &minor); -+ -+ if(n < 2) { - ERROR("Not enough or invalid arguments in pseudo file " - "definition\n"); - goto error; -@@ -265,47 +358,15 @@ - goto error; - } - -- /* fall through */ -- case 'd': -- if(mode > 0777) { -- ERROR("Mode %o out of range\n", mode); -+ case 'f': -+ if(def[bytes] == '\0') { -+ ERROR("Not enough arguments in pseudo file " -+ "definition\n"); - goto error; -- } -- -- uid = strtoll(suid, &ptr, 10); -- if(*ptr == '\0') { -- if(uid < 0 || uid > ((1LL << 32) - 1)) { -- ERROR("Uid %s out of range\n", suid); -- goto error; -- } -- } else { -- struct passwd *pwuid = getpwnam(suid); -- if(pwuid) -- uid = pwuid->pw_uid; -- else { -- ERROR("Uid %s invalid uid or unknown user\n", -- suid); -- goto error; -- } -- } -- -- gid = strtoll(sgid, &ptr, 10); -- if(*ptr == '\0') { -- if(gid < 0 || gid > ((1LL << 32) - 1)) { -- ERROR("Gid %s out of range\n", sgid); -- goto error; -- } -- } else { -- struct group *grgid = getgrnam(sgid); -- if(grgid) -- gid = grgid->gr_gid; -- else { -- ERROR("Gid %s invalid uid or unknown user\n", -- sgid); -- goto error; -- } -- } -- -+ } -+ break; -+ case 'd': -+ case 'm': - break; - default: - ERROR("Unsupported type %c\n", type); -@@ -313,6 +374,43 @@ - } - - -+ if(mode > 0777) { -+ ERROR("Mode %o out of range\n", mode); -+ goto error; -+ } -+ -+ uid = strtoll(suid, &ptr, 10); -+ if(*ptr == '\0') { -+ if(uid < 0 || uid > ((1LL << 32) - 1)) { -+ ERROR("Uid %s out of range\n", suid); -+ goto error; -+ } -+ } else { -+ struct passwd *pwuid = getpwnam(suid); -+ if(pwuid) -+ uid = pwuid->pw_uid; -+ else { -+ ERROR("Uid %s invalid uid or unknown user\n", suid); -+ goto error; -+ } -+ } -+ -+ gid = strtoll(sgid, &ptr, 10); -+ if(*ptr == '\0') { -+ if(gid < 0 || gid > ((1LL << 32) - 1)) { -+ ERROR("Gid %s out of range\n", sgid); -+ goto error; -+ } -+ } else { -+ struct group *grgid = getgrnam(sgid); -+ if(grgid) -+ gid = grgid->gr_gid; -+ else { -+ ERROR("Gid %s invalid uid or unknown user\n", sgid); -+ goto error; -+ } -+ } -+ - switch(type) { - case 'b': - mode |= S_IFBLK; -@@ -323,16 +421,37 @@ - case 'd': - mode |= S_IFDIR; - break; -+ case 'f': -+ mode |= S_IFREG; -+ break; - } - -- dev.type = type; -- dev.mode = mode; -- dev.uid = uid; -- dev.gid = gid; -- dev.major = major; -- dev.minor = minor; -+ dev = malloc(sizeof(struct pseudo_dev)); -+ if(dev == NULL) -+ BAD_ERROR("Failed to create pseudo_dev\n"); -+ -+ dev->type = type; -+ dev->mode = mode; -+ dev->uid = uid; -+ dev->gid = gid; -+ dev->major = major; -+ dev->minor = minor; -+ -+ if(type == 'f') { -+ int res; -+ -+ printf("Executing dynamic pseudo file\n"); -+ printf("\t\"%s\"\n", def); -+ res = exec_file(def + bytes, dev); -+ if(res == -1) { -+ ERROR("Failed to execute dynamic pseudo file definition" -+ " \"%s\"\n", def); -+ return FALSE; -+ } -+ add_pseudo_file(dev); -+ } - -- *pseudo = add_pseudo(*pseudo, &dev, filename, filename); -+ *pseudo = add_pseudo(*pseudo, dev, filename, filename); - - return TRUE; - -diff -Nur squashfs4.0/squashfs-tools/pseudo.h squashfs4.0-lzma-snapshot/squashfs-tools/pseudo.h ---- squashfs4.0/squashfs-tools/pseudo.h 2009-04-04 03:44:24.000000000 +0200 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/pseudo.h 2009-10-20 06:03:38.000000000 +0200 -@@ -27,6 +27,12 @@ - unsigned int gid; - unsigned int major; - unsigned int minor; -+ int pseudo_id; -+ int fd; -+ int child; -+#ifdef USE_TMP_FILE -+ char *filename; -+#endif - }; - - struct pseudo_entry { -@@ -46,3 +52,5 @@ - extern int read_pseudo_file(struct pseudo **, char *); - extern struct pseudo *pseudo_subdir(char *, struct pseudo *); - extern struct pseudo_entry *pseudo_readdir(struct pseudo *); -+extern struct pseudo_dev *get_pseudo_file(int); -+extern void delete_pseudo_files(); -diff -Nur squashfs4.0/squashfs-tools/read_fs.c squashfs4.0-lzma-snapshot/squashfs-tools/read_fs.c ---- squashfs4.0/squashfs-tools/read_fs.c 2009-03-31 06:23:14.000000000 +0200 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/read_fs.c 2009-10-20 06:03:38.000000000 +0200 -@@ -36,7 +36,6 @@ - #include <fcntl.h> - #include <errno.h> - #include <string.h> --#include <zlib.h> - #include <sys/mman.h> - - #ifndef linux -@@ -51,6 +50,7 @@ - #include "squashfs_swap.h" - #include "read_fs.h" - #include "global.h" -+#include "compressor.h" - - #include <stdlib.h> - -@@ -66,7 +66,9 @@ - fprintf(stderr, s, ## args); \ - } while(0) - --int read_block(int fd, long long start, long long *next, unsigned char *block, -+static struct compressor *comp; -+ -+int read_block(int fd, long long start, long long *next, void *block, - squashfs_super_block *sBlk) - { - unsigned short c_byte; -@@ -77,32 +79,24 @@ - - if(SQUASHFS_COMPRESSED(c_byte)) { - char buffer[SQUASHFS_METADATA_SIZE]; -- int res; -- unsigned long bytes = SQUASHFS_METADATA_SIZE; -+ int error, res; - - c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); - read_destination(fd, start + offset, c_byte, buffer); - -- res = uncompress(block, &bytes, (const unsigned char *) buffer, -- c_byte); -- if(res != Z_OK) { -- if(res == Z_MEM_ERROR) -- ERROR("zlib::uncompress failed, not enough " -- "memory\n"); -- else if(res == Z_BUF_ERROR) -- ERROR("zlib::uncompress failed, not enough " -- "room in output buffer\n"); -- else -- ERROR("zlib::uncompress failed, unknown error " -- "%d\n", res); -+ res = comp->uncompress(block, buffer, c_byte, -+ SQUASHFS_METADATA_SIZE, &error); -+ if(res == -1) { -+ ERROR("%s uncompress failed with error code %d\n", -+ comp->name, error); - return 0; - } - if(next) - *next = start + offset + c_byte; -- return bytes; -+ return res; - } else { - c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); -- read_destination(fd, start + offset, c_byte, (char *) block); -+ read_destination(fd, start + offset, c_byte, block); - if(next) - *next = start + offset + c_byte; - return c_byte; -@@ -356,7 +350,7 @@ - } - - --int read_super(int fd, squashfs_super_block *sBlk, char *source) -+struct compressor *read_super(int fd, squashfs_super_block *sBlk, char *source) - { - read_destination(fd, SQUASHFS_START, sizeof(squashfs_super_block), - (char *) sBlk); -@@ -388,8 +382,18 @@ - goto failed_mount; - } - -+ /* Check the compression type */ -+ comp = lookup_compressor_id(sBlk->compression); -+ if(!comp->supported) { -+ ERROR("Filesystem on %s uses %s compression, this is" -+ "unsupported by this version\n", source, comp->name); -+ display_compressors("", ""); -+ goto failed_mount; -+ } -+ - printf("Found a valid %sSQUASHFS superblock on %s.\n", - SQUASHFS_EXPORTABLE(sBlk->flags) ? "exportable " : "", source); -+ printf("\tCompression used %s\n", comp->name); - printf("\tInodes are %scompressed\n", - SQUASHFS_UNCOMPRESSED_INODES(sBlk->flags) ? "un" : ""); - printf("\tData is %scompressed\n", -@@ -417,10 +421,10 @@ - TRACE("sBlk->lookup_table_start %llx\n", sBlk->lookup_table_start); - printf("\n"); - -- return TRUE; -+ return comp; - - failed_mount: -- return FALSE; -+ return NULL; - } - - -@@ -514,12 +518,17 @@ - SQUASHFS_INSWAP_ID_BLOCKS(index, indexes); - - for(i = 0; i < indexes; i++) { -- int length; -- length = read_block(fd, index[i], NULL, -+ int length = read_block(fd, index[i], NULL, - ((unsigned char *) id_table) + - (i * SQUASHFS_METADATA_SIZE), sBlk); - TRACE("Read id table block %d, from 0x%llx, length %d\n", i, - index[i], length); -+ if(length == 0) { -+ ERROR("Failed to read id table block %d, from 0x%llx, " -+ "length %d\n", i, index[i], length); -+ free(id_table); -+ return NULL; -+ } - } - - SQUASHFS_INSWAP_INTS(id_table, sBlk->no_ids); -@@ -563,6 +572,13 @@ - (i * SQUASHFS_METADATA_SIZE), sBlk); - TRACE("Read fragment table block %d, from 0x%llx, length %d\n", - i, fragment_table_index[i], length); -+ if(length == 0) { -+ ERROR("Failed to read fragment table block %d, from " -+ "0x%llx, length %d\n", i, -+ fragment_table_index[i], length); -+ free(*fragment_table); -+ return 0; -+ } - } - - for(i = 0; i < sBlk->fragments; i++) -@@ -599,6 +615,13 @@ - (i * SQUASHFS_METADATA_SIZE), sBlk); - TRACE("Read inode lookup table block %d, from 0x%llx, length " - "%d\n", i, index[i], length); -+ if(length == 0) { -+ ERROR("Failed to read inode lookup table block %d, " -+ "from 0x%llx, length %d\n", i, index[i], -+ length); -+ free(*inode_lookup_table); -+ return 0; -+ } - } - - SQUASHFS_INSWAP_LONG_LONGS(*inode_lookup_table, sBlk->inodes); -diff -Nur squashfs4.0/squashfs-tools/sort.c squashfs4.0-lzma-snapshot/squashfs-tools/sort.c ---- squashfs4.0/squashfs-tools/sort.c 2009-03-31 06:25:53.000000000 +0200 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/sort.c 2009-10-20 06:03:38.000000000 +0200 -@@ -198,7 +198,7 @@ - while(dir->current_count < dir->count) { - struct dir_ent *dir_ent = dir->list[dir->current_count++]; - struct stat *buf = &dir_ent->inode->buf; -- if(dir_ent->data) -+ if(dir_ent->inode->root_entry) - continue; - - switch(buf->st_mode & S_IFMT) { -@@ -254,6 +254,7 @@ - write_file(&inode, entry->dir, &duplicate_file); - INFO("file %s, uncompressed size %lld bytes %s" - "\n", entry->dir->pathname, -+ (long long) - entry->dir->inode->buf.st_size, - duplicate_file ? "DUPLICATE" : ""); - entry->dir->inode->inode = inode; -@@ -261,6 +262,7 @@ - } else - INFO("file %s, uncompressed size %lld bytes " - "LINK\n", entry->dir->pathname, -+ (long long) - entry->dir->inode->buf.st_size); - } - } -diff -Nur squashfs4.0/squashfs-tools/sort.h squashfs4.0-lzma-snapshot/squashfs-tools/sort.h ---- squashfs4.0/squashfs-tools/sort.h 2009-02-08 13:02:53.000000000 +0100 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/sort.h 2009-10-20 06:03:38.000000000 +0200 -@@ -42,17 +42,19 @@ - struct inode_info *inode; - struct dir_info *dir; - struct dir_info *our_dir; -- struct old_root_entry_info *data; - }; - - struct inode_info { -- unsigned int nlink; - struct stat buf; -+ struct inode_info *next; - squashfs_inode inode; -- unsigned int type; - unsigned int inode_number; -+ unsigned int nlink; -+ int pseudo_id; -+ char type; - char read; -- struct inode_info *next; -+ char root_entry; -+ char pseudo_file; - }; - - struct priority_entry { -diff -Nur squashfs4.0/squashfs-tools/squashfs_compat.h squashfs4.0-lzma-snapshot/squashfs-tools/squashfs_compat.h ---- squashfs4.0/squashfs-tools/squashfs_compat.h 2009-03-16 05:27:27.000000000 +0100 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/squashfs_compat.h 2009-10-20 06:03:38.000000000 +0200 -@@ -777,11 +777,10 @@ - #endif - - #define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\ -- int bits;\ -- int b_pos = pos % 8;\ -- unsigned long long val = 0;\ -- unsigned char *s = (unsigned char *)p + (pos / 8);\ -- unsigned char *d = ((unsigned char *) &val) + 7;\ -+ b_pos = pos % 8;\ -+ val = 0;\ -+ s = (unsigned char *)p + (pos / 8);\ -+ d = ((unsigned char *) &val) + 7;\ - for(bits = 0; bits < (tbits + b_pos); bits += 8) \ - *d-- = *s++;\ - value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\ -diff -Nur squashfs4.0/squashfs-tools/squashfs_fs.h squashfs4.0-lzma-snapshot/squashfs-tools/squashfs_fs.h ---- squashfs4.0/squashfs-tools/squashfs_fs.h 2009-03-18 03:50:20.000000000 +0100 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/squashfs_fs.h 2009-10-20 06:03:38.000000000 +0200 -@@ -229,6 +229,7 @@ - typedef long long squashfs_inode_t; - - #define ZLIB_COMPRESSION 1 -+#define LZMA_COMPRESSION 2 - - struct squashfs_super_block { - unsigned int s_magic; -diff -Nur squashfs4.0/squashfs-tools/unsquash-3.c squashfs4.0-lzma-snapshot/squashfs-tools/unsquash-3.c ---- squashfs4.0/squashfs-tools/unsquash-3.c 2009-03-31 06:35:10.000000000 +0200 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/unsquash-3.c 2009-10-20 06:03:38.000000000 +0200 -@@ -36,7 +36,7 @@ - sBlk.fragment_table_start); - - if(sBlk.fragments == 0) -- return; -+ return TRUE; - - if((fragment_table = malloc(sBlk.fragments * - sizeof(squashfs_fragment_entry_3))) == NULL) -diff -Nur squashfs4.0/squashfs-tools/unsquash-4.c squashfs4.0-lzma-snapshot/squashfs-tools/unsquash-4.c ---- squashfs4.0/squashfs-tools/unsquash-4.c 2009-03-31 06:38:31.000000000 +0200 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/unsquash-4.c 2009-10-20 06:03:38.000000000 +0200 -@@ -38,7 +38,7 @@ - sBlk.fragment_table_start); - - if(sBlk.fragments == 0) -- return; -+ return TRUE; - - if((fragment_table = malloc(sBlk.fragments * - sizeof(squashfs_fragment_entry))) == NULL) -diff -Nur squashfs4.0/squashfs-tools/unsquashfs.c squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.c ---- squashfs4.0/squashfs-tools/unsquashfs.c 2009-04-05 23:23:06.000000000 +0200 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.c 2009-10-20 06:03:39.000000000 +0200 -@@ -25,6 +25,7 @@ - #include "squashfs_swap.h" - #include "squashfs_compat.h" - #include "read_fs.h" -+#include "compressor.h" - - struct cache *fragment_cache, *data_cache; - struct queue *to_reader, *to_deflate, *to_writer, *from_writer; -@@ -36,6 +39,7 @@ - - struct super_block sBlk; - squashfs_operations s_ops; -+struct compressor *comp; - - int bytes = 0, swap, file_count = 0, dir_count = 0, sym_count = 0, - dev_count = 0, fifo_count = 0; -@@ -590,31 +594,23 @@ - offset = 3; - if(SQUASHFS_COMPRESSED(c_byte)) { - char buffer[SQUASHFS_METADATA_SIZE]; -- int res; -- unsigned long bytes = SQUASHFS_METADATA_SIZE; -+ int error, res; - - c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); - if(read_bytes(start + offset, c_byte, buffer) == FALSE) - goto failed; - -- res = uncompress((unsigned char *) block, &bytes, -- (const unsigned char *) buffer, c_byte); -+ res = comp->uncompress(block, buffer, c_byte, -+ SQUASHFS_METADATA_SIZE, &error); - -- if(res != Z_OK) { -- if(res == Z_MEM_ERROR) -- ERROR("zlib::uncompress failed, not enough " -- "memory\n"); -- else if(res == Z_BUF_ERROR) -- ERROR("zlib::uncompress failed, not enough " -- "room in output buffer\n"); -- else -- ERROR("zlib::uncompress failed, unknown error " -- "%d\n", res); -+ if(res == -1) { -+ ERROR("%s uncompress failed with error code %d\n", -+ comp->name, error); - goto failed; - } - if(next) - *next = start + offset + c_byte; -- return bytes; -+ return res; - } else { - c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); - if(read_bytes(start + offset, c_byte, block) == FALSE) -@@ -632,36 +628,26 @@ - - int read_data_block(long long start, unsigned int size, char *block) - { -- int res; -- unsigned long bytes = block_size; -+ int error, res; - int c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(size); - - TRACE("read_data_block: block @0x%llx, %d %s bytes\n", start, -- SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte), -- SQUASHFS_COMPRESSED_BLOCK(c_byte) ? "compressed" : -+ c_byte, SQUASHFS_COMPRESSED_BLOCK(size) ? "compressed" : - "uncompressed"); - - if(SQUASHFS_COMPRESSED_BLOCK(size)) { - if(read_bytes(start, c_byte, data) == FALSE) - goto failed; - -- res = uncompress((unsigned char *) block, &bytes, -- (const unsigned char *) data, c_byte); -+ res = comp->uncompress(block, data, c_byte, block_size, &error); - -- if(res != Z_OK) { -- if(res == Z_MEM_ERROR) -- ERROR("zlib::uncompress failed, not enough " -- "memory\n"); -- else if(res == Z_BUF_ERROR) -- ERROR("zlib::uncompress failed, not enough " -- "room in output buffer\n"); -- else -- ERROR("zlib::uncompress failed, unknown error " -- "%d\n", res); -+ if(res == -1) { -+ ERROR("%s uncompress failed with error code %d\n", -+ comp->name, error); - goto failed; - } - -- return bytes; -+ return res; - } else { - if(read_bytes(start, c_byte, block) == FALSE) - goto failed; -@@ -671,7 +657,7 @@ - - failed: - ERROR("read_data_block: failed to read block @0x%llx, size %d\n", start, -- size); -+ c_byte); - return FALSE; - } - -@@ -1383,6 +1369,11 @@ - #endif - printf("Creation or last append time %s", mkfs_str ? mkfs_str : - "failed to get time\n"); -+ printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n", -+ sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0)); -+ if(sBlk.s_major == 4) -+ printf("Compression %s\n", comp->name); -+ printf("Block size %d\n", sBlk.block_size); - printf("Filesystem is %sexportable via NFS\n", - SQUASHFS_EXPORTABLE(sBlk.flags) ? "" : "not "); - -@@ -1409,9 +1400,6 @@ - SQUASHFS_DUPLICATES(sBlk.flags) ? "" : "not "); - else - printf("Duplicates are removed\n"); -- printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n", -- sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0)); -- printf("Block size %d\n", sBlk.block_size); - if(sBlk.s_major > 1) - printf("Number of fragments %d\n", sBlk.fragments); - printf("Number of inodes %d\n", sBlk.inodes); -@@ -1459,6 +1447,18 @@ - s_ops.read_inode = read_inode_4; - s_ops.read_uids_guids = read_uids_guids_4; - memcpy(&sBlk, &sBlk_4, sizeof(sBlk_4)); -+ -+ /* -+ * Check the compression type -+ */ -+ comp = lookup_compressor_id(sBlk.compression); -+ if(!comp->supported) { -+ ERROR("Filesystem uses %s compression, this is " -+ "unsupported by this version\n", comp->name); -+ ERROR("Decompressors available:\n"); -+ display_compressors("", ""); -+ goto failed_mount; -+ } - return TRUE; - } - -@@ -1548,6 +1548,11 @@ - goto failed_mount; - } - -+ /* -+ * 1.x, 2.x and 3.x filesystems use gzip compression. Gzip is always -+ * suppported. -+ */ -+ comp = lookup_compressor("gzip"); - return TRUE; - - failed_mount: -@@ -1707,32 +1712,24 @@ - - while(1) { - struct cache_entry *entry = queue_get(to_deflate); -- int res; -- unsigned long bytes = block_size; -+ int error, res; - -- res = uncompress((unsigned char *) tmp, &bytes, -- (const unsigned char *) entry->data, -- SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size)); -- -- if(res != Z_OK) { -- if(res == Z_MEM_ERROR) -- ERROR("zlib::uncompress failed, not enough" -- "memory\n"); -- else if(res == Z_BUF_ERROR) -- ERROR("zlib::uncompress failed, not enough " -- "room in output buffer\n"); -- else -- ERROR("zlib::uncompress failed, unknown error " -- "%d\n", res); -- } else -- memcpy(entry->data, tmp, bytes); -+ res = comp->uncompress(tmp, entry->data, -+ SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size), block_size, -+ &error); -+ -+ if(res == -1) -+ ERROR("%s uncompress failed with error code %d\n", -+ comp->name, error); -+ else -+ memcpy(entry->data, tmp, res); - - /* - * block has been either successfully decompressed, or an error - * occurred, clear pending flag, set error appropriately and - * wake up any threads waiting on this block - */ -- cache_block_ready(entry, res != Z_OK); -+ cache_block_ready(entry, res == -1); - } - } - -@@ -1913,7 +1910,7 @@ - - - #define VERSION() \ -- printf("unsquashfs version 4.0 (2009/04/05)\n");\ -+ printf("unsquashfs version 4.1-CVS (2009/08/30)\n");\ - printf("copyright (C) 2009 Phillip Lougher <phillip@lougher.demon.co.uk>"\ - "\n\n");\ - printf("This program is free software; you can redistribute it and/or\n");\ -@@ -1938,7 +1935,6 @@ - int fragment_buffer_size = FRAGMENT_BUFFER_DEFAULT; - int data_buffer_size = DATA_BUFFER_DEFAULT; - char *b; -- struct winsize winsize; - - pthread_mutex_init(&screen_mutex, NULL); - root_process = geteuid() == 0; -@@ -2087,6 +2083,8 @@ - "regular expressions\n"); - ERROR("\t\t\t\trather than use the default shell " - "wildcard\n\t\t\t\texpansion (globbing)\n"); -+ ERROR("\nDecompressors available:\n"); -+ display_compressors("", ""); - } - exit(1); - } -diff -Nur squashfs4.0/squashfs-tools/unsquashfs.h squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.h ---- squashfs4.0/squashfs-tools/unsquashfs.h 2009-03-29 04:29:02.000000000 +0200 -+++ squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.h 2009-10-20 06:03:39.000000000 +0200 -@@ -31,7 +31,6 @@ - #include <fcntl.h> - #include <errno.h> - #include <string.h> --#include <zlib.h> - #include <sys/mman.h> - #include <utime.h> - #include <pwd.h> diff --git a/tools/squashfs4/patches/120-cygwin_fixes.patch b/tools/squashfs4/patches/120-cygwin_fixes.patch index 79469a9ea..fa1dfba42 100644 --- a/tools/squashfs4/patches/120-cygwin_fixes.patch +++ b/tools/squashfs4/patches/120-cygwin_fixes.patch @@ -1,20 +1,6 @@ ---- a/squashfs-tools/global.h -+++ b/squashfs-tools/global.h -@@ -44,6 +44,11 @@ typedef long long squashfs_fragment_inde - typedef squashfs_inode_t squashfs_inode; - typedef squashfs_block_t squashfs_block; - -+#ifdef __CYGWIN__ -+#include <sys/termios.h> -+#define FNM_EXTMATCH (1 << 5) -+#endif -+ - #ifndef FNM_EXTMATCH - #define FNM_EXTMATCH 0 - #endif --- a/squashfs-tools/mksquashfs.c +++ b/squashfs-tools/mksquashfs.c -@@ -49,10 +49,12 @@ +@@ -51,15 +51,22 @@ #include <sys/wait.h> #ifndef linux @@ -27,7 +13,17 @@ #else #include <endian.h> #include <sys/sysinfo.h> -@@ -817,6 +819,7 @@ void sigusr1_handler() + #endif + ++#ifdef __CYGWIN__ ++#include <sys/termios.h> ++#define FNM_EXTMATCH (1 << 5) ++#endif ++ + #ifndef FNM_EXTMATCH + #define FNM_EXTMATCH 0 + #endif +@@ -844,6 +851,7 @@ void sigusr1_handler() void sigwinch_handler() { @@ -35,7 +31,7 @@ struct winsize winsize; if(ioctl(1, TIOCGWINSZ, &winsize) == -1) { -@@ -826,6 +829,9 @@ void sigwinch_handler() +@@ -853,6 +861,9 @@ void sigwinch_handler() columns = 80; } else columns = winsize.ws_col; @@ -45,28 +41,27 @@ } -@@ -3853,7 +3859,9 @@ void initialise_threads() - BAD_ERROR("Failed to set signal mask in intialise_threads\n"); +@@ -4066,6 +4077,9 @@ void initialise_threads(int readb_mbytes signal(SIGUSR1, sigusr1_handler); -- + +#ifdef __CYGWIN__ + processors = atoi(getenv("NUMBER_OF_PROCESSORS")); +#else if(processors == -1) { #ifndef linux int mib[2]; -@@ -3875,6 +3883,7 @@ void initialise_threads() - processors = get_nprocs(); +@@ -4087,6 +4101,7 @@ void initialise_threads(int readb_mbytes + processors = sysconf(_SC_NPROCESSORS_ONLN); #endif } +#endif /* __CYGWIN__ */ - if((thread = malloc((2 + processors * 2) * sizeof(pthread_t))) == NULL) - BAD_ERROR("Out of memory allocating thread descriptors\n"); + thread = malloc((2 + processors * 2) * sizeof(pthread_t)); + if(thread == NULL) --- a/squashfs-tools/read_fs.c +++ b/squashfs-tools/read_fs.c -@@ -39,9 +39,11 @@ extern unsigned int get_guid(unsigned in +@@ -33,9 +33,11 @@ #include <sys/mman.h> #ifndef linux @@ -94,7 +89,7 @@ #endif --- a/squashfs-tools/unsquashfs.c +++ b/squashfs-tools/unsquashfs.c -@@ -112,6 +112,7 @@ void update_progress_bar(); +@@ -117,6 +117,7 @@ void update_progress_bar(); void sigwinch_handler() { @@ -102,7 +97,7 @@ struct winsize winsize; if(ioctl(1, TIOCGWINSZ, &winsize) == -1) { -@@ -121,6 +122,9 @@ void sigwinch_handler() +@@ -126,6 +127,9 @@ void sigwinch_handler() columns = 80; } else columns = winsize.ws_col; @@ -112,7 +107,7 @@ } -@@ -1787,7 +1791,9 @@ void initialise_threads(int fragment_buf +@@ -1807,7 +1811,9 @@ void initialise_threads(int fragment_buf if(sigprocmask(SIG_BLOCK, &sigmask, &old_mask) == -1) EXIT_UNSQUASH("Failed to set signal mask in intialise_threads" "\n"); @@ -123,17 +118,17 @@ if(processors == -1) { #ifndef linux int mib[2]; -@@ -1809,6 +1815,7 @@ void initialise_threads(int fragment_buf - processors = get_nprocs(); +@@ -1829,6 +1835,7 @@ void initialise_threads(int fragment_buf + processors = sysconf(_SC_NPROCESSORS_ONLN); #endif } +#endif /* __CYGWIN__ */ - if((thread = malloc((3 + processors) * sizeof(pthread_t))) == NULL) - EXIT_UNSQUASH("Out of memory allocating thread descriptors\n"); + thread = malloc((3 + processors) * sizeof(pthread_t)); + if(thread == NULL) --- a/squashfs-tools/unsquashfs.h +++ b/squashfs-tools/unsquashfs.h -@@ -45,10 +45,12 @@ +@@ -46,15 +46,22 @@ #include <sys/time.h> #ifndef linux @@ -142,7 +137,17 @@ #define __BIG_ENDIAN BIG_ENDIAN #define __LITTLE_ENDIAN LITTLE_ENDIAN #include <sys/sysctl.h> -+#endif /* __CYGWIN__ */ ++#endif #else #include <endian.h> #include <sys/sysinfo.h> + #endif + ++#ifdef __CYGWIN__ ++#include <sys/termios.h> ++#define FNM_EXTMATCH (1 << 5) ++#endif ++ + #ifndef FNM_EXTMATCH + #define FNM_EXTMATCH 0 + #endif diff --git a/tools/squashfs4/patches/130-dynamic_lzma_params.patch b/tools/squashfs4/patches/130-dynamic_lzma_params.patch deleted file mode 100644 index 65fc3f625..000000000 --- a/tools/squashfs4/patches/130-dynamic_lzma_params.patch +++ /dev/null @@ -1,91 +0,0 @@ ---- a/squashfs-tools/lzma_wrapper.c -+++ b/squashfs-tools/lzma_wrapper.c -@@ -20,6 +20,8 @@ - */ - - #include <LzmaLib.h> -+#include <stdio.h> -+#include "compressor.h" - - #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8) - -@@ -30,9 +32,18 @@ - size_t props_size = LZMA_PROPS_SIZE, - outlen = block_size - LZMA_HEADER_SIZE; - int res; -+ int lc; -+ int lp; -+ int pb; -+ -+ if (!comp_args || sscanf(comp_args, "%d:%d:%d", &lc, &lp, &pb) != 3) { -+ lc = 0; -+ lp = 2; -+ pb = 2; -+ } - - res = LzmaCompress(d + LZMA_HEADER_SIZE, &outlen, s, size, d, -- &props_size, 5, block_size, 3, 0, 2, 32, 1); -+ &props_size, 5, block_size, lc, lp, pb, 32, 1); - - if(res == SZ_ERROR_OUTPUT_EOF) { - /* ---- a/squashfs-tools/compressor.c -+++ b/squashfs-tools/compressor.c -@@ -25,6 +25,7 @@ - #include "compressor.h" - #include "squashfs_fs.h" - -+char *comp_args = NULL; - extern int gzip_compress(void **, char *, char *, int, int, int *); - extern int gzip_uncompress(char *, char *, int, int, int *); - extern int lzma_compress(void **, char *, char *, int, int, int *); ---- a/squashfs-tools/compressor.h -+++ b/squashfs-tools/compressor.h -@@ -31,3 +31,4 @@ - extern struct compressor *lookup_compressor(char *); - extern struct compressor *lookup_compressor_id(int); - extern void display_compressors(char *, char *); -+extern char *comp_args; ---- a/squashfs-tools/mksquashfs.c -+++ b/squashfs-tools/mksquashfs.c -@@ -4355,6 +4355,12 @@ - exit(1); - } - comp_name = argv[i]; -+ } else if(strcmp(argv[i], "-comp_args") == 0) { -+ if(++i == argc) { -+ ERROR("%s: -comp_args missing compression arguments\n", argv[0]); -+ exit(1); -+ } -+ comp_args = argv[i]; - } else if(strcmp(argv[i], "-pf") == 0) { - if(++i == argc) { - ERROR("%s: -pf missing filename\n", argv[0]); -@@ -4574,6 +4580,7 @@ - "[-e list of exclude\ndirs/files]\n", argv[0]); - ERROR("\nFilesystem build options:\n"); - ERROR("-comp <comp>\t\tselect <comp> compression\n"); -+ ERROR("-comp_args <comp>\t\tselect compression arguments\n"); - ERROR("\t\t\tCompressors available:\n"); - display_compressors("\t\t\t", COMP_DEFAULT); - ERROR("-b <block_size>\t\tset data block to " -@@ -4736,7 +4743,8 @@ - else if(strcmp(argv[i], "-root-becomes") == 0 || - strcmp(argv[i], "-sort") == 0 || - strcmp(argv[i], "-pf") == 0 || -- strcmp(argv[i], "-comp") == 0) -+ strcmp(argv[i], "-comp") == 0 || -+ strcmp(argv[i], "-comp_args") == 0) - i++; - - if(i != argc) { -@@ -4761,7 +4769,8 @@ - else if(strcmp(argv[i], "-root-becomes") == 0 || - strcmp(argv[i], "-ef") == 0 || - strcmp(argv[i], "-pf") == 0 || -- strcmp(argv[i], "-comp") == 0) -+ strcmp(argv[i], "-comp") == 0 || -+ strcmp(argv[i], "-comp_args") == 0) - i++; - - #ifdef SQUASHFS_TRACE diff --git a/tools/squashfs4/patches/140-mode_check.patch b/tools/squashfs4/patches/140-mode_check.patch deleted file mode 100644 index 30ab4e137..000000000 --- a/tools/squashfs4/patches/140-mode_check.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/squashfs-tools/pseudo.c -+++ b/squashfs-tools/pseudo.c -@@ -374,7 +374,7 @@ - } - - -- if(mode > 0777) { -+ if(mode > 07777) { - ERROR("Mode %o out of range\n", mode); - goto error; - } diff --git a/tools/squashfs4/patches/150-freebsd_fixes.patch b/tools/squashfs4/patches/150-freebsd_fixes.patch index 344d9ec68..44d40a7d1 100644 --- a/tools/squashfs4/patches/150-freebsd_fixes.patch +++ b/tools/squashfs4/patches/150-freebsd_fixes.patch @@ -1,6 +1,6 @@ --- a/squashfs-tools/pseudo.c +++ b/squashfs-tools/pseudo.c -@@ -31,6 +31,7 @@ +@@ -32,6 +32,7 @@ #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> diff --git a/tools/squashfs4/patches/160-expose_lzma_xz_options.patch b/tools/squashfs4/patches/160-expose_lzma_xz_options.patch new file mode 100644 index 000000000..b5fb80dff --- /dev/null +++ b/tools/squashfs4/patches/160-expose_lzma_xz_options.patch @@ -0,0 +1,926 @@ +--- /dev/null ++++ b/squashfs-tools/lzma_xz_options.h +@@ -0,0 +1,112 @@ ++#ifndef LZMA_XZ_OPTIONS_H ++#define LZMA_XZ_OPTIONS_H ++/* ++ * Copyright (c) 2011 ++ * Jonas Gorski <jonas.gorski@gmail.com> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2, ++ * or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * lzma_options.h ++ */ ++ ++#include <stdint.h> ++ ++#ifndef linux ++#define __BYTE_ORDER BYTE_ORDER ++#define __BIG_ENDIAN BIG_ENDIAN ++#define __LITTLE_ENDIAN LITTLE_ENDIAN ++#else ++#include <endian.h> ++#endif ++ ++ ++ ++struct lzma_opts { ++ uint32_t flags; ++#define LZMA_OPT_FLT_MASK 0xffff ++#define LZMA_OPT_PRE_OFF 16 ++#define LZMA_OPT_PRE_MASK (0xf << LZMA_OPT_PRE_OFF) ++#define LZMA_OPT_EXTREME 20 ++ uint16_t bit_opts; ++#define LZMA_OPT_LC_OFF 0 ++#define LZMA_OPT_LC_MASK (0x7 << LZMA_OPT_LC_OFF) ++#define LZMA_OPT_LP_OFF 3 ++#define LZMA_OPT_LP_MASK (0x7 << LZMA_OPT_LP_OFF) ++#define LZMA_OPT_PB_OFF 6 ++#define LZMA_OPT_PB_MASK (0x7 << LZMA_OPT_PB_OFF) ++ uint16_t fb; ++ uint32_t dict_size; ++}; ++ ++#if __BYTE_ORDER == __BIG_ENDIAN ++extern unsigned int inswap_le32(unsigned int); ++ ++#define SQUASHFS_INSWAP_LZMA_COMP_OPTS(s) { \ ++ (s)->flags = inswap_le32((s)->flags); \ ++ (s)->bit_opts = inswap_le16((s)->bit_opts); \ ++ (s)->fb = inswap_le16((s)->fb); \ ++ (s)->dict_size = inswap_le32((s)->dict_size); \ ++} ++#else ++#define SQUASHFS_INSWAP_LZMA_COMP_OPTS(s) ++#endif ++ ++#define MEMLIMIT (32 * 1024 * 1024) ++ ++#define LZMA_OPT_LC_MIN 0 ++#define LZMA_OPT_LC_MAX 4 ++#define LZMA_OPT_LC_DEFAULT 3 ++ ++#define LZMA_OPT_LP_MIN 0 ++#define LZMA_OPT_LP_MAX 4 ++#define LZMA_OPT_LP_DEFAULT 0 ++ ++#define LZMA_OPT_PB_MIN 0 ++#define LZMA_OPT_PB_MAX 4 ++#define LZMA_OPT_PB_DEFAULT 2 ++ ++#define LZMA_OPT_FB_MIN 5 ++#define LZMA_OPT_FB_MAX 273 ++#define LZMA_OPT_FB_DEFAULT 64 ++ ++enum { ++ LZMA_OPT_LZMA = 1, ++ LZMA_OPT_XZ ++}; ++ ++struct lzma_xz_options { ++ int preset; ++ int extreme; ++ int lc; ++ int lp; ++ int pb; ++ int fb; ++ int dict_size; ++ int flags; ++}; ++ ++struct lzma_xz_options *lzma_xz_get_options(void); ++ ++int lzma_xz_options(char *argv[], int argc, int lzmaver); ++ ++int lzma_xz_options_post(int block_size, int lzmaver); ++ ++void *lzma_xz_dump_options(int block_size, int *size, int flags); ++ ++int lzma_xz_extract_options(int block_size, void *buffer, int size, int lzmaver); ++ ++void lzma_xz_usage(int lzmaver); ++ ++#endif +--- /dev/null ++++ b/squashfs-tools/lzma_xz_options.c +@@ -0,0 +1,365 @@ ++/* ++ * Copyright (c) 2011 ++ * Jonas Gorski <jonas.gorski@gmail.com> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2, ++ * or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * lzma_options.c ++ * ++ * Common options for LZMA1 and 2 compressors. Based on xz_wrapper.c ++ */ ++ ++#include <stdio.h> ++#include <string.h> ++#include <stdlib.h> ++ ++#include <lzma.h> ++ ++#include "lzma_xz_options.h" ++ ++static const char const *lzmaver_str[] = { "", "lzma", "xz" }; ++ ++static struct lzma_xz_options options = { ++ .flags = 0, ++ .preset = 6, ++ .extreme = 0, ++ .lc = LZMA_OPT_LC_DEFAULT, ++ .lp = LZMA_OPT_LP_DEFAULT, ++ .pb = LZMA_OPT_PB_DEFAULT, ++ .fb = LZMA_OPT_FB_DEFAULT, ++ .dict_size = 0, ++}; ++ ++static float lzma_dict_percent = 0; ++ ++struct lzma_xz_options *lzma_xz_get_options(void) ++{ ++ return &options; ++} ++ ++ ++int lzma_xz_options(char *argv[], int argc, int lzmaver) ++{ ++ const char *comp_name = lzmaver_str[lzmaver]; ++ ++ if(strcmp(argv[0], "-Xpreset") == 0) { ++ int preset; ++ ++ if(argc < 2) { ++ fprintf(stderr, "%s: -Xpreset missing preset\n", comp_name); ++ goto failed; ++ } ++ ++ preset = atoi(argv[1]); ++ ++ if (preset < 0 || preset > 9) { ++ fprintf(stderr, "%s: -Xpreset invalid value\n", comp_name); ++ goto failed; ++ } ++ options.preset = preset; ++ return 1; ++ } else if(strcmp(argv[0], "-Xe") == 0) { ++ options.extreme = 1; ++ return 0; ++ } else if(strcmp(argv[0], "-Xlc") == 0) { ++ int lc; ++ ++ if(argc < 2) { ++ fprintf(stderr, "%s: -Xlc missing lc\n", comp_name); ++ goto failed; ++ } ++ ++ lc = atoi(argv[1]); ++ ++ if (lc < LZMA_OPT_LC_MIN || lc > LZMA_OPT_LC_MAX) { ++ fprintf(stderr, "%s: -Xlc invalid value\n", comp_name); ++ goto failed; ++ } ++ options.lc = lc; ++ return 1; ++ } else if(strcmp(argv[0], "-Xlp") == 0) { ++ int lp; ++ ++ if(argc < 2) { ++ fprintf(stderr, "%s: -Xlp missing lp\n", comp_name); ++ goto failed; ++ } ++ ++ lp = atoi(argv[1]); ++ ++ if (lp < LZMA_OPT_LP_MIN || lp > LZMA_OPT_LP_MAX) { ++ fprintf(stderr, "%s: -Xlp invalid value\n", comp_name); ++ goto failed; ++ } ++ options.lp = lp; ++ return 1; ++ } else if(strcmp(argv[0], "-Xpb") == 0) { ++ int pb; ++ ++ if(argc < 2) { ++ fprintf(stderr, "%s: -Xpb missing pb\n", comp_name); ++ goto failed; ++ } ++ ++ pb = atoi(argv[1]); ++ ++ if (pb < LZMA_OPT_PB_MIN || pb > LZMA_OPT_PB_MAX) { ++ fprintf(stderr, "%s: -Xbp invalid value\n", comp_name); ++ goto failed; ++ } ++ options.pb = pb; ++ return 1; ++ } else if(strcmp(argv[0], "-Xfb") == 0) { ++ int fb; ++ ++ if(argc < 2) { ++ fprintf(stderr, "%s: -Xfb missing fb\n", comp_name); ++ goto failed; ++ } ++ ++ fb = atoi(argv[1]); ++ ++ if (fb < LZMA_OPT_FB_MIN || fb > LZMA_OPT_FB_MAX) { ++ fprintf(stderr, "%s: -Xfb invalid value\n", comp_name); ++ goto failed; ++ } ++ options.fb = fb; ++ return 1; ++ } else if(strcmp(argv[0], "-Xdict-size") == 0) { ++ char *b; ++ float size; ++ ++ if(argc < 2) { ++ fprintf(stderr, "%s: -Xdict-size missing dict-size\n", comp_name); ++ goto failed; ++ } ++ ++ size = strtof(argv[1], &b); ++ if(*b == '%') { ++ if(size <= 0 || size > 100) { ++ fprintf(stderr, "%s: -Xdict-size percentage " ++ "should be 0 < dict-size <= 100\n", comp_name); ++ goto failed; ++ } ++ ++ lzma_dict_percent = size; ++ options.dict_size = 0; ++ } else { ++ if((float) ((int) size) != size) { ++ fprintf(stderr, "%s: -Xdict-size can't be " ++ "fractional unless a percentage of the" ++ " block size\n", comp_name); ++ goto failed; ++ } ++ ++ lzma_dict_percent = 0; ++ options.dict_size = (int) size; ++ ++ if(*b == 'k' || *b == 'K') ++ options.dict_size *= 1024; ++ else if(*b == 'm' || *b == 'M') ++ options.dict_size *= 1024 * 1024; ++ else if(*b != '\0') { ++ fprintf(stderr, "%s: -Xdict-size invalid " ++ "dict-size\n", comp_name); ++ goto failed; ++ } ++ } ++ ++ return 1; ++ } ++ ++ return -1; ++ ++failed: ++ return -2; ++ ++} ++ ++int lzma_xz_options_post(int block_size, int lzmaver) ++{ ++ const char *comp_name = lzmaver_str[lzmaver]; ++ /* ++ * if -Xdict-size has been specified use this to compute the datablock ++ * dictionary size ++ */ ++ if(options.dict_size || lzma_dict_percent) { ++ int dict_size_min = (lzmaver == 1 ? 4096 : 8192); ++ int n; ++ ++ if(options.dict_size) { ++ if(options.dict_size > block_size) { ++ fprintf(stderr, "%s: -Xdict-size is larger than" ++ " block_size\n", comp_name); ++ goto failed; ++ } ++ } else ++ options.dict_size = block_size * lzma_dict_percent / 100; ++ ++ if(options.dict_size < dict_size_min) { ++ fprintf(stderr, "%s: -Xdict-size should be %i bytes " ++ "or larger\n", comp_name, dict_size_min); ++ goto failed; ++ } ++ ++ /* ++ * dictionary_size must be storable in xz header as either ++ * 2^n or as 2^n+2^(n+1) ++ */ ++ n = ffs(options.dict_size) - 1; ++ if(options.dict_size != (1 << n) && ++ options.dict_size != ((1 << n) + (1 << (n + 1)))) { ++ fprintf(stderr, "%s: -Xdict-size is an unsupported " ++ "value, dict-size must be storable in %s " ++ "header\n", comp_name, comp_name); ++ fprintf(stderr, "as either 2^n or as 2^n+2^(n+1). " ++ "Example dict-sizes are 75%%, 50%%, 37.5%%, " ++ "25%%,\n"); ++ fprintf(stderr, "or 32K, 16K, 8K etc.\n"); ++ goto failed; ++ } ++ ++ } else ++ /* No -Xdict-size specified, use defaults */ ++ options.dict_size = block_size; ++ ++ return 0; ++ ++failed: ++ return -1; ++} ++ ++static struct lzma_opts lzma_comp_opts; ++ ++void *lzma_xz_dump_options(int block_size, int *size, int flags) ++{ ++ /* No need to store default options */ ++ if (options.preset == 6 && ++ options.extreme == 0 && ++ options.lc == LZMA_OPT_LC_DEFAULT && ++ options.lp == LZMA_OPT_LC_DEFAULT && ++ options.pb == LZMA_OPT_PB_DEFAULT && ++ options.fb == 0 && ++ options.dict_size == block_size && ++ flags == 0) ++ return NULL; ++ ++ *size = sizeof(struct lzma_opts); ++ ++ lzma_comp_opts.flags |= flags; ++ ++ if (options.extreme) ++ lzma_comp_opts.flags |= LZMA_OPT_EXTREME; ++ ++ lzma_comp_opts.flags |= ((options.preset << LZMA_OPT_PRE_OFF) & LZMA_OPT_PRE_MASK); ++ ++ lzma_comp_opts.bit_opts = ++ ((options.lc << LZMA_OPT_LC_OFF) & LZMA_OPT_LC_MASK) | ++ ((options.lp << LZMA_OPT_LP_OFF) & LZMA_OPT_LP_MASK) | ++ ((options.pb << LZMA_OPT_PB_OFF) & LZMA_OPT_PB_MASK); ++ lzma_comp_opts.fb = options.fb; ++ lzma_comp_opts.dict_size = options.dict_size; ++ ++ SQUASHFS_INSWAP_LZMA_COMP_OPTS(&lzma_comp_opts); ++ ++ return &lzma_comp_opts; ++} ++ ++int lzma_xz_extract_options(int block_size, void *buffer, int size, int lzmaver) ++{ ++ if (size == 0) { ++ /* default options */ ++ options.preset = 6; ++ options.extreme = 0; ++ options.lc = LZMA_OPT_LC_DEFAULT; ++ options.lp = LZMA_OPT_LC_DEFAULT; ++ options.pb = LZMA_OPT_PB_DEFAULT; ++ options.fb = LZMA_OPT_FB_DEFAULT; ++ options.dict_size = block_size; ++ options.flags = 0; ++ } else { ++ struct lzma_opts *comp_opts = buffer; ++ int n; ++ ++ if (size != sizeof(struct lzma_opts)) ++ goto failed; ++ ++ SQUASHFS_INSWAP_LZMA_COMP_OPTS(&comp_opts); ++ ++ options.flags = comp_opts->flags & LZMA_OPT_FLT_MASK; ++ options.preset = (comp_opts->flags & LZMA_OPT_PRE_MASK) >> LZMA_OPT_PRE_OFF; ++ options.extreme = !!(comp_opts->flags & LZMA_OPT_EXTREME); ++ ++ options.lc = (comp_opts->bit_opts & LZMA_OPT_LC_MASK) >> LZMA_OPT_LC_OFF; ++ options.lp = (comp_opts->bit_opts & LZMA_OPT_LP_MASK) >> LZMA_OPT_LP_OFF; ++ options.pb = (comp_opts->bit_opts & LZMA_OPT_PB_MASK) >> LZMA_OPT_PB_OFF; ++ options.fb = comp_opts->fb; ++ options.dict_size = comp_opts->dict_size; ++ ++ /* check that the LZMA bit options are in range */ ++ if (options.lc < LZMA_OPT_LC_MIN || options.lc > LZMA_OPT_LC_MAX || ++ options.lp < LZMA_OPT_LP_MIN || options.lp > LZMA_OPT_LP_MAX || ++ options.pb < LZMA_OPT_PB_MIN || options.pb > LZMA_OPT_PB_MAX || ++ options.fb < LZMA_OPT_FB_MIN || options.fb > LZMA_OPT_FB_MAX) ++ goto failed; ++ ++ /* ++ * check that the dictionary size seems correct - the dictionary ++ * size should 2^n or 2^n+2^(n+1) ++ */ ++ n = ffs(options.dict_size) - 1; ++ if(options.dict_size != (1 << n) && ++ options.dict_size != ((1 << n) + (1 << (n + 1)))) ++ goto failed; ++ ++ } ++ ++ return 0; ++ ++failed: ++ fprintf(stderr, "%s: error reading stored compressor options from " ++ "filesystem!\n", lzmaver_str[lzmaver]); ++ return -1; ++} ++ ++void lzma_xz_usage(int lzmaver) ++{ ++ fprintf(stderr, "\t -Xpreset <preset>\n"); ++ fprintf(stderr, "\t\tcompression preset (0-9, default 6)\n"); ++ fprintf(stderr, "\t -Xe\n"); ++ fprintf(stderr, "\t\tTry to improve compression ratio by using more "); ++ fprintf(stderr, "CPU time.\n"); ++ fprintf(stderr, "\t -Xlc <lc>\n"); ++ fprintf(stderr, "\t\tNumber of literal context bits (0-4, default 3)\n"); ++ fprintf(stderr, "\t -Xlp <lp>\n"); ++ fprintf(stderr, "\t\tNumber of literal position bits (0-4, default 0)\n"); ++ fprintf(stderr, "\t -Xpb <pb>\n"); ++ fprintf(stderr, "\t\tNumber of position bits (0-4, default 2)\n"); ++ fprintf(stderr, "\t -Xnice <nice>\n"); ++ fprintf(stderr, "\t\tNice length of a match (5-273, default 64)\n"); ++ fprintf(stderr, "\t -Xdict-size <dict-size>\n"); ++ fprintf(stderr, "\t\tUse <dict-size> as the %s dictionary size. The", ++ lzmaver == LZMA_OPT_LZMA ? "LZMA" : "XZ"); ++ fprintf(stderr, " dictionary size\n\t\tcan be specified as a"); ++ fprintf(stderr, " percentage of the block size, or as an\n\t\t"); ++ fprintf(stderr, "absolute value. The dictionary size must be less"); ++ fprintf(stderr, " than or equal\n\t\tto the block size and %d bytes", ++ lzmaver == LZMA_OPT_LZMA ? 4096 : 8192); ++ fprintf(stderr, " or larger. It must also be\n\t\tstorable in the lzma"); ++ fprintf(stderr, " header as either 2^n or as 2^n+2^(n+1).\n\t\t"); ++ fprintf(stderr, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or"); ++ fprintf(stderr, " 32K, 16K, 8K\n\t\tetc.\n"); ++ ++} +--- a/squashfs-tools/lzma_xz_wrapper.c ++++ b/squashfs-tools/lzma_xz_wrapper.c +@@ -27,6 +27,7 @@ + + #include "squashfs_fs.h" + #include "compressor.h" ++#include "lzma_xz_options.h" + + #define LZMA_PROPS_SIZE 5 + #define LZMA_UNCOMP_SIZE 8 +@@ -38,13 +39,27 @@ + static int lzma_compress(void *dummy, void *dest, void *src, int size, + int block_size, int *error) + { ++ uint32_t preset; + unsigned char *d = (unsigned char *) dest; ++ struct lzma_xz_options *opts = lzma_xz_get_options(); ++ + lzma_options_lzma opt; + lzma_stream strm = LZMA_STREAM_INIT; + int res; + +- lzma_lzma_preset(&opt, LZMA_OPTIONS); +- opt.dict_size = block_size; ++ preset = opts->preset; ++ ++ if (opts->extreme) ++ preset |= LZMA_PRESET_EXTREME; ++ ++ lzma_lzma_preset(&opt, opts->preset); ++ opt.lc = opts->lc; ++ opt.lp = opts->lp; ++ opt.pb = opts->pb; ++ if (opts->fb) ++ opt.nice_len = opts->fb; ++ ++ opt.dict_size = opts->dict_size; + + res = lzma_alone_encoder(&strm, &opt); + if(res != LZMA_OK) { +@@ -143,13 +158,45 @@ failed: + return -1; + } + ++static int lzma_options(char *argv[], int argc) ++{ ++ return lzma_xz_options(argv, argc, LZMA_OPT_LZMA); ++} ++ ++ ++static int lzma_options_post(int block_size) ++{ ++ return lzma_xz_options_post(block_size, LZMA_OPT_LZMA); ++} ++ ++ ++static void *lzma_dump_options(int block_size, int *size) ++{ ++ return lzma_xz_dump_options(block_size, size, 0); ++} ++ ++ ++static int lzma_extract_options(int block_size, void *buffer, int size) ++{ ++ return lzma_xz_extract_options(block_size, buffer, size, LZMA_OPT_LZMA); ++} ++ ++ ++void lzma_usage() ++{ ++ lzma_xz_usage(LZMA_OPT_LZMA); ++} ++ + + struct compressor lzma_comp_ops = { + .init = NULL, + .compress = lzma_compress, + .uncompress = lzma_uncompress, +- .options = NULL, +- .usage = NULL, ++ .options = lzma_options, ++ .options_post = lzma_options_post, ++ .dump_options = lzma_dump_options, ++ .extract_options = lzma_extract_options, ++ .usage = lzma_usage, + .id = LZMA_COMPRESSION, + .name = "lzma", + .supported = 1 +--- a/squashfs-tools/xz_wrapper.h ++++ b/squashfs-tools/xz_wrapper.h +@@ -24,25 +24,6 @@ + * + */ + +-#ifndef linux +-#define __BYTE_ORDER BYTE_ORDER +-#define __BIG_ENDIAN BIG_ENDIAN +-#define __LITTLE_ENDIAN LITTLE_ENDIAN +-#else +-#include <endian.h> +-#endif +- +-#if __BYTE_ORDER == __BIG_ENDIAN +-extern unsigned int inswap_le32(unsigned int); +- +-#define SQUASHFS_INSWAP_COMP_OPTS(s) { \ +- (s)->dictionary_size = inswap_le32((s)->dictionary_size); \ +- (s)->flags = inswap_le32((s)->flags); \ +-} +-#else +-#define SQUASHFS_INSWAP_COMP_OPTS(s) +-#endif +- + #define MEMLIMIT (32 * 1024 * 1024) + + struct bcj { +--- a/squashfs-tools/xz_wrapper.c ++++ b/squashfs-tools/xz_wrapper.c +@@ -30,6 +30,7 @@ + #include "squashfs_fs.h" + #include "xz_wrapper.h" + #include "compressor.h" ++#include "lzma_xz_options.h" + + static struct bcj bcj[] = { + { "x86", LZMA_FILTER_X86, 0 }, +@@ -41,22 +42,18 @@ static struct bcj bcj[] = { + { NULL, LZMA_VLI_UNKNOWN, 0 } + }; + +-static struct comp_opts comp_opts; +- + static int filter_count = 1; +-static int dictionary_size = 0; +-static float dictionary_percent = 0; + + + static int xz_options(char *argv[], int argc) + { +- int i; +- char *name; +- + if(strcmp(argv[0], "-Xbcj") == 0) { ++ int i; ++ char *name; ++ + if(argc < 2) { + fprintf(stderr, "xz: -Xbcj missing filter\n"); +- goto failed; ++ return -2; + } + + name = argv[1]; +@@ -76,190 +73,50 @@ static int xz_options(char *argv[], int + } + if(bcj[i].name == NULL) { + fprintf(stderr, "xz: -Xbcj unrecognised " +- "filter\n"); +- goto failed; +- } +- } +- +- return 1; +- } else if(strcmp(argv[0], "-Xdict-size") == 0) { +- char *b; +- float size; +- +- if(argc < 2) { +- fprintf(stderr, "xz: -Xdict-size missing dict-size\n"); +- goto failed; +- } +- +- size = strtof(argv[1], &b); +- if(*b == '%') { +- if(size <= 0 || size > 100) { +- fprintf(stderr, "xz: -Xdict-size percentage " +- "should be 0 < dict-size <= 100\n"); +- goto failed; +- } +- +- dictionary_percent = size; +- dictionary_size = 0; +- } else { +- if((float) ((int) size) != size) { +- fprintf(stderr, "xz: -Xdict-size can't be " +- "fractional unless a percentage of the" +- " block size\n"); +- goto failed; +- } +- +- dictionary_percent = 0; +- dictionary_size = (int) size; +- +- if(*b == 'k' || *b == 'K') +- dictionary_size *= 1024; +- else if(*b == 'm' || *b == 'M') +- dictionary_size *= 1024 * 1024; +- else if(*b != '\0') { +- fprintf(stderr, "xz: -Xdict-size invalid " +- "dict-size\n"); +- goto failed; ++ "filter\n"); ++ return -2; + } + } +- + return 1; ++ } else { ++ return lzma_xz_options(argv, argc, LZMA_OPT_XZ); + } +- +- return -1; +- +-failed: +- return -2; + } + + + static int xz_options_post(int block_size) + { +- /* +- * if -Xdict-size has been specified use this to compute the datablock +- * dictionary size +- */ +- if(dictionary_size || dictionary_percent) { +- int n; +- +- if(dictionary_size) { +- if(dictionary_size > block_size) { +- fprintf(stderr, "xz: -Xdict-size is larger than" +- " block_size\n"); +- goto failed; +- } +- } else +- dictionary_size = block_size * dictionary_percent / 100; +- +- if(dictionary_size < 8192) { +- fprintf(stderr, "xz: -Xdict-size should be 8192 bytes " +- "or larger\n"); +- goto failed; +- } +- +- /* +- * dictionary_size must be storable in xz header as either +- * 2^n or as 2^n+2^(n+1) +- */ +- n = ffs(dictionary_size) - 1; +- if(dictionary_size != (1 << n) && +- dictionary_size != ((1 << n) + (1 << (n + 1)))) { +- fprintf(stderr, "xz: -Xdict-size is an unsupported " +- "value, dict-size must be storable in xz " +- "header\n"); +- fprintf(stderr, "as either 2^n or as 2^n+2^(n+1). " +- "Example dict-sizes are 75%%, 50%%, 37.5%%, " +- "25%%,\n"); +- fprintf(stderr, "or 32K, 16K, 8K etc.\n"); +- goto failed; +- } +- +- } else +- /* No -Xdict-size specified, use defaults */ +- dictionary_size = block_size; +- +- return 0; +- +-failed: +- return -1; ++ return lzma_xz_options_post(block_size, LZMA_OPT_XZ); + } + + + static void *xz_dump_options(int block_size, int *size) + { +- int flags = 0, i; +- +- /* +- * don't store compressor specific options in file system if the +- * default options are being used - no compressor options in the +- * file system means the default options are always assumed +- * +- * Defaults are: +- * metadata dictionary size: SQUASHFS_METADATA_SIZE +- * datablock dictionary size: block_size +- * 1 filter +- */ +- if(dictionary_size == block_size && filter_count == 1) +- return NULL; ++ int i, flags = 0; + + for(i = 0; bcj[i].name; i++) + flags |= bcj[i].selected << i; + +- comp_opts.dictionary_size = dictionary_size; +- comp_opts.flags = flags; +- +- SQUASHFS_INSWAP_COMP_OPTS(&comp_opts); +- +- *size = sizeof(comp_opts); +- return &comp_opts; ++ return lzma_xz_dump_options(block_size, size, flags); + } + + + static int xz_extract_options(int block_size, void *buffer, int size) + { +- struct comp_opts *comp_opts = buffer; +- int flags, i, n; +- +- if(size == 0) { +- /* set defaults */ +- dictionary_size = block_size; +- flags = 0; +- } else { +- /* check passed comp opts struct is of the correct length */ +- if(size != sizeof(struct comp_opts)) +- goto failed; +- +- SQUASHFS_INSWAP_COMP_OPTS(comp_opts); +- +- dictionary_size = comp_opts->dictionary_size; +- flags = comp_opts->flags; +- +- /* +- * check that the dictionary size seems correct - the dictionary +- * size should 2^n or 2^n+2^(n+1) +- */ +- n = ffs(dictionary_size) - 1; +- if(dictionary_size != (1 << n) && +- dictionary_size != ((1 << n) + (1 << (n + 1)))) +- goto failed; +- } ++ int ret = lzma_xz_extract_options(block_size, buffer, size, LZMA_OPT_XZ); + +- filter_count = 1; +- for(i = 0; bcj[i].name; i++) { +- if((flags >> i) & 1) { +- bcj[i].selected = 1; +- filter_count ++; +- } else +- bcj[i].selected = 0; ++ if (!ret) { ++ int i; ++ struct lzma_xz_options *opts = lzma_xz_get_options(); ++ for(i = 0; bcj[i].name; i++) { ++ if((opts->flags >> i) & 1) { ++ bcj[i].selected = 1; ++ filter_count ++; ++ } else ++ bcj[i].selected = 0; ++ } + } +- +- return 0; +- +-failed: +- fprintf(stderr, "xz: error reading stored compressor options from " +- "filesystem!\n"); +- +- return -1; ++ return ret; + } + + +@@ -268,6 +125,7 @@ static int xz_init(void **strm, int bloc + int i, j, filters = datablock ? filter_count : 1; + struct filter *filter = malloc(filters * sizeof(struct filter)); + struct xz_stream *stream; ++ struct lzma_xz_options *opts = lzma_xz_get_options(); + + if(filter == NULL) + goto failed; +@@ -281,7 +139,7 @@ static int xz_init(void **strm, int bloc + + memset(filter, 0, filters * sizeof(struct filter)); + +- stream->dictionary_size = datablock ? dictionary_size : ++ stream->dictionary_size = datablock ? opts->dict_size : + SQUASHFS_METADATA_SIZE; + + filter[0].filter[0].id = LZMA_FILTER_LZMA2; +@@ -323,14 +181,25 @@ static int xz_compress(void *strm, void + lzma_ret res = 0; + struct xz_stream *stream = strm; + struct filter *selected = NULL; ++ struct lzma_xz_options *opts = lzma_xz_get_options(); + + stream->filter[0].buffer = dest; + + for(i = 0; i < stream->filters; i++) { ++ uint32_t preset = opts->preset; + struct filter *filter = &stream->filter[i]; + +- if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT)) +- goto failed; ++ if (opts->extreme) ++ preset |= LZMA_PRESET_EXTREME; ++ ++ if(lzma_lzma_preset(&stream->opt, preset)) ++ goto failed; ++ ++ stream->opt.lc = opts->lc; ++ stream->opt.lp = opts->lp; ++ stream->opt.pb = opts->pb; ++ if (opts->fb) ++ stream->opt.nice_len = opts->fb; + + stream->opt.dict_size = stream->dictionary_size; + +@@ -384,22 +253,13 @@ static int xz_uncompress(void *dest, voi + + void xz_usage() + { ++ lzma_xz_usage(LZMA_OPT_XZ); + fprintf(stderr, "\t -Xbcj filter1,filter2,...,filterN\n"); + fprintf(stderr, "\t\tCompress using filter1,filter2,...,filterN in"); + fprintf(stderr, " turn\n\t\t(in addition to no filter), and choose"); + fprintf(stderr, " the best compression.\n"); + fprintf(stderr, "\t\tAvailable filters: x86, arm, armthumb,"); + fprintf(stderr, " powerpc, sparc, ia64\n"); +- fprintf(stderr, "\t -Xdict-size <dict-size>\n"); +- fprintf(stderr, "\t\tUse <dict-size> as the XZ dictionary size. The"); +- fprintf(stderr, " dictionary size\n\t\tcan be specified as a"); +- fprintf(stderr, " percentage of the block size, or as an\n\t\t"); +- fprintf(stderr, "absolute value. The dictionary size must be less"); +- fprintf(stderr, " than or equal\n\t\tto the block size and 8192 bytes"); +- fprintf(stderr, " or larger. It must also be\n\t\tstorable in the xz"); +- fprintf(stderr, " header as either 2^n or as 2^n+2^(n+1).\n\t\t"); +- fprintf(stderr, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or"); +- fprintf(stderr, " 32K, 16K, 8K\n\t\tetc.\n"); + } + + +--- a/squashfs-tools/Makefile ++++ b/squashfs-tools/Makefile +@@ -140,6 +140,8 @@ COMPRESSORS += xz + endif + + ifneq ($(LZMA_XZ_SUPPORT)$(XZ_SUPPORT),) ++MKSQUASHFS_OBJS += lzma_xz_options.o ++UNSQUASHFS_OBJS += lzma_xz_options.o + ifneq ($(LZMA_LIB),) + MKSQUASHFS_OBJS += $(LZMA_LIB) + UNSQUASHFS_OBJS += $(LZMA_LIB) |