diff options
11 files changed, 713 insertions, 3 deletions
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 <phillip@squashfs.org.uk> +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 <phillip@squashfs.org.uk> +--- + 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 <errno.h> + #include <stdlib.h> + #include <stdio.h> ++#include <signal.h> + #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 <sys/sysinfo.h> + #include <sys/sysmacros.h> ++#elif defined __FreeBSD__ ++#include <sys/sysctl.h> ++#endif ++ + #include <sys/types.h> + #include <sys/time.h> + #include <sys/resource.h> 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 <phillip@squashfs.org.uk> +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 <phillip@squashfs.org.uk> +--- + 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 <wsl@fruit.je> +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 <ctype.h> + #include <sys/sysinfo.h> + +-#ifndef linux ++#ifdef linux ++#include <sched.h> ++#else + #include <sys/sysctl.h> + #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 <sched.h> + #include <sys/sysinfo.h> + #include <sys/sysmacros.h> + #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 <ansuelsmth@gmail.com> +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 <ansuelsmth@gmail.com> +Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk> +--- + 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 <phillip@squashfs.org.uk> +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 <phillip@squashfs.org.uk> +--- + 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 <phillip@squashfs.org.uk> + * + * 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 <phillip@squashfs.org.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. ++ * ++ * 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 <phillip@squashfs.org.uk> + * + * 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 <spudz76@gmail.com> +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 <spudz76@gmail.com> +--- + 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 <sys/wait.h> + #include <limits.h> + #include <ctype.h> +-#include <sys/sysinfo.h> + +-#ifdef linux ++#ifdef __linux__ ++#include <sys/sysinfo.h> + #include <sched.h> + #else + #include <sys/sysctl.h> +@@ -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 <ansuelsmth@gmail.com> +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 <ansuelsmth@gmail.com> +--- + 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 <sched.h> + #include <sys/sysinfo.h> + #include <sys/sysmacros.h> +-#elif defined __FreeBSD__ ++#else + #include <sys/sysctl.h> + #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 <ansuelsmth@gmail.com> +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 <ansuelsmth@gmail.com> +--- + 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 <preset-level or extreme>\n"); ++ fprintf(stream, "\t\tUse <preset-value> as the custom preset to use"); ++ fprintf(stream, " on compress. Can be a level number or extreme.\n"); ++ fprintf(stream, "\t -Xlc <value>\n"); ++ fprintf(stream, "\t -Xlp <value>\n"); ++ fprintf(stream, "\t -Xpb <value>\n"); + } + + |