diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 38a9870d..3ded7256 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,25 +8,18 @@ jobs: fail-fast: false matrix: include: - # >= we can make C++-17 work on bionic with the ubuntu-toolchain-r PPA - # use a tool like, e.g., linuxdeploy-plugin-checkrt to bundle libstdc++ when building libappimage-based packages on bionic - - DIST: bionic + - RELEASE: latest ARCH: x86_64 - - DIST: bionic - ARCH: i386 - - # CentOS 7 based Docker images can use devtoolset-9 to get a compatible compiler (as demonstrated by appimagebuild) - # (devtoolset compilers can build ABI compatible builds by embedding parts of libc/libstdc++, so ld-p-checkrt is not needed) - - DIST: appimagebuild - ARCH: x86_64 - - DIST: appimagebuild - ARCH: i386 + - RELEASE: latest + ARCH: armhf + - RELEASE: latest + ARCH: aarch64 # special builds - - DIST: bionic + - RELEASE: latest ARCH: x86_64 BUILD_TYPE: coverage - - DIST: bionic + - RELEASE: latest ARCH: x86_64 BUILD_TYPE: shared-only LIBAPPIMAGE_SHARED_ONLY: 1 @@ -35,13 +28,15 @@ jobs: runs-on: ubuntu-latest env: ARCH: ${{ matrix.ARCH }} - DIST: ${{ matrix.DIST }} + RELEASE: ${{ matrix.RELEASE }} BUILD_TYPE: ${{ matrix.DIST }} LIBAPPIMAGE_SHARED_ONLY: ${{ matrix.LIBAPPIMAGE_SHARED_ONLY }} steps: - uses: actions/checkout@v2 with: submodules: recursive + - name: Set up QEMU integration for Docker + run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - name: Build libappimage and run tests run: bash -ex ci/build-in-docker.sh env: diff --git a/ci/Dockerfile b/ci/Dockerfile index 790372d4..535a3fe6 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -1,8 +1,7 @@ # these args are available *only* for the FROM call -ARG DOCKER_ARCH -ARG DIST +ARG RELEASE -FROM $DOCKER_ARCH/ubuntu:$DIST +FROM ubuntu:$RELEASE # we need to repeat all args from above which we need during build and runtime to make them available ARG ARCH @@ -12,9 +11,9 @@ ENV CI=1 COPY ./install-deps.sh / # see above, for build time we need to pass the args manually (using ENV does not work) -RUN bash -xe install-deps.sh +RUN bash -xe /install-deps.sh # create unprivileged user for non-build-script use of this image # build-in-docker.sh will likely not use this one, as it enforces the caller's uid inside the container -RUN adduser --system --group build +RUN useradd build USER build diff --git a/ci/build-and-test.sh b/ci/build-and-test.sh index 7e35e89b..fc8c8c9c 100755 --- a/ci/build-and-test.sh +++ b/ci/build-and-test.sh @@ -21,8 +21,8 @@ cleanup () { trap cleanup EXIT # store repo root as variable -REPO_ROOT="$(readlink -f "$(dirname "$(dirname "$0")")")" -OLD_CWD="$(readlink -f .)" +REPO_ROOT="$(readlink -f "$(dirname "$(dirname "${BASH_SOURCE[0]}")")")" +OLD_CWD="$(readlink -f "$PWD")" pushd "$BUILD_DIR" diff --git a/ci/build-docker-image.sh b/ci/build-docker-image.sh index ab37c85d..1bd7426b 100755 --- a/ci/build-docker-image.sh +++ b/ci/build-docker-image.sh @@ -1,12 +1,11 @@ #! /bin/bash -if [[ "$DIST" == "" ]] || [[ "$ARCH" == "" ]]; then - echo "Usage: env ARCH=... DIST=... bash $0" +if [[ "${ARCH:-}" == "" ]] || [[ "${RELEASE:-}" == "" ]]; then + echo "Usage: env ARCH=... RELEASE=... bash $0" exit 1 fi -set -x -set -e +set -euo pipefail # the other script sources this script, therefore we have to support that use case if [[ "${BASH_SOURCE[*]}" != "" ]]; then @@ -15,19 +14,10 @@ else this_dir="$(readlink -f "$(dirname "$0")")" fi -case "$ARCH" in - x86_64) - export DOCKER_ARCH=amd64 - ;; - *) - export DOCKER_ARCH="$ARCH" - ;; -esac - -image=quay.io/appimage/libappimage-build:"$DIST"-"$ARCH" +image=quay.io/appimage/libappimage-build:"$RELEASE" extra_build_args=() -if [[ "$NO_PULL" == "" ]]; then +if [[ "${NO_PULL:-}" == "" ]]; then # speed up build by pulling last built image from quay.io and building the docker file using the old image as a base docker pull "$image" || true extra_build_args=(--cache-from "$image") @@ -35,10 +25,10 @@ fi # if the image hasn't changed, this should be a no-op docker build \ + --platform "$platform" \ --pull \ - --build-arg DOCKER_ARCH \ --build-arg ARCH \ - --build-arg DIST \ + --build-arg RELEASE \ -t "$image" \ "${extra_build_args[@]}" \ "$this_dir" @@ -48,7 +38,7 @@ docker build \ # rebuilt anyway # credentials shall only be available on (protected) master branch set +x -if [[ "$DOCKER_USERNAME" != "" ]]; then +if [[ "${DOCKER_USERNAME:-}" != "" ]]; then echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin quay.io docker push "$image" fi diff --git a/ci/build-in-docker.sh b/ci/build-in-docker.sh index d05cb92a..be5eb895 100755 --- a/ci/build-in-docker.sh +++ b/ci/build-in-docker.sh @@ -1,31 +1,51 @@ #! /bin/bash -if [[ "$DIST" == "" ]] || [[ "$ARCH" == "" ]]; then - echo "Usage: env ARCH=... DIST=... bash $0" +if [[ "${ARCH:-}" == "" ]] || [[ "${RELEASE:-}" == "" ]]; then + echo "Usage: env ARCH=... RELEASE=... bash $0" exit 1 fi -set -x -set -e +set -euo pipefail -cd "$(readlink -f "$(dirname "$0")")" - -if [[ "$DIST" != appimagebuild* ]]; then - # sets variables $image - source build-docker-image.sh +# the other script sources this script, therefore we have to support that use case +if [[ "${BASH_SOURCE[*]}" != "" ]]; then + this_dir="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")" else - image=quay.io/appimage/appimagebuild:centos7-"$ARCH" - docker pull "$image" + this_dir="$(readlink -f "$(dirname "$0")")" fi +case "$ARCH" in + x86_64) + platform=linux/amd64 + ;; + i686) + platform=linux/i386 + ;; + armhf) + platform=linux/arm/v7 + ;; + aarch64) + platform=linux/arm64/v8 + ;; + *) + echo "unknown architecture: $ARCH" + exit 2 + ;; +esac + +cd "$(readlink -f "$(dirname "$0")")" + +# sets variables $image +source build-docker-image.sh + DOCKER_OPTS=() # fix for https://stackoverflow.com/questions/51195528/rcc-error-in-resource-qrc-cannot-find-file-png -if [ "$CI" != "" ]; then +if [ "${CI:-}" != "" ]; then DOCKER_OPTS+=("--security-opt" "seccomp:unconfined") fi # only if there's more than 3G of free space in RAM, we can build in a RAM disk -if [[ "$GITHUB_ACTIONS" != "" ]]; then +if [[ "${GITHUB_ACTIONS:-}" != "" ]]; then echo "Building on GitHub actions, which does not support --tmpfs flag -> building on regular disk" elif [[ "$(free -m | grep "Mem:" | awk '{print $4}')" -gt 3072 ]]; then echo "Host system has enough free memory -> building in RAM disk" diff --git a/ci/install-deps.sh b/ci/install-deps.sh index b02aab99..84bce412 100755 --- a/ci/install-deps.sh +++ b/ci/install-deps.sh @@ -1,44 +1,20 @@ #! /bin/bash -set -e +set -euo pipefail -if [[ "$ARCH" == "" ]]; then - echo "Usage: env ARCH=... bash $0" - exit 2 -fi - -if [[ "$CI" == "" ]]; then +if [[ "${CI:-}" == "" ]]; then echo "Caution: this script is supposed to run inside a (disposable) CI environment" echo "It will alter a system, and should not be run on workstations or alike" echo "You can export CI=1 to prevent this error from being shown again" exit 3 fi -case "$ARCH" in - x86_64|i386|armhf|arm64) - ;; - *) - echo "Error: unsupported architecture: $ARCH" - exit 4 - ;; -esac - -case "$DIST" in - bionic|focal) - ;; - *) - echo "Error: unsupported distribution: $DIST" - exit 5 - ;; -esac - set -x packages=( libfuse-dev desktop-file-utils ca-certificates - gcc-multilib make build-essential git @@ -60,27 +36,8 @@ packages=( libboost-dev ) -# install gcc-10 (supports C++17 with std::filesystem properly) -if [[ "$DIST" == "bionic" ]]; then - apt-get update - apt-get install --no-install-recommends -y software-properties-common - add-apt-repository -y ppa:ubuntu-toolchain-r/test - packages+=(g++-10-multilib) -else - packages+=(g++-multilib) -fi - # make sure installation won't hang on GitHub actions export DEBIAN_FRONTEND=noninteractive apt-get update apt-get -y --no-install-recommends install "${packages[@]}" - -# install more recent CMake version -wget https://artifacts.assassinate-you.net/prebuilt-cmake/continuous/cmake-v3.24.1-ubuntu_"$DIST"-"$ARCH".tar.gz -qO- | \ - tar xz -C/usr/local --strip-components=1 - -# g++-10 should be used by default -if [[ "$DIST" == "bionic" ]]; then - update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-10 9999 -fi diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake index 459f2363..a3540706 100644 --- a/cmake/dependencies.cmake +++ b/cmake/dependencies.cmake @@ -33,35 +33,10 @@ set(CFLAGS ${DEPENDENCIES_CFLAGS}) set(CPPFLAGS ${DEPENDENCIES_CPPFLAGS}) set(LDFLAGS ${DEPENDENCIES_LDFLAGS}) - -set(USE_SYSTEM_XZ OFF CACHE BOOL "Use system xz/liblzma instead of building our own") - if (NOT LIBAPPIMAGE_SHARED_ONLY) - if(NOT USE_SYSTEM_XZ) - message(STATUS "Downloading and building xz") + import_pkgconfig_target(TARGET_NAME liblzma PKGCONFIG_TARGET liblzma) - ExternalProject_Add( - xz-EXTERNAL - URL https://netcologne.dl.sourceforge.net/project/lzmautils/xz-5.2.5.tar.gz - URL_HASH SHA512=7443674247deda2935220fbc4dfc7665e5bb5a260be8ad858c8bd7d7b9f0f868f04ea45e62eb17c0a5e6a2de7c7500ad2d201e2d668c48ca29bd9eea5a73a3ce - CONFIGURE_COMMAND CC=${CC} CXX=${CXX} CFLAGS=${CFLAGS} CPPFLAGS=${CPPFLAGS} LDFLAGS=${LDFLAGS} /configure --with-pic --disable-shared --enable-static --prefix= --libdir=/lib ${EXTRA_CONFIGURE_FLAGS} --disable-xz --disable-xzdec - BUILD_COMMAND ${MAKE} - INSTALL_COMMAND ${MAKE} install - UPDATE_DISCONNECTED On - ) - - import_external_project( - TARGET_NAME xz - EXT_PROJECT_NAME xz-EXTERNAL - LIBRARY_DIRS /lib/ - LIBRARIES "/lib/liblzma.a" - INCLUDE_DIRS "/src/liblzma/api/" - ) - else() - message(STATUS "Using system xz") - - import_pkgconfig_target(TARGET_NAME xz PKGCONFIG_TARGET liblzma) - endif() + import_pkgconfig_target(TARGET_NAME libzstd PKGCONFIG_TARGET libzstd) # as distros don't provide suitable squashfuse and squashfs-tools, those dependencies are bundled in, can, and should @@ -76,27 +51,16 @@ if (NOT LIBAPPIMAGE_SHARED_ONLY) import_pkgconfig_target(TARGET_NAME libfuse PKGCONFIG_TARGET fuse) # TODO: implement out-of-source builds for squashfuse, as for the other dependencies - configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/src/patches/patch-squashfuse.sh.in - ${CMAKE_CURRENT_BINARY_DIR}/patch-squashfuse.sh - @ONLY - ) ExternalProject_Add( squashfuse-EXTERNAL GIT_REPOSITORY https://github.com/vasi/squashfuse/ - GIT_TAG 1f98030 + # release 0.5.2 + GIT_TAG 775b4cc72ab47641637897f11ce0da15d5c1f115 UPDATE_COMMAND "" # make sure CMake won't try to fetch updates unnecessarily and hence rebuild the dependency every time - PATCH_COMMAND bash -xe ${CMAKE_CURRENT_BINARY_DIR}/patch-squashfuse.sh - CONFIGURE_COMMAND ${LIBTOOLIZE} --force - COMMAND env ACLOCAL_FLAGS="-I /usr/share/aclocal" aclocal - COMMAND ${AUTOHEADER} - COMMAND ${AUTOMAKE} --force-missing --add-missing - COMMAND ${AUTORECONF} -fi || true - COMMAND ${SED} -i "/PKG_CHECK_MODULES.*/,/,:./d" configure # https://github.com/vasi/squashfuse/issues/12 + CONFIGURE_COMMAND /autogen.sh COMMAND ${SED} -i "s/typedef off_t sqfs_off_t/typedef int64_t sqfs_off_t/g" common.h # off_t's size might differ, see https://stackoverflow.com/a/9073762 - COMMAND CC=${CC} CXX=${CXX} CFLAGS=${CFLAGS} LDFLAGS=${LDFLAGS} /configure --disable-demo --disable-high-level --without-lzo --without-lz4 --prefix= --libdir=/lib --with-xz=${xz_PREFIX} ${EXTRA_CONFIGURE_FLAGS} - COMMAND ${SED} -i "s|XZ_LIBS = -llzma |XZ_LIBS = -Bstatic ${xz_LIBRARIES}/|g" Makefile + COMMAND CC=${CC} CXX=${CXX} CFLAGS=${CFLAGS} LDFLAGS=${LDFLAGS} /configure --disable-demo --disable-high-level --without-lzo --without-lz4 --prefix= --libdir=/lib ${EXTRA_CONFIGURE_FLAGS} BUILD_COMMAND ${MAKE} BUILD_IN_SOURCE ON INSTALL_COMMAND ${MAKE} install @@ -109,50 +73,24 @@ if (NOT LIBAPPIMAGE_SHARED_ONLY) LIBRARIES "/.libs/libsquashfuse.a;/.libs/libsquashfuse_ll.a;/.libs/libfuseprivate.a" INCLUDE_DIRS "" ) - else() - message(STATUS "Using system squashfuse") - import_pkgconfig_target(TARGET_NAME libsquashfuse PKGCONFIG_TARGET squashfuse) - endif() - - - set(USE_SYSTEM_LIBARCHIVE OFF CACHE BOOL "Use system libarchive instead of building our own") - - if(NOT USE_SYSTEM_LIBARCHIVE) - message(STATUS "Downloading and building libarchive") - - ExternalProject_Add( - libarchive-EXTERNAL - URL https://www.libarchive.org/downloads/libarchive-3.3.1.tar.gz - URL_HASH SHA512=90702b393b6f0943f42438e277b257af45eee4fa82420431f6a4f5f48bb846f2a72c8ff084dc3ee9c87bdf8b57f4d8dddf7814870fe2604fe86c55d8d744c164 - CONFIGURE_COMMAND CC=${CC} CXX=${CXX} CFLAGS=${CFLAGS} CPPFLAGS=${CPPFLAGS} LDFLAGS=${LDFLAGS} /configure --with-pic --disable-shared --enable-static --disable-bsdtar --disable-bsdcat --disable-bsdcpio --with-zlib --without-bz2lib --without-iconv --without-lz4 --without-lzma --without-lzo2 --without-nettle --without-openssl --without-xml2 --without-expat --prefix= --libdir=/lib ${EXTRA_CONFIGURE_FLAGS} - BUILD_COMMAND ${MAKE} - INSTALL_COMMAND ${MAKE} install - UPDATE_DISCONNECTED On - ) - - import_external_project( - TARGET_NAME libarchive - EXT_PROJECT_NAME libarchive-EXTERNAL - LIBRARIES "/lib/libarchive.a" - INCLUDE_DIRS "/include/" + target_link_libraries( + libsquashfuse + INTERFACE liblzma + INTERFACE libzstd + INTERFACE libzlib ) else() - message(STATUS "Using system libarchive") + message(STATUS "Using system squashfuse") - import_find_pkg_target(libarchive LibArchive LibArchive) + import_pkgconfig_target(TARGET_NAME libsquashfuse PKGCONFIG_TARGET squashfuse) endif() + message(STATUS "Using system libarchive") + import_find_pkg_target(libarchive LibArchive LibArchive) #### build dependency configuration #### - # only have to build custom xz when not using system libxz - if(TARGET xz-EXTERNAL) - if(TARGET squashfuse-EXTERNAL) - ExternalProject_Add_StepDependencies(squashfuse-EXTERNAL configure xz-EXTERNAL) - endif() - endif() - # we need Boost.Algorithm, which does not need to be included explicitly since it's header-only # link to Boost::boost to include the header directories find_package(Boost 1.53.0 REQUIRED) diff --git a/src/libappimage/CMakeLists.txt b/src/libappimage/CMakeLists.txt index 50ae1bf1..09269334 100644 --- a/src/libappimage/CMakeLists.txt +++ b/src/libappimage/CMakeLists.txt @@ -32,12 +32,10 @@ foreach(target libappimage libappimage_static) # not linking publicly to squashfuse as headers are not needed when using libappimage # unit tests etc., which use squashfuse directly, must link to it explicitly PRIVATE libsquashfuse - PRIVATE xz PRIVATE Boost::boost PUBLIC libappimage_shared PUBLIC pthread PRIVATE libgio - PRIVATE libzlib PUBLIC libcairo PUBLIC librsvg PUBLIC dl diff --git a/src/patches/patch-squashfuse.sh.in b/src/patches/patch-squashfuse.sh.in deleted file mode 100755 index bd3452f2..00000000 --- a/src/patches/patch-squashfuse.sh.in +++ /dev/null @@ -1,8 +0,0 @@ -#! /bin/bash - -git checkout ll.c Makefile.am fuseprivate.c fuseprivate.h hl.c ll.h ll_inode.c nonstd-daemon.c - -patch -p1 < @PROJECT_SOURCE_DIR@/src/patches/squashfuse.patch -patch -p1 < @PROJECT_SOURCE_DIR@/src/patches/squashfuse_dlopen.patch - -cp -v @PROJECT_SOURCE_DIR@/src/patches/squashfuse_dlopen.c @PROJECT_SOURCE_DIR@/src/patches/squashfuse_dlopen.h . diff --git a/src/patches/squashfuse.patch b/src/patches/squashfuse.patch deleted file mode 100644 index db94d2f7..00000000 --- a/src/patches/squashfuse.patch +++ /dev/null @@ -1,57 +0,0 @@ -diff --git a/Makefile.am b/Makefile.am -index f0d7cde..70c4aa0 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -14,6 +14,7 @@ bin_PROGRAMS = - noinst_PROGRAMS = - - noinst_LTLIBRARIES = libsquashfuse.la -+noinst_LTLIBRARIES += libsquashfuse_ll.la - - # Main library: libsquashfuse - libsquashfuse_la_SOURCES = swap.c cache.c table.c dir.c file.c fs.c \ -@@ -46,10 +47,9 @@ endif - - # Low-level squashfuse_ll, if supported - if SQ_WANT_LOWLEVEL --bin_PROGRAMS += squashfuse_ll --squashfuse_ll_SOURCES = ll.c ll_inode.c nonstd-daemon.c ll.h --squashfuse_ll_CPPFLAGS = $(FUSE_CPPFLAGS) --squashfuse_ll_LDADD = libsquashfuse.la libfuseprivate.la $(COMPRESSION_LIBS) \ -+libsquashfuse_ll_la_SOURCES = ll.c ll_inode.c nonstd-daemon.c ll.h -+libsquashfuse_ll_la_CPPFLAGS = $(FUSE_CPPFLAGS) -+libsquashfuse_ll_la_LIBADD = libsquashfuse.la libfuseprivate.la $(COMPRESSION_LIBS) \ - $(FUSE_LIBS) - - noinst_LTLIBRARIES += libfuseprivate.la -diff --git a/ll.c b/ll.c -index a2c7902..8fcb3f4 100644 ---- a/ll.c -+++ b/ll.c -@@ -390,7 +390,7 @@ static sqfs_ll *sqfs_ll_open(const char *path, size_t offset) { - return NULL; - } - --int main(int argc, char *argv[]) { -+int fusefs_main(int argc, char *argv[], void (*mounted) (void)) { - struct fuse_args args; - sqfs_opts opts; - -@@ -451,6 +451,8 @@ int main(int argc, char *argv[]) { - if (sqfs_ll_daemonize(fg) != -1) { - if (fuse_set_signal_handlers(se) != -1) { - fuse_session_add_chan(se, ch.ch); -+ if (mounted) -+ mounted (); - /* FIXME: multithreading */ - err = fuse_session_loop(se); - fuse_remove_signal_handlers(se); -@@ -466,6 +468,8 @@ int main(int argc, char *argv[]) { - } - } - fuse_opt_free_args(&args); -+ if (mounted) -+ rmdir (mountpoint); - free(ll); - free(mountpoint); - diff --git a/src/patches/squashfuse_dlopen.c b/src/patches/squashfuse_dlopen.c deleted file mode 100644 index fec4b761..00000000 --- a/src/patches/squashfuse_dlopen.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "squashfuse_dlopen.h" - -void *libhandle = NULL; -int have_libloaded = 0; - -const char *load_library_errmsg = - "AppImages require FUSE to run. \n" - "You might still be able to extract the contents of this AppImage \n" - "if you run it with the --appimage-extract option. \n" - "See https://github.com/AppImage/AppImageKit/wiki/FUSE \n" - "for more information\n"; - diff --git a/src/patches/squashfuse_dlopen.h b/src/patches/squashfuse_dlopen.h deleted file mode 100644 index 1b93a8e9..00000000 --- a/src/patches/squashfuse_dlopen.h +++ /dev/null @@ -1,262 +0,0 @@ -#ifndef SQFS_DLOPEN_H -#define SQFS_DLOPEN_H - -//#define ENABLE_DLOPEN - -#ifdef ENABLE_DLOPEN - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/*** dlopen() stuff ***/ - -#define LIBNAME "libfuse.so.2" - -extern void *libhandle; -extern int have_libloaded; -extern const char *load_library_errmsg; - -#define LOAD_LIBRARY \ -if (have_libloaded != 1) { \ - if (!(libhandle = dlopen(LIBNAME, RTLD_LAZY))) { \ - fprintf(stderr, "dlopen(): error loading " LIBNAME "\n\n%s", load_library_errmsg ); \ - exit(1); \ - } else { \ - have_libloaded = 1; \ - } \ -} - -#define STRINGIFY(x) #x - -#define LOAD_SYMBOL(type,x,param) \ -type (*dl_##x) param; \ -*(void **) (&dl_##x) = dlsym(libhandle, STRINGIFY(x)); \ -if (dlerror()) { \ - fprintf(stderr, "dlsym(): error loading symbol from " LIBNAME "\n\n%s", load_library_errmsg ); \ - CLOSE_LIBRARY; \ - exit(1); \ -} - -#define DL(x) dl_##x -#define CLOSE_LIBRARY dlclose(libhandle); - - -/*** libfuse stuff ***/ - -#define FUSE_ROOT_ID 1 -#define FUSE_ARGS_INIT(argc, argv) { argc, argv, 0 } -#define FUSE_OPT_KEY(templ, key) { templ, -1U, key } -#define FUSE_OPT_KEY_OPT -1 -#define FUSE_OPT_KEY_NONOPT -2 -#define FUSE_OPT_END { NULL, 0, 0 } - -enum fuse_buf_flags { - FUSE_BUF_IS_FD = (1 << 1), - FUSE_BUF_FD_SEEK = (1 << 2), - FUSE_BUF_FD_RETRY = (1 << 3), -}; - -typedef unsigned long fuse_ino_t; -typedef struct fuse_req *fuse_req_t; - -struct fuse_chan; -struct fuse_pollhandle; - -struct fuse_args { - int argc; - char **argv; - int allocated; -}; - -typedef int (*fuse_fill_dir_t) (void *buf, const char *name, const struct stat *stbuf, off_t off); -typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key, struct fuse_args *outargs); -typedef struct fuse_dirhandle *fuse_dirh_t; -typedef int (*fuse_dirfil_t) (fuse_dirh_t h, const char *name, int type, ino_t ino); - -struct fuse_file_info { - int flags; - unsigned long fh_old; - int writepage; - unsigned int direct_io : 1; - unsigned int keep_cache : 1; - unsigned int flush : 1; - unsigned int nonseekable : 1; - unsigned int flock_release : 1; - unsigned int padding : 27; - uint64_t fh; - uint64_t lock_owner; -}; - -struct fuse_entry_param { - fuse_ino_t ino; - unsigned long generation; - struct stat attr; - double attr_timeout; - double entry_timeout; -}; - -struct fuse_opt { - const char *templ; - unsigned long offset; - int value; -}; - -struct fuse_forget_data { - uint64_t ino; - uint64_t nlookup; -}; - -struct fuse_conn_info { - unsigned proto_major; - unsigned proto_minor; - unsigned async_read; - unsigned max_write; - unsigned max_readahead; - unsigned capable; - unsigned want; - unsigned max_background; - unsigned congestion_threshold; - unsigned reserved[23]; -}; - -struct fuse_buf { - size_t size; - enum fuse_buf_flags flags; - void *mem; - int fd; - off_t pos; -}; - -struct fuse_bufvec { - size_t count; - size_t idx; - size_t off; - struct fuse_buf buf[1]; -}; - -struct fuse_context { - struct fuse *fuse; - uid_t uid; - gid_t gid; - pid_t pid; - void *private_data; - mode_t umask; -}; - -struct fuse_operations { - int (*getattr) (const char *, struct stat *); - int (*readlink) (const char *, char *, size_t); - int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t); - int (*mknod) (const char *, mode_t, dev_t); - int (*mkdir) (const char *, mode_t); - int (*unlink) (const char *); - int (*rmdir) (const char *); - int (*symlink) (const char *, const char *); - int (*rename) (const char *, const char *); - int (*link) (const char *, const char *); - int (*chmod) (const char *, mode_t); - int (*chown) (const char *, uid_t, gid_t); - int (*truncate) (const char *, off_t); - int (*utime) (const char *, struct utimbuf *); - int (*open) (const char *, struct fuse_file_info *); - int (*read) (const char *, char *, size_t, off_t, struct fuse_file_info *); - int (*write) (const char *, const char *, size_t, off_t, struct fuse_file_info *); - int (*statfs) (const char *, struct statvfs *); - int (*flush) (const char *, struct fuse_file_info *); - int (*release) (const char *, struct fuse_file_info *); - int (*fsync) (const char *, int, struct fuse_file_info *); - int (*setxattr) (const char *, const char *, const char *, size_t, int); - int (*getxattr) (const char *, const char *, char *, size_t); - int (*listxattr) (const char *, char *, size_t); - int (*removexattr) (const char *, const char *); - int (*opendir) (const char *, struct fuse_file_info *); - int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *); - int (*releasedir) (const char *, struct fuse_file_info *); - int (*fsyncdir) (const char *, int, struct fuse_file_info *); - void *(*init) (struct fuse_conn_info *conn); - void (*destroy) (void *); - int (*access) (const char *, int); - int (*create) (const char *, mode_t, struct fuse_file_info *); - int (*ftruncate) (const char *, off_t, struct fuse_file_info *); - int (*fgetattr) (const char *, struct stat *, struct fuse_file_info *); - int (*lock) (const char *, struct fuse_file_info *, int cmd, struct flock *); - int (*utimens) (const char *, const struct timespec tv[2]); - int (*bmap) (const char *, size_t blocksize, uint64_t *idx); - unsigned int flag_nullpath_ok:1; - unsigned int flag_nopath:1; - unsigned int flag_utime_omit_ok:1; - unsigned int flag_reserved:29; - int (*ioctl) (const char *, int cmd, void *arg, struct fuse_file_info *, unsigned int flags, void *data); - int (*poll) (const char *, struct fuse_file_info *, struct fuse_pollhandle *ph, unsigned *reventsp); - int (*write_buf) (const char *, struct fuse_bufvec *buf, off_t off, struct fuse_file_info *); - int (*read_buf) (const char *, struct fuse_bufvec **bufp, size_t size, off_t off, struct fuse_file_info *); - int (*flock) (const char *, struct fuse_file_info *, int op); - int (*fallocate) (const char *, int, off_t, off_t, struct fuse_file_info *); -}; - -struct fuse_lowlevel_ops { - void (*init) (void *userdata, struct fuse_conn_info *conn); - void (*destroy) (void *userdata); - void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name); - void (*forget) (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup); - void (*getattr) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi); - void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr, int to_set, struct fuse_file_info *fi); - void (*readlink) (fuse_req_t req, fuse_ino_t ino); - void (*mknod) (fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode, dev_t rdev); - void (*mkdir) (fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode); - void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name); - void (*rmdir) (fuse_req_t req, fuse_ino_t parent, const char *name); - void (*symlink) (fuse_req_t req, const char *link, fuse_ino_t parent, const char *name); - void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name, fuse_ino_t newparent, const char *newname); - void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent, const char *newname); - void (*open) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi); - void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi); - void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf, size_t size, off_t off, struct fuse_file_info *fi); - void (*flush) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi); - void (*release) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi); - void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync, struct fuse_file_info *fi); - void (*opendir) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi); - void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi); - void (*releasedir) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi); - void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync, struct fuse_file_info *fi); - void (*statfs) (fuse_req_t req, fuse_ino_t ino); - void (*setxattr) (fuse_req_t req, fuse_ino_t ino, const char *name, const char *value, size_t size, int flags); - void (*getxattr) (fuse_req_t req, fuse_ino_t ino, const char *name, size_t size); - void (*listxattr) (fuse_req_t req, fuse_ino_t ino, size_t size); - void (*removexattr) (fuse_req_t req, fuse_ino_t ino, const char *name); - void (*access) (fuse_req_t req, fuse_ino_t ino, int mask); - void (*create) (fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode, struct fuse_file_info *fi); - void (*getlk) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock); - void (*setlk) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock, int sleep); - void (*bmap) (fuse_req_t req, fuse_ino_t ino, size_t blocksize, uint64_t idx); - void (*ioctl) (fuse_req_t req, fuse_ino_t ino, int cmd, void *arg, struct fuse_file_info *fi, unsigned flags, const void *in_buf, size_t in_bufsz, size_t out_bufsz); - void (*poll) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct fuse_pollhandle *ph); - void (*write_buf) (fuse_req_t req, fuse_ino_t ino, struct fuse_bufvec *bufv, off_t off, struct fuse_file_info *fi); - void (*retrieve_reply) (fuse_req_t req, void *cookie, fuse_ino_t ino, off_t offset, struct fuse_bufvec *bufv); - void (*forget_multi) (fuse_req_t req, size_t count, struct fuse_forget_data *forgets); - void (*flock) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, int op); - void (*fallocate) (fuse_req_t req, fuse_ino_t ino, int mode, off_t offset, off_t length, struct fuse_file_info *fi); -}; - -#else /* !ENABLE_DLOPEN */ - -#define LOAD_LIBRARY -#define LOAD_SYMBOL(x) -#define DL(x) -#define CLOSE_LIBRARY - -#endif /* !ENABLE_DLOPEN */ - -#endif /* SQFS_DLOPEN_H */ - diff --git a/src/patches/squashfuse_dlopen.patch b/src/patches/squashfuse_dlopen.patch deleted file mode 100644 index 59e1e6e6..00000000 --- a/src/patches/squashfuse_dlopen.patch +++ /dev/null @@ -1,640 +0,0 @@ ---- a/Makefile.am -+++ b/Makefile.am -@@ -1,6 +1,7 @@ - COMPRESSION_LIBS = $(ZLIB_LIBS) $(XZ_LIBS) $(LZO_LIBS) $(LZ4_LIBS) - - ACLOCAL_AMFLAGS = -I m4 --install -+AM_CFLAGS = -fno-strict-aliasing -DENABLE_DLOPEN - - # Suppress AppleDouble - if MAKE_EXPORT -@@ -19,13 +20,13 @@ - # Main library: libsquashfuse - libsquashfuse_la_SOURCES = swap.c cache.c table.c dir.c file.c fs.c \ - decompress.c xattr.c hash.c stack.c traverse.c util.c \ -- nonstd-pread.c nonstd-stat.c \ -+ nonstd-pread.c nonstd-stat.c squashfuse_dlopen.c \ - squashfs_fs.h common.h nonstd-internal.h nonstd.h swap.h cache.h table.h \ - dir.h file.h decompress.h xattr.h squashfuse.h hash.h stack.h traverse.h \ -- util.h fs.h -+ util.h fs.h squashfuse_dlopen.h - libsquashfuse_la_CPPFLAGS = $(ZLIB_CPPFLAGS) $(XZ_CPPFLAGS) $(LZO_CPPFLAGS) \ - $(LZ4_CPPFLAGS) --libsquashfuse_la_LIBADD = -+libsquashfuse_la_LIBADD = -ldl - - # Helper for FUSE clients: libfuseprivate - libfuseprivate_la_SOURCES = fuseprivate.c nonstd-makedev.c nonstd-enoattr.c \ ---- a/fuseprivate.c -+++ b/fuseprivate.c -@@ -94,15 +94,17 @@ - } - - void sqfs_usage(char *progname, bool fuse_usage) { -+ LOAD_SYMBOL(int,fuse_opt_add_arg,(struct fuse_args *args, const char *arg)); -+ LOAD_SYMBOL(int,fuse_parse_cmdline,(struct fuse_args *args, char **mountpoint, int *multithreaded, int *foreground)); - fprintf(stderr, "%s (c) 2012 Dave Vasilevsky\n\n", PACKAGE_STRING); - fprintf(stderr, "Usage: %s [options] ARCHIVE MOUNTPOINT\n", - progname ? progname : PACKAGE_NAME); - if (fuse_usage) { - struct fuse_args args = FUSE_ARGS_INIT(0, NULL); -- fuse_opt_add_arg(&args, ""); /* progname */ -- fuse_opt_add_arg(&args, "-ho"); -+ DL(fuse_opt_add_arg)(&args, ""); /* progname */ -+ DL(fuse_opt_add_arg)(&args, "-ho"); - fprintf(stderr, "\n"); -- fuse_parse_cmdline(&args, NULL, NULL, NULL); -+ DL(fuse_parse_cmdline)(&args, NULL, NULL, NULL); - } - exit(-2); - } ---- a/fuseprivate.h -+++ b/fuseprivate.h -@@ -27,7 +27,10 @@ - - #include "squashfuse.h" - --#include -+#include "squashfuse_dlopen.h" -+#ifndef ENABLE_DLOPEN -+# include -+#endif - - #include - ---- a/hl.c -+++ b/hl.c -@@ -33,6 +33,7 @@ - #include - #include - -+int have_libloaded = 0; - - typedef struct sqfs_hl sqfs_hl; - struct sqfs_hl { -@@ -42,9 +43,10 @@ - - static sqfs_err sqfs_hl_lookup(sqfs **fs, sqfs_inode *inode, - const char *path) { -+ LOAD_SYMBOL(struct fuse_context *,fuse_get_context,(void)); - bool found; - -- sqfs_hl *hl = fuse_get_context()->private_data; -+ sqfs_hl *hl = DL(fuse_get_context)()->private_data; - *fs = &hl->fs; - if (inode) - *inode = hl->root; /* copy */ -@@ -67,7 +69,8 @@ - } - - static void *sqfs_hl_op_init(struct fuse_conn_info *conn) { -- return fuse_get_context()->private_data; -+ LOAD_SYMBOL(struct fuse_context *,fuse_get_context,(void)); -+ return DL(fuse_get_context)()->private_data; - } - - static int sqfs_hl_op_getattr(const char *path, struct stat *st) { -@@ -264,7 +267,16 @@ - return NULL; - } - -+#ifdef ENABLE_DLOPEN -+#define fuse_main(argc, argv, op, user_data) \ -+ DL(fuse_main_real)(argc, argv, op, sizeof(*(op)), user_data) -+#endif -+ - int main(int argc, char *argv[]) { -+ LOAD_SYMBOL(int,fuse_opt_parse,(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)); -+ LOAD_SYMBOL(int,fuse_opt_add_arg,(struct fuse_args *args, const char *arg)); -+ LOAD_SYMBOL(int,fuse_main_real,(int argc, char *argv[], const struct fuse_operations *op, size_t op_size, void *user_data)); /* fuse_main */ -+ LOAD_SYMBOL(void,fuse_opt_free_args,(struct fuse_args *args)); - struct fuse_args args; - sqfs_opts opts; - sqfs_hl *hl; -@@ -299,7 +311,7 @@ - opts.image = NULL; - opts.mountpoint = 0; - opts.offset = 0; -- if (fuse_opt_parse(&args, &opts, fuse_opts, sqfs_opt_proc) == -1) -+ if (DL(fuse_opt_parse)(&args, &opts, fuse_opts, sqfs_opt_proc) == -1) - sqfs_usage(argv[0], true); - if (!opts.image) - sqfs_usage(argv[0], true); -@@ -308,8 +320,9 @@ - if (!hl) - return -1; - -- fuse_opt_add_arg(&args, "-s"); /* single threaded */ -+ DL(fuse_opt_add_arg)(&args, "-s"); /* single threaded */ - ret = fuse_main(args.argc, args.argv, &sqfs_hl_ops, hl); -- fuse_opt_free_args(&args); -+ DL(fuse_opt_free_args)(&args); -+ CLOSE_LIBRARY; - return ret; - } ---- a/ll.h -+++ b/ll.h -@@ -27,7 +27,10 @@ - - #include "squashfuse.h" - --#include -+#include "squashfuse_dlopen.h" -+#ifndef ENABLE_DLOPEN -+# include -+#endif - - typedef struct sqfs_ll sqfs_ll; - struct sqfs_ll { ---- a/ll_inode.c -+++ b/ll_inode.c -@@ -348,12 +348,14 @@ - - - sqfs_err sqfs_ll_iget(fuse_req_t req, sqfs_ll_i *lli, fuse_ino_t i) { -+ LOAD_SYMBOL(void *,fuse_req_userdata,(fuse_req_t req)); -+ LOAD_SYMBOL(int,fuse_reply_err,(fuse_req_t req, int err)); - sqfs_err err = SQFS_OK; -- lli->ll = fuse_req_userdata(req); -+ lli->ll = DL(fuse_req_userdata)(req); - if (i != SQFS_FUSE_INODE_NONE) { - err = sqfs_ll_inode(lli->ll, &lli->inode, i); - if (err) -- fuse_reply_err(req, ENOENT); -+ DL(fuse_reply_err)(req, ENOENT); - } - return err; - } ---- a/nonstd-daemon.c -+++ b/nonstd-daemon.c -@@ -28,11 +28,16 @@ - #include "nonstd-internal.h" - - #include --#include -+ -+#include "squashfuse_dlopen.h" -+#ifndef ENABLE_DLOPEN -+# include -+#endif - - int sqfs_ll_daemonize(int fg) { - #if HAVE_DECL_FUSE_DAEMONIZE -- return fuse_daemonize(fg); -+ LOAD_SYMBOL(int,fuse_daemonize,(int foreground)); -+ return DL(fuse_daemonize)(fg); - #else - return daemon(0,0); - #endif ---- a/ll.c -+++ b/ll.c -@@ -38,37 +38,41 @@ - - static void sqfs_ll_op_getattr(fuse_req_t req, fuse_ino_t ino, - struct fuse_file_info *fi) { -+ LOAD_SYMBOL(int,fuse_reply_err,(fuse_req_t req, int err)); -+ LOAD_SYMBOL(int,fuse_reply_attr,(fuse_req_t req, const struct stat *attr, double attr_timeout)); - sqfs_ll_i lli; - struct stat st; - if (sqfs_ll_iget(req, &lli, ino)) - return; - - if (sqfs_stat(&lli.ll->fs, &lli.inode, &st)) { -- fuse_reply_err(req, ENOENT); -+ DL(fuse_reply_err)(req, ENOENT); - } else { - st.st_ino = ino; -- fuse_reply_attr(req, &st, SQFS_TIMEOUT); -+ DL(fuse_reply_attr)(req, &st, SQFS_TIMEOUT); - } - } - - static void sqfs_ll_op_opendir(fuse_req_t req, fuse_ino_t ino, - struct fuse_file_info *fi) { -+ LOAD_SYMBOL(int,fuse_reply_err,(fuse_req_t req, int err)); -+ LOAD_SYMBOL(int,fuse_reply_open,(fuse_req_t req, const struct fuse_file_info *fi)); - sqfs_ll_i *lli; - - fi->fh = (intptr_t)NULL; - - lli = malloc(sizeof(*lli)); - if (!lli) { -- fuse_reply_err(req, ENOMEM); -+ DL(fuse_reply_err)(req, ENOMEM); - return; - } - - if (sqfs_ll_iget(req, lli, ino) == SQFS_OK) { - if (!S_ISDIR(lli->inode.base.mode)) { -- fuse_reply_err(req, ENOTDIR); -+ DL(fuse_reply_err)(req, ENOTDIR); - } else { - fi->fh = (intptr_t)lli; -- fuse_reply_open(req, fi); -+ DL(fuse_reply_open)(req, fi); - return; - } - } -@@ -77,28 +81,35 @@ - - static void sqfs_ll_op_create(fuse_req_t req, fuse_ino_t parent, const char *name, - mode_t mode, struct fuse_file_info *fi) { -- fuse_reply_err(req, EROFS); -+ LOAD_SYMBOL(int,fuse_reply_err,(fuse_req_t req, int err)); -+ DL(fuse_reply_err)(req, EROFS); - } - - static void sqfs_ll_op_releasedir(fuse_req_t req, fuse_ino_t ino, - struct fuse_file_info *fi) { - free((sqfs_ll_i*)(intptr_t)fi->fh); -- fuse_reply_err(req, 0); /* yes, this is necessary */ -+ LOAD_SYMBOL(int,fuse_reply_err,(fuse_req_t req, int err)); -+ DL(fuse_reply_err)(req, 0); /* yes, this is necessary */ - } - - static size_t sqfs_ll_add_direntry(fuse_req_t req, char *buf, size_t bufsize, - const char *name, const struct stat *st, off_t off) { - #if HAVE_DECL_FUSE_ADD_DIRENTRY -- return fuse_add_direntry(req, buf, bufsize, name, st, off); -+ LOAD_SYMBOL(size_t,fuse_add_direntry,(fuse_req_t req, char *buf, size_t bufsize, const char *name, const struct stat *stbuf, off_t off)); -+ return DL(fuse_add_direntry)(req, buf, bufsize, name, st, off); - #else -- size_t esize = fuse_dirent_size(strlen(name)); -+ LOAD_SYMBOL(size_t,fuse_dirent_size(size_t namelen)); -+ LOAD_SYMBOL(char *,fuse_add_dirent,(char *buf, const char *name, const struct stat *stbuf, off_t off)); -+ size_t esize = DL(fuse_dirent_size)(strlen(name)); - if (bufsize >= esize) -- fuse_add_dirent(buf, name, st, off); -+ DL(fuse_add_dirent)(buf, name, st, off); - return esize; - #endif - } - static void sqfs_ll_op_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, - off_t off, struct fuse_file_info *fi) { -+ LOAD_SYMBOL(int,fuse_reply_err,(fuse_req_t req, int err)); -+ LOAD_SYMBOL(int,fuse_reply_buf,(fuse_req_t req, const char *buf, size_t size)); - sqfs_err sqerr; - sqfs_dir dir; - sqfs_name namebuf; -@@ -135,14 +146,16 @@ - } - - if (err) -- fuse_reply_err(req, err); -+ DL(fuse_reply_err)(req, err); - else -- fuse_reply_buf(req, buf, bufpos - buf); -+ DL(fuse_reply_buf)(req, buf, bufpos - buf); - free(buf); - } - - static void sqfs_ll_op_lookup(fuse_req_t req, fuse_ino_t parent, - const char *name) { -+ LOAD_SYMBOL(int,fuse_reply_err,(fuse_req_t req, int err)); -+ LOAD_SYMBOL(int,fuse_reply_entry,(fuse_req_t req, const struct fuse_entry_param *e)); - sqfs_ll_i lli; - sqfs_err sqerr; - sqfs_name namebuf; -@@ -154,7 +167,7 @@ - return; - - if (!S_ISDIR(lli.inode.base.mode)) { -- fuse_reply_err(req, ENOTDIR); -+ DL(fuse_reply_err)(req, ENOTDIR); - return; - } - -@@ -162,55 +175,58 @@ - sqerr = sqfs_dir_lookup(&lli.ll->fs, &lli.inode, name, strlen(name), &entry, - &found); - if (sqerr) { -- fuse_reply_err(req, EIO); -+ DL(fuse_reply_err)(req, EIO); - return; - } - if (!found) { -- fuse_reply_err(req, ENOENT); -+ DL(fuse_reply_err)(req, ENOENT); - return; - } - - if (sqfs_inode_get(&lli.ll->fs, &inode, sqfs_dentry_inode(&entry))) { -- fuse_reply_err(req, ENOENT); -+ DL(fuse_reply_err)(req, ENOENT); - } else { - struct fuse_entry_param fentry; - memset(&fentry, 0, sizeof(fentry)); - if (sqfs_stat(&lli.ll->fs, &inode, &fentry.attr)) { -- fuse_reply_err(req, EIO); -+ DL(fuse_reply_err)(req, EIO); - } else { - fentry.attr_timeout = fentry.entry_timeout = SQFS_TIMEOUT; - fentry.ino = lli.ll->ino_register(lli.ll, &entry); - fentry.attr.st_ino = fentry.ino; -- fuse_reply_entry(req, &fentry); -+ DL(fuse_reply_entry)(req, &fentry); - } - } - } - - static void sqfs_ll_op_open(fuse_req_t req, fuse_ino_t ino, - struct fuse_file_info *fi) { -+ LOAD_SYMBOL(int,fuse_reply_err,(fuse_req_t req, int err)); -+ LOAD_SYMBOL(int,fuse_reply_open,(fuse_req_t req, const struct fuse_file_info *fi)); -+ LOAD_SYMBOL(void *,fuse_req_userdata,(fuse_req_t req)); - sqfs_inode *inode; - sqfs_ll *ll; - - if (fi->flags & (O_WRONLY | O_RDWR)) { -- fuse_reply_err(req, EROFS); -+ DL(fuse_reply_err)(req, EROFS); - return; - } - - inode = malloc(sizeof(sqfs_inode)); - if (!inode) { -- fuse_reply_err(req, ENOMEM); -+ DL(fuse_reply_err)(req, ENOMEM); - return; - } - -- ll = fuse_req_userdata(req); -+ ll = DL(fuse_req_userdata)(req); - if (sqfs_ll_inode(ll, inode, ino)) { -- fuse_reply_err(req, ENOENT); -+ DL(fuse_reply_err)(req, ENOENT); - } else if (!S_ISREG(inode->base.mode)) { -- fuse_reply_err(req, EISDIR); -+ DL(fuse_reply_err)(req, EISDIR); - } else { - fi->fh = (intptr_t)inode; - fi->keep_cache = 1; -- fuse_reply_open(req, fi); -+ DL(fuse_reply_open)(req, fi); - return; - } - free(inode); -@@ -218,37 +234,43 @@ - - static void sqfs_ll_op_release(fuse_req_t req, fuse_ino_t ino, - struct fuse_file_info *fi) { -+ LOAD_SYMBOL(int,fuse_reply_err,(fuse_req_t req, int err)); - free((sqfs_inode*)(intptr_t)fi->fh); - fi->fh = 0; -- fuse_reply_err(req, 0); -+ DL(fuse_reply_err)(req, 0); - } - - static void sqfs_ll_op_read(fuse_req_t req, fuse_ino_t ino, - size_t size, off_t off, struct fuse_file_info *fi) { -- sqfs_ll *ll = fuse_req_userdata(req); -+ LOAD_SYMBOL(void *,fuse_req_userdata,(fuse_req_t req)); -+ LOAD_SYMBOL(int,fuse_reply_err,(fuse_req_t req, int err)); -+ LOAD_SYMBOL(int,fuse_reply_buf,(fuse_req_t req, const char *buf, size_t size)); -+ sqfs_ll *ll = DL(fuse_req_userdata)(req); - sqfs_inode *inode = (sqfs_inode*)(intptr_t)fi->fh; - sqfs_err err = SQFS_OK; - - off_t osize; - char *buf = malloc(size); - if (!buf) { -- fuse_reply_err(req, ENOMEM); -+ DL(fuse_reply_err)(req, ENOMEM); - return; - } - - osize = size; - err = sqfs_read_range(&ll->fs, inode, off, &osize, buf); - if (err) { -- fuse_reply_err(req, EIO); -+ DL(fuse_reply_err)(req, EIO); - } else if (osize == 0) { /* EOF */ -- fuse_reply_buf(req, NULL, 0); -+ DL(fuse_reply_buf)(req, NULL, 0); - } else { -- fuse_reply_buf(req, buf, osize); -+ DL(fuse_reply_buf)(req, buf, osize); - } - free(buf); - } - - static void sqfs_ll_op_readlink(fuse_req_t req, fuse_ino_t ino) { -+ LOAD_SYMBOL(int,fuse_reply_err,(fuse_req_t req, int err)); -+ LOAD_SYMBOL(int,fuse_reply_readlink,(fuse_req_t req, const char *link)); - char *dst; - size_t size; - sqfs_ll_i lli; -@@ -256,21 +278,24 @@ - return; - - if (!S_ISLNK(lli.inode.base.mode)) { -- fuse_reply_err(req, EINVAL); -+ DL(fuse_reply_err)(req, EINVAL); - } else if (sqfs_readlink(&lli.ll->fs, &lli.inode, NULL, &size)) { -- fuse_reply_err(req, EIO); -+ DL(fuse_reply_err)(req, EIO); - } else if (!(dst = malloc(size + 1))) { -- fuse_reply_err(req, ENOMEM); -+ DL(fuse_reply_err)(req, ENOMEM); - } else if (sqfs_readlink(&lli.ll->fs, &lli.inode, dst, &size)) { -- fuse_reply_err(req, EIO); -+ DL(fuse_reply_err)(req, EIO); - free(dst); - } else { -- fuse_reply_readlink(req, dst); -+ DL(fuse_reply_readlink)(req, dst); - free(dst); - } - } - - static void sqfs_ll_op_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size) { -+ LOAD_SYMBOL(int,fuse_reply_err,(fuse_req_t req, int err)); -+ LOAD_SYMBOL(int,fuse_reply_xattr,(fuse_req_t req, size_t count)); -+ LOAD_SYMBOL(int,fuse_reply_buf,(fuse_req_t req, const char *buf, size_t size)); - sqfs_ll_i lli; - char *buf; - int ferr; -@@ -280,17 +305,17 @@ - - buf = NULL; - if (size && !(buf = malloc(size))) { -- fuse_reply_err(req, ENOMEM); -+ DL(fuse_reply_err)(req, ENOMEM); - return; - } - - ferr = sqfs_listxattr(&lli.ll->fs, &lli.inode, buf, &size); - if (ferr) { -- fuse_reply_err(req, ferr); -+ DL(fuse_reply_err)(req, ferr); - } else if (buf) { -- fuse_reply_buf(req, buf, size); -+ DL(fuse_reply_buf)(req, buf, size); - } else { -- fuse_reply_xattr(req, size); -+ DL(fuse_reply_xattr)(req, size); - } - free(buf); - } -@@ -301,13 +326,16 @@ - , uint32_t position - #endif - ) { -+ LOAD_SYMBOL(int,fuse_reply_err,(fuse_req_t req, int err)); -+ LOAD_SYMBOL(int,fuse_reply_xattr,(fuse_req_t req, size_t count)); -+ LOAD_SYMBOL(int,fuse_reply_buf,(fuse_req_t req, const char *buf, size_t size)); - sqfs_ll_i lli; - char *buf = NULL; - size_t real = size; - - #ifdef FUSE_XATTR_POSITION - if (position != 0) { /* We don't support resource forks */ -- fuse_reply_err(req, EINVAL); -+ DL(fuse_reply_err)(req, EINVAL); - return; - } - #endif -@@ -316,26 +344,27 @@ - return; - - if (!(buf = malloc(size))) -- fuse_reply_err(req, ENOMEM); -+ DL(fuse_reply_err)(req, ENOMEM); - else if (sqfs_xattr_lookup(&lli.ll->fs, &lli.inode, name, buf, &real)) -- fuse_reply_err(req, EIO); -+ DL(fuse_reply_err)(req, EIO); - else if (real == 0) -- fuse_reply_err(req, sqfs_enoattr()); -+ DL(fuse_reply_err)(req, sqfs_enoattr()); - else if (size == 0) -- fuse_reply_xattr(req, real); -+ DL(fuse_reply_xattr)(req, real); - else if (size < real) -- fuse_reply_err(req, ERANGE); -+ DL(fuse_reply_err)(req, ERANGE); - else -- fuse_reply_buf(req, buf, real); -+ DL(fuse_reply_buf)(req, buf, real); - free(buf); - } - - static void sqfs_ll_op_forget(fuse_req_t req, fuse_ino_t ino, - unsigned long nlookup) { -+ LOAD_SYMBOL(void,fuse_reply_none,(fuse_req_t req)); - sqfs_ll_i lli; - sqfs_ll_iget(req, &lli, SQFS_FUSE_INODE_NONE); - lli.ll->ino_forget(lli.ll, ino, nlookup); -- fuse_reply_none(req); -+ DL(fuse_reply_none)(req); - } - - -@@ -348,23 +377,27 @@ - - static sqfs_err sqfs_ll_mount(sqfs_ll_chan *ch, const char *mountpoint, - struct fuse_args *args) { -+ LOAD_SYMBOL(struct fuse_chan *,fuse_mount,(const char *mountpoint, struct fuse_args *args)); - #ifdef HAVE_NEW_FUSE_UNMOUNT -- ch->ch = fuse_mount(mountpoint, args); -+ ch->ch = DL(fuse_mount)(mountpoint, args); - #else -- ch->fd = fuse_mount(mountpoint, args); -+ LOAD_SYMBOL(struct fuse_chan *,fuse_kern_chan_new,(int fd)); -+ ch->fd = DL(fuse_mount)(mountpoint, args); - if (ch->fd == -1) - return SQFS_ERR; -- ch->ch = fuse_kern_chan_new(ch->fd); -+ ch->ch = DL(fuse_kern_chan_new)(ch->fd); - #endif - return ch->ch ? SQFS_OK : SQFS_ERR; - } - - static void sqfs_ll_unmount(sqfs_ll_chan *ch, const char *mountpoint) { - #ifdef HAVE_NEW_FUSE_UNMOUNT -- fuse_unmount(mountpoint, ch->ch); -+ LOAD_SYMBOL(void,fuse_unmount,(const char *mountpoint, struct fuse_chan *ch)); -+ DL(fuse_unmount)(mountpoint, ch->ch); - #else -+ LOAD_SYMBOL(void,fuse_unmount,(const char *mountpoint)); - close(ch->fd); -- fuse_unmount(mountpoint); -+ DL(fuse_unmount)(mountpoint); - #endif - } - -@@ -391,6 +424,19 @@ - } - - int fusefs_main(int argc, char *argv[], void (*mounted) (void)) { -+ LOAD_SYMBOL(int,fuse_opt_parse,(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)); -+ LOAD_SYMBOL(int,fuse_parse_cmdline,(struct fuse_args *args, char **mountpoint, int *multithreaded, int *foreground)); -+ LOAD_SYMBOL(struct fuse_session *,fuse_lowlevel_new,(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata)); -+ LOAD_SYMBOL(int,fuse_set_signal_handlers,(struct fuse_session *se)); -+ LOAD_SYMBOL(void,fuse_session_add_chan,(struct fuse_session *se, struct fuse_chan *ch)); -+ LOAD_SYMBOL(int,fuse_session_loop,(struct fuse_session *se)); -+ LOAD_SYMBOL(void,fuse_remove_signal_handlers,(struct fuse_session *se)); -+#if HAVE_DECL_FUSE_SESSION_REMOVE_CHAN -+ LOAD_SYMBOL(void,fuse_session_remove_chan,(struct fuse_chan *ch)); -+#endif -+ LOAD_SYMBOL(void,fuse_session_destroy,(struct fuse_session *se)); -+ LOAD_SYMBOL(void,fuse_opt_free_args,(struct fuse_args *args)); -+ - struct fuse_args args; - sqfs_opts opts; - -@@ -429,10 +475,10 @@ - opts.image = NULL; - opts.mountpoint = 0; - opts.offset = 0; -- if (fuse_opt_parse(&args, &opts, fuse_opts, sqfs_opt_proc) == -1) -+ if (DL(fuse_opt_parse)(&args, &opts, fuse_opts, sqfs_opt_proc) == -1) - sqfs_usage(argv[0], true); - -- if (fuse_parse_cmdline(&args, &mountpoint, &mt, &fg) == -1) -+ if (DL(fuse_parse_cmdline)(&args, &mountpoint, &mt, &fg) == -1) - sqfs_usage(argv[0], true); - if (mountpoint == NULL) - sqfs_usage(argv[0], true); -@@ -445,33 +491,34 @@ - sqfs_ll_chan ch; - err = -1; - if (sqfs_ll_mount(&ch, mountpoint, &args) == SQFS_OK) { -- struct fuse_session *se = fuse_lowlevel_new(&args, -+ struct fuse_session *se = DL(fuse_lowlevel_new)(&args, - &sqfs_ll_ops, sizeof(sqfs_ll_ops), ll); - if (se != NULL) { - if (sqfs_ll_daemonize(fg) != -1) { -- if (fuse_set_signal_handlers(se) != -1) { -- fuse_session_add_chan(se, ch.ch); -+ if (DL(fuse_set_signal_handlers)(se) != -1) { -+ DL(fuse_session_add_chan)(se, ch.ch); - if (mounted) - mounted (); - /* FIXME: multithreading */ -- err = fuse_session_loop(se); -- fuse_remove_signal_handlers(se); -+ err = DL(fuse_session_loop)(se); -+ DL(fuse_remove_signal_handlers)(se); - #if HAVE_DECL_FUSE_SESSION_REMOVE_CHAN -- fuse_session_remove_chan(ch.ch); -+ DL(fuse_session_remove_chan)(ch.ch); - #endif - } - } -- fuse_session_destroy(se); -+ DL(fuse_session_destroy)(se); - } - sqfs_ll_destroy(ll); - sqfs_ll_unmount(&ch, mountpoint); - } - } -- fuse_opt_free_args(&args); -+ DL(fuse_opt_free_args)(&args); - if (mounted) - rmdir (mountpoint); - free(ll); - free(mountpoint); -+ CLOSE_LIBRARY; - - return -err; - } diff --git a/tests/data/Hello_World-x86_64.gzip.AppImage b/tests/data/Hello_World-x86_64.gzip.AppImage new file mode 100755 index 00000000..de453811 Binary files /dev/null and b/tests/data/Hello_World-x86_64.gzip.AppImage differ diff --git a/tests/data/Hello_World-x86_64.xz.AppImage b/tests/data/Hello_World-x86_64.xz.AppImage new file mode 100755 index 00000000..af7bc13d Binary files /dev/null and b/tests/data/Hello_World-x86_64.xz.AppImage differ diff --git a/tests/data/Hello_World-x86_64.zstd.AppImage b/tests/data/Hello_World-x86_64.zstd.AppImage new file mode 100755 index 00000000..2b957723 Binary files /dev/null and b/tests/data/Hello_World-x86_64.zstd.AppImage differ diff --git a/tests/libappimage/desktop_integration/CMakeLists.txt b/tests/libappimage/desktop_integration/CMakeLists.txt index a9cc3f0a..c6986ada 100644 --- a/tests/libappimage/desktop_integration/CMakeLists.txt +++ b/tests/libappimage/desktop_integration/CMakeLists.txt @@ -28,13 +28,11 @@ target_include_directories( target_link_libraries(TestDesktopIntegration PRIVATE temporarydirectory PRIVATE libappimage_shared - PRIVATE libsquashfuse PRIVATE libarchive - PRIVATE xz - PRIVATE libzlib PRIVATE XdgUtils::DesktopEntry PRIVATE XdgUtils::BaseDir - # Builds using old glib versions requiered that the glib to be initialized, this initialization is performed + PRIVATE libsquashfuse + # Builds using old glib versions required that the glib to be initialized, this initialization is performed # statically once glib is loaded. PRIVATE libglib PUBLIC dl