From: Christian Marangi Date: Mon, 6 Feb 2023 22:22:43 +0000 (+0100) Subject: tools/squashfs4: add new tool for squashfs4 images X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=30f2d516ba7be08f06f7ca8767472c3ea5678706;p=openwrt%2Fstaging%2Fdedeckeh.git tools/squashfs4: add new tool for squashfs4 images squashfs tool is finally reborn and correctly maintained. Introduce the new version as a replacement for squasfs4kit as it was a fork and also abandoned. Add additional patch to add the missing feature present in squashfskit4 but still missing on this new project. Backport each required patch that fix compilation error on macos. Signed-off-by: Christian Marangi --- diff --git a/tools/Makefile b/tools/Makefile index aa80ee4ba6..bdd9f0a257 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -59,7 +59,7 @@ tools-y += patch-image tools-y += patchelf tools-y += pkgconf tools-y += quilt -tools-y += squashfskit4 +tools-y += squashfs4 tools-y += sstrip tools-y += zip tools-y += zlib @@ -117,11 +117,11 @@ $(curdir)/pkgconf/compile := $(curdir)/meson/compile $(curdir)/quilt/compile := $(curdir)/autoconf/compile $(curdir)/findutils/compile $(curdir)/sdcc/compile := $(curdir)/bison/compile $(curdir)/squashfs3-lzma/compile := $(curdir)/lzma-old/compile -$(curdir)/squashfskit4/compile := $(curdir)/xz/compile $(curdir)/zlib/compile +$(curdir)/squashfs4/compile := $(curdir)/xz/compile $(curdir)/zlib/compile $(curdir)/zstd/compile := $(curdir)/meson/compile ifneq ($(HOST_OS),Linux) - $(curdir)/squashfskit4/compile += $(curdir)/coreutils/compile + $(curdir)/squashfs4/compile += $(curdir)/coreutils/compile tools-y += coreutils endif ifeq ($(HOST_OS),Darwin) diff --git a/tools/squashfs4/Makefile b/tools/squashfs4/Makefile new file mode 100644 index 0000000000..9d4f6babfc --- /dev/null +++ b/tools/squashfs4/Makefile @@ -0,0 +1,41 @@ +# +# Copyright (C) 2006-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=squashfs4 +PKG_CPE_ID:=cpe:/a:phillip_lougher:squashfs +PKG_VERSION:=4.5.1 +PKG_RELEASE=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/plougher/squashfs-tools +PKG_SOURCE_DATE:=2022-03-17 +PKG_SOURCE_VERSION:=afdd63fc386919b4aa40d573b0a6069414d14317 +PKG_MIRROR_HASH:=caedb66cf6dcbdcee0d1525923e203d003ef15f34a13a328686794666f16171f + +include $(INCLUDE_DIR)/host-build.mk + +define Host/Compile + +$(HOST_MAKE_VARS) \ + $(MAKE) -C $(HOST_BUILD_DIR)/squashfs-tools \ + XZ_SUPPORT=1 \ + LZMA_XZ_SUPPORT=1 \ + EXTRA_CFLAGS="-I$(STAGING_DIR_HOST)/include" \ + mksquashfs unsquashfs +endef + +define Host/Install + $(INSTALL_BIN) $(HOST_BUILD_DIR)/squashfs-tools/mksquashfs $(STAGING_DIR_HOST)/bin/mksquashfs4 + $(INSTALL_BIN) $(HOST_BUILD_DIR)/squashfs-tools/unsquashfs $(STAGING_DIR_HOST)/bin/unsquashfs4 +endef + +define Host/Clean + rm -f $(STAGING_DIR_HOST)/bin/mksquashfs4 + rm -f $(STAGING_DIR_HOST)/bin/unsquashfs4 +endef + +$(eval $(call HostBuild)) diff --git a/tools/squashfs4/patches/001-Unsquashfs-Add-and-make-some-header-includes-conditi.patch b/tools/squashfs4/patches/001-Unsquashfs-Add-and-make-some-header-includes-conditi.patch new file mode 100644 index 0000000000..2fdb509492 --- /dev/null +++ b/tools/squashfs4/patches/001-Unsquashfs-Add-and-make-some-header-includes-conditi.patch @@ -0,0 +1,39 @@ +From a9119c969af0a5aa961d56978d5dd4f3eb952667 Mon Sep 17 00:00:00 2001 +From: Phillip Lougher +Date: Mon, 15 Aug 2022 17:04:43 +0100 +Subject: [PATCH 1/1] Unsquashfs: Add and make some header includes conditional + +Fixes https://github.com/plougher/squashfs-tools/issues/122 + +Signed-off-by: Phillip Lougher +--- + squashfs-tools/reader.c | 1 + + squashfs-tools/unsquashfs.c | 5 +++++ + 2 files changed, 6 insertions(+) + +--- a/squashfs-tools/reader.c ++++ b/squashfs-tools/reader.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + #include "squashfs_fs.h" + #include "mksquashfs.h" + #include "caches-queues-lists.h" +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -32,8 +32,13 @@ + #include "stdarg.h" + #include "fnmatch_compat.h" + ++#ifdef __linux__ + #include + #include ++#elif defined __FreeBSD__ ++#include ++#endif ++ + #include + #include + #include diff --git a/tools/squashfs4/patches/002-Mksquashfs-Make-sysinfo-conditional.patch b/tools/squashfs4/patches/002-Mksquashfs-Make-sysinfo-conditional.patch new file mode 100644 index 0000000000..d152181f8a --- /dev/null +++ b/tools/squashfs4/patches/002-Mksquashfs-Make-sysinfo-conditional.patch @@ -0,0 +1,30 @@ +From 374e39a786a5acda841056bec26fd0e0c4d40dac Mon Sep 17 00:00:00 2001 +From: Phillip Lougher +Date: Mon, 15 Aug 2022 17:09:05 +0100 +Subject: [PATCH 1/1] Mksquashfs: Make sysinfo() conditional + +Fixes https://github.com/plougher/squashfs-tools/issues/123 + +Signed-off-by: Phillip Lougher +--- + squashfs-tools/mksquashfs.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -5802,6 +5802,7 @@ static int get_physical_memory() + long long page_size = sysconf(_SC_PAGESIZE); + int phys_mem; + ++#ifdef __linux__ + if(num_pages == -1 || page_size == -1) { + struct sysinfo sys; + int res = sysinfo(&sys); +@@ -5812,6 +5813,7 @@ static int get_physical_memory() + num_pages = sys.totalram; + page_size = sys.mem_unit; + } ++#endif + + phys_mem = num_pages * page_size >> 20; + diff --git a/tools/squashfs4/patches/003-Only-use-available-CPUs.patch b/tools/squashfs4/patches/003-Only-use-available-CPUs.patch new file mode 100644 index 0000000000..4f608b9ed6 --- /dev/null +++ b/tools/squashfs4/patches/003-Only-use-available-CPUs.patch @@ -0,0 +1,92 @@ +From bc8e655a420d2f62bb0597947e96dce7b4d3fb36 Mon Sep 17 00:00:00 2001 +From: Wessel Dankers +Date: Sun, 30 Oct 2022 19:29:28 +0100 +Subject: [PATCH] Only use available CPUs + +Not all online CPUs may be available for the current process, +especially when CPU affinity is involved. In such cases too many +threads will be created, which will then compete unnecessarily +for CPU time. + +Use sched_getaffinity() to determine the correct number of threads +to create. +--- + squashfs-tools/mksquashfs.c | 16 ++++++++++++---- + squashfs-tools/unsquashfs.c | 13 ++++++++++--- + 2 files changed, 22 insertions(+), 7 deletions(-) + +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -52,7 +52,9 @@ + #include + #include + +-#ifndef linux ++#ifdef linux ++#include ++#else + #include + #endif + +@@ -5079,7 +5081,15 @@ static void initialise_threads(int readq + BAD_ERROR("Failed to set signal mask in intialise_threads\n"); + + if(processors == -1) { +-#ifndef linux ++#ifdef linux ++ cpu_set_t cpu_set; ++ CPU_ZERO(&cpu_set); ++ ++ if(sched_getaffinity(0, sizeof cpu_set, &cpu_set) == -1) ++ processors = sysconf(_SC_NPROCESSORS_ONLN); ++ else ++ processors = CPU_COUNT(&cpu_set); ++#else + int mib[2]; + size_t len = sizeof(processors); + +@@ -5096,8 +5106,6 @@ static void initialise_threads(int readq + ERROR_EXIT(" Defaulting to 1\n"); + processors = 1; + } +-#else +- processors = sysconf(_SC_NPROCESSORS_ONLN); + #endif + } + +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -33,6 +33,7 @@ + #include "fnmatch_compat.h" + + #ifdef __linux__ ++#include + #include + #include + #elif defined __FreeBSD__ +@@ -2719,7 +2720,15 @@ void initialise_threads(int fragment_buf + } + + if(processors == -1) { +-#ifndef linux ++#ifdef linux ++ cpu_set_t cpu_set; ++ CPU_ZERO(&cpu_set); ++ ++ if(sched_getaffinity(0, sizeof cpu_set, &cpu_set) == -1) ++ processors = sysconf(_SC_NPROCESSORS_ONLN); ++ else ++ processors = CPU_COUNT(&cpu_set); ++#else + int mib[2]; + size_t len = sizeof(processors); + +@@ -2735,8 +2744,6 @@ void initialise_threads(int fragment_buf + "Defaulting to 1\n"); + processors = 1; + } +-#else +- processors = sysconf(_SC_NPROCESSORS_ONLN); + #endif + } + diff --git a/tools/squashfs4/patches/004-action-rework-strdupa-with-POSIX-strdup-and-free.patch b/tools/squashfs4/patches/004-action-rework-strdupa-with-POSIX-strdup-and-free.patch new file mode 100644 index 0000000000..3d6f696c8e --- /dev/null +++ b/tools/squashfs4/patches/004-action-rework-strdupa-with-POSIX-strdup-and-free.patch @@ -0,0 +1,37 @@ +From 92e628ec0e26cf091d82356e3b74f73bedf4cfc8 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sat, 15 Oct 2022 00:11:20 +0200 +Subject: [PATCH] action: rework strdupa with POSIX strdup and free + +strdupa is not POSIX and cause compilation error on macos. +Fix this by using strdup and free. + +Signed-off-by: Christian Marangi +Signed-off-by: Phillip Lougher +--- + squashfs-tools/action.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/squashfs-tools/action.c ++++ b/squashfs-tools/action.c +@@ -2415,9 +2415,17 @@ static char *get_start(char *s, int n) + + static int subpathname_fn(struct atom *atom, struct action_data *action_data) + { +- return fnmatch(atom->argv[0], get_start(strdupa(action_data->subpath), +- count_components(atom->argv[0])), +- FNM_PATHNAME|FNM_EXTMATCH) == 0; ++ char *s, *tmp; ++ int ret; ++ ++ s = tmp = strdup(action_data->subpath); ++ tmp = get_start(tmp, count_components(atom->argv[0])); ++ ++ ret = fnmatch(atom->argv[0], tmp, FNM_PATHNAME|FNM_EXTMATCH); ++ ++ free(s); ++ ++ return ret == 0; + } + + /* diff --git a/tools/squashfs4/patches/005-Don-t-use-sigwaitinfo-sigtimedwait-if-not-supported.patch b/tools/squashfs4/patches/005-Don-t-use-sigwaitinfo-sigtimedwait-if-not-supported.patch new file mode 100644 index 0000000000..80e8824c46 --- /dev/null +++ b/tools/squashfs4/patches/005-Don-t-use-sigwaitinfo-sigtimedwait-if-not-supported.patch @@ -0,0 +1,192 @@ +From dbe9747b4f09bd2f4d63af06e55c2c3ed35bfca1 Mon Sep 17 00:00:00 2001 +From: Phillip Lougher +Date: Tue, 7 Feb 2023 23:09:30 +0000 +Subject: [PATCH] Don't use sigwaitinfo()/sigtimedwait() if not supported + +If sigwaitinfo() and sigtimedwait() are not supported, +use sigwait() instead. + +This will disable the queue/caches dump if ^\ (SIGQUIT) +is hit twice within a second. + +But the queue/caches dump is still available if SIGHUP +is sent to the program. + +Currently this check is applied to MAC OS X. FreeBSD and +NetBSD appear to have these functions. + +Signed-off-by: Phillip Lougher +--- + squashfs-tools/info.c | 25 ++------------- + squashfs-tools/signals.h | 54 ++++++++++++++++++++++++++++++++ + squashfs-tools/unsquashfs_info.c | 25 ++------------- + 3 files changed, 60 insertions(+), 44 deletions(-) + create mode 100644 squashfs-tools/signals.h + +--- a/squashfs-tools/info.c ++++ b/squashfs-tools/info.c +@@ -2,7 +2,7 @@ + * Create a squashfs filesystem. This is a highly compressed read only + * filesystem. + * +- * Copyright (c) 2013, 2014, 2019, 2021 ++ * Copyright (c) 2013, 2014, 2019, 2021, 2022, 2023 + * Phillip Lougher + * + * This program is free software; you can redistribute it and/or +@@ -42,6 +42,7 @@ + #include "mksquashfs_error.h" + #include "progressbar.h" + #include "caches-queues-lists.h" ++#include "signals.h" + + static int silent = 0; + static struct dir_ent *ent = NULL; +@@ -144,7 +145,6 @@ void dump_state() + void *info_thrd(void *arg) + { + sigset_t sigmask; +- struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 }; + int sig, waiting = 0; + + sigemptyset(&sigmask); +@@ -152,26 +152,7 @@ void *info_thrd(void *arg) + sigaddset(&sigmask, SIGHUP); + + while(1) { +- if(waiting) +- sig = sigtimedwait(&sigmask, NULL, ×pec); +- else +- sig = sigwaitinfo(&sigmask, NULL); +- +- if(sig == -1) { +- switch(errno) { +- case EAGAIN: +- /* interval timed out */ +- waiting = 0; +- /* FALLTHROUGH */ +- case EINTR: +- /* if waiting, the wait will be longer, but +- that's OK */ +- continue; +- default: +- BAD_ERROR("sigtimedwait/sigwaitinfo failed " +- "because %s\n", strerror(errno)); +- } +- } ++ sig = wait_for_signal(&sigmask, &waiting); + + if(sig == SIGQUIT && !waiting) { + print_filename(); +--- /dev/null ++++ b/squashfs-tools/signals.h +@@ -0,0 +1,54 @@ ++#ifndef SIGNALS_H ++#define SIGNALS_H ++/* ++ * Create a squashfs filesystem. This is a highly compressed read only ++ * filesystem. ++ * ++ * Copyright (c) 2023 ++ * Phillip Lougher ++ * ++ * 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. ++ * ++ * signals.h ++ */ ++ ++static inline int wait_for_signal(sigset_t *sigmask, int *waiting) ++{ ++ int sig; ++ ++#if defined(__APPLE__) && defined(__MACH__) ++ sigwait(sigmask, &sig); ++ *waiting = 0; ++#else ++ struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 }; ++ ++ while(1) { ++ if(*waiting) ++ sig = sigtimedwait(sigmask, NULL, ×pec); ++ else ++ sig = sigwaitinfo(sigmask, NULL); ++ ++ if(sig != -1) ++ break; ++ ++ if(errno == EAGAIN) ++ *waiting = 0; ++ else if(errno != EINTR) ++ BAD_ERROR("sigtimedwait/sigwaitinfo failed because %s\n", strerror(errno)); ++ } ++#endif ++ return sig; ++} ++#endif +--- a/squashfs-tools/unsquashfs_info.c ++++ b/squashfs-tools/unsquashfs_info.c +@@ -2,7 +2,7 @@ + * Create a squashfs filesystem. This is a highly compressed read only + * filesystem. + * +- * Copyright (c) 2013, 2021 ++ * Copyright (c) 2013, 2021, 2023 + * Phillip Lougher + * + * This program is free software; you can redistribute it and/or +@@ -40,6 +40,7 @@ + #include "squashfs_fs.h" + #include "unsquashfs.h" + #include "unsquashfs_error.h" ++#include "signals.h" + + char *pathname = NULL; + +@@ -96,7 +97,6 @@ void dump_state() + void *info_thrd(void *arg) + { + sigset_t sigmask; +- struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 }; + int sig, waiting = 0; + + sigemptyset(&sigmask); +@@ -104,26 +104,7 @@ void *info_thrd(void *arg) + sigaddset(&sigmask, SIGHUP); + + while(1) { +- if(waiting) +- sig = sigtimedwait(&sigmask, NULL, ×pec); +- else +- sig = sigwaitinfo(&sigmask, NULL); +- +- if(sig == -1) { +- switch(errno) { +- case EAGAIN: +- /* interval timed out */ +- waiting = 0; +- /* FALLTHROUGH */ +- case EINTR: +- /* if waiting, the wait will be longer, but +- that's OK */ +- continue; +- default: +- BAD_ERROR("sigtimedwait/sigwaitinfo failed " +- "because %s\n", strerror(errno)); +- } +- } ++ sig = wait_for_signal(&sigmask, &waiting); + + if(sig == SIGQUIT && !waiting) { + if(pathname) diff --git a/tools/squashfs4/patches/006-Move-sysinfo.h-into-the-linux-only-section-should-fi.patch b/tools/squashfs4/patches/006-Move-sysinfo.h-into-the-linux-only-section-should-fi.patch new file mode 100644 index 0000000000..364356188f --- /dev/null +++ b/tools/squashfs4/patches/006-Move-sysinfo.h-into-the-linux-only-section-should-fi.patch @@ -0,0 +1,49 @@ +From b2f6454a2b2517cfba7a24cf02e9bdf3b959c86a Mon Sep 17 00:00:00 2001 +From: Tony Butler +Date: Sat, 18 Feb 2023 13:20:48 -0800 +Subject: [PATCH] Move sysinfo.h into the linux-only section, should fix build + on MacOS. + +All compilers set `__linux__`, but `linux` may not be defined, and usage +was mixed. Use `__linux__` everywhere instead. + +Signed-off-by: Tony Butler +--- + squashfs-tools/mksquashfs.c | 6 +++--- + squashfs-tools/unsquashfs.c | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -50,9 +50,9 @@ + #include + #include + #include +-#include + +-#ifdef linux ++#ifdef __linux__ ++#include + #include + #else + #include +@@ -5081,7 +5081,7 @@ static void initialise_threads(int readq + BAD_ERROR("Failed to set signal mask in intialise_threads\n"); + + if(processors == -1) { +-#ifdef linux ++#ifdef __linux__ + cpu_set_t cpu_set; + CPU_ZERO(&cpu_set); + +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -2720,7 +2720,7 @@ void initialise_threads(int fragment_buf + } + + if(processors == -1) { +-#ifdef linux ++#ifdef __linux__ + cpu_set_t cpu_set; + CPU_ZERO(&cpu_set); + diff --git a/tools/squashfs4/patches/007-Unsquashfs-fix-compilation-error-for-missing-sysctl..patch b/tools/squashfs4/patches/007-Unsquashfs-fix-compilation-error-for-missing-sysctl..patch new file mode 100644 index 0000000000..b7db00e4cb --- /dev/null +++ b/tools/squashfs4/patches/007-Unsquashfs-fix-compilation-error-for-missing-sysctl..patch @@ -0,0 +1,26 @@ +From dcf492077ef10ed7550b6e2b38b81318645bbdd5 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sun, 19 Feb 2023 04:36:01 +0100 +Subject: [PATCH] Unsquashfs: fix compilation error for missing sysctl.h on + macos + +Currently the include of sys/sysctl.h is guarded and done only for +FreeBSD system. Remove this to fix compilation error on macos following +the same pattern done in mksquashfs.c + +Signed-off-by: Christian Marangi +--- + squashfs-tools/unsquashfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -36,7 +36,7 @@ + #include + #include + #include +-#elif defined __FreeBSD__ ++#else + #include + #endif + diff --git a/tools/squashfs4/patches/100-portability.patch b/tools/squashfs4/patches/100-portability.patch new file mode 100644 index 0000000000..fe804d4476 --- /dev/null +++ b/tools/squashfs4/patches/100-portability.patch @@ -0,0 +1,37 @@ +--- a/squashfs-tools/xattr.c ++++ b/squashfs-tools/xattr.c +@@ -115,6 +115,7 @@ int xattr_get_prefix(struct xattr_list * + + static int read_xattrs_from_system(char *filename, struct xattr_list **xattrs) + { ++#if defined(linux) + ssize_t size, vsize; + char *xattr_names, *p; + int i; +@@ -227,6 +228,10 @@ failed: + free(xattr_list); + free(xattr_names); + return 0; ++#else ++ *xattrs = NULL; ++ return 0; ++#endif + } + + +--- a/squashfs-tools/unsquashfs_xattr.c ++++ b/squashfs-tools/unsquashfs_xattr.c +@@ -36,6 +36,7 @@ extern int strict_errors; + + int write_xattr(char *pathname, unsigned int xattr) + { ++#if defined(linux) + unsigned int count; + struct xattr_list *xattr_list; + int i; +@@ -147,4 +148,5 @@ int write_xattr(char *pathname, unsigned + free_xattr(xattr_list, count); + + return !failed; ++#endif + } diff --git a/tools/squashfs4/patches/101-xz_wrapper-support-multiple-lzma-configuration-optio.patch b/tools/squashfs4/patches/101-xz_wrapper-support-multiple-lzma-configuration-optio.patch new file mode 100644 index 0000000000..c882529cad --- /dev/null +++ b/tools/squashfs4/patches/101-xz_wrapper-support-multiple-lzma-configuration-optio.patch @@ -0,0 +1,167 @@ +From f49793cfbd72fdc40ab75dbffef42dca774701d1 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 14 Oct 2022 15:59:16 +0200 +Subject: [PATCH] xz_wrapper: support multiple lzma configuration options + +Add option to configure preset, lc, lp and pb lzma parameters. +-Xpreset can be both a level or set to 'extreme' to use the lzma extreme +compression options. + +New option added: + -Xpreset + -Xlc + -Xlp + -Xpb + +Signed-off-by: Christian Marangi +--- + squashfs-tools/xz_wrapper.c | 112 +++++++++++++++++++++++++++++++++++- + 1 file changed, 109 insertions(+), 3 deletions(-) + +--- a/squashfs-tools/xz_wrapper.c ++++ b/squashfs-tools/xz_wrapper.c +@@ -44,7 +44,10 @@ static struct bcj bcj[] = { + static int filter_count = 1; + static int dictionary_size = 0; + static float dictionary_percent = 0; +- ++static int preset = LZMA_PRESET_DEFAULT; ++static int lc = -1; ++static int lp = -1; ++static int pb = -1; + + /* + * This function is called by the options parsing code in mksquashfs.c +@@ -53,6 +56,11 @@ static float dictionary_percent = 0; + * Two specific options are supported: + * -Xbcj + * -Xdict-size ++ * -Xpreset ++ * -Xe ++ * -Xlc ++ * -Xlp ++ * -Xpb + * + * This function returns: + * >=0 (number of additional args parsed) on success +@@ -141,6 +149,85 @@ static int xz_options(char *argv[], int + } + + return 1; ++ } else if(strcmp(argv[0], "-Xpreset") == 0) { ++ char *b; ++ long val; ++ ++ if(argc < 2) { ++ fprintf(stderr, "xz: -Xpreset missing preset-level\n"); ++ goto failed; ++ } ++ ++ if (strcmp(argv[1], "extreme") == 0) { ++ preset = LZMA_PRESET_EXTREME; ++ ++ return 1; ++ } ++ ++ val = strtol(argv[1], &b, 10); ++ if ((int) val < 0 || (int) val & ~LZMA_PRESET_LEVEL_MASK) { ++ fprintf(stderr, "xz: -Xpreset can't be " ++ "negative or more than the max preset\n"); ++ goto failed; ++ } ++ ++ preset = (int) val; ++ ++ return 1; ++ } else if(strcmp(argv[0], "-Xlc") == 0) { ++ char *b; ++ long val; ++ ++ if(argc < 2) { ++ fprintf(stderr, "xz: -Xlc missing value\n"); ++ goto failed; ++ } ++ ++ val = strtol(argv[1], &b, 10); ++ if ((int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) { ++ fprintf(stderr, "xz: -Xlc invalid value\n"); ++ goto failed; ++ } ++ ++ lc = (int) val; ++ ++ return 1; ++ } else if(strcmp(argv[0], "-Xlp") == 0) { ++ char *b; ++ long val; ++ ++ if(argc < 2) { ++ fprintf(stderr, "xz: -Xlp missing value\n"); ++ goto failed; ++ } ++ ++ val = strtol(argv[1], &b, 10); ++ if ((int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) { ++ fprintf(stderr, "xz: -Xlc invalid value\n"); ++ goto failed; ++ } ++ ++ lp = (int) val; ++ ++ return 1; ++ } else if(strcmp(argv[0], "-Xpb") == 0) { ++ char *b; ++ long val; ++ ++ if(argc < 2) { ++ fprintf(stderr, "xz: -Xpb missing value\n"); ++ goto failed; ++ } ++ ++ val = strtol(argv[1], &b, 10); ++ if ((int) val < LZMA_PB_MIN || (int) val > LZMA_PB_MAX) { ++ fprintf(stderr, "xz: -Xlc invalid value\n"); ++ goto failed; ++ } ++ ++ pb = (int) val; ++ ++ return 1; + } + + return -1; +@@ -446,11 +533,20 @@ static int xz_compress(void *strm, void + for(i = 0; i < stream->filters; i++) { + struct filter *filter = &stream->filter[i]; + +- if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT)) ++ if(lzma_lzma_preset(&stream->opt, preset)) + goto failed; + + stream->opt.dict_size = stream->dictionary_size; + ++ if (lc >= 0) ++ stream->opt.lc = lc; ++ ++ if (lp >= 0) ++ stream->opt.lp = lp; ++ ++ if (pb >= 0) ++ stream->opt.pb = pb; ++ + filter->length = 0; + res = lzma_stream_buffer_encode(filter->filter, + LZMA_CHECK_CRC32, NULL, src, size, filter->buffer, +@@ -521,6 +617,12 @@ static void xz_usage(FILE *stream) + fprintf(stream, " header as either 2^n or as 2^n+2^(n+1).\n\t\t"); + fprintf(stream, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or"); + fprintf(stream, " 32K, 16K, 8K\n\t\tetc.\n"); ++ fprintf(stream, "\t -Xpreset \n"); ++ fprintf(stream, "\t\tUse as the custom preset to use"); ++ fprintf(stream, " on compress. Can be a level number or extreme.\n"); ++ fprintf(stream, "\t -Xlc \n"); ++ fprintf(stream, "\t -Xlp \n"); ++ fprintf(stream, "\t -Xpb \n"); + } + +