mirror of
https://github.com/feather-wallet/feather.git
synced 2024-12-23 03:59:29 +00:00
depends: type2 static appimage runtimes
This commit is contained in:
parent
d3ec0946ea
commit
408276e409
21 changed files with 120 additions and 2417 deletions
|
@ -39,7 +39,7 @@ chmod +x "$APPDIR/AppRun"
|
||||||
|
|
||||||
find feather.AppDir/ -exec touch -h -a -m -t 202101010100.00 {} \;
|
find feather.AppDir/ -exec touch -h -a -m -t 202101010100.00 {} \;
|
||||||
|
|
||||||
mksquashfs feather.AppDir feather.squashfs -info -root-owned -no-xattrs -noappend -fstime 0
|
mksquashfs feather.AppDir feather.squashfs -comp zstd -info -root-owned -no-xattrs -noappend -fstime 0
|
||||||
# mksquashfs writes a timestamp to the header
|
# mksquashfs writes a timestamp to the header
|
||||||
printf '\x00\x00\x00\x00' | dd conv=notrunc of=feather.squashfs bs=1 seek=$((0x8))
|
printf '\x00\x00\x00\x00' | dd conv=notrunc of=feather.squashfs bs=1 seek=$((0x8))
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
# TODO: we're not actually using the sources downloaded here. Perhaps host patches in a github repo.
|
|
||||||
package=appimage_runtime
|
package=appimage_runtime
|
||||||
$(package)_version=13
|
$(package)_version=c1ea7509bc179a05d907baca64f41875662f35f2
|
||||||
$(package)_download_path=https://github.com/AppImage/AppImageKit/archive/refs/tags/
|
$(package)_download_path=https://github.com/AppImage/type2-runtime/archive/
|
||||||
$(package)_file_name=$($(package)_version).tar.gz
|
$(package)_file_name=$($(package)_version).tar.gz
|
||||||
$(package)_sha256_hash=51b837c78dd99ecc1cf3dd283f4a98a1be665b01457da0edc1ff736d12974b1a
|
$(package)_sha256_hash=a7906c7d1610eacb6c67a16c554fac8875b05424fea49e291311c3e5db2237a3
|
||||||
$(package)_dependencies=libsquashfuse libappimage liblzma
|
$(package)_dependencies=libsquashfuse zstd
|
||||||
$(package)_patches=CMakeLists.txt runtime.c notify.c
|
$(package)_patches=depends-fix.patch
|
||||||
|
|
||||||
define $(package)_preprocess_cmds
|
define $(package)_preprocess_cmds
|
||||||
cp -v $($(package)_patch_dir)/* .
|
patch -p1 < $($(package)_patch_dir)/depends-fix.patch
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_config_cmds
|
|
||||||
$($(package)_cmake) -DCMAKE_INSTALL_PREFIX=$(host_prefix) -DHOST=$(host) -DGLIBC_DYNAMIC_LINKER=$(GLIBC_DYNAMIC_LINKER) .
|
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define $(package)_build_cmds
|
define $(package)_build_cmds
|
||||||
$(MAKE)
|
cd src/runtime && \
|
||||||
|
export host_prefix="$(host_prefix)" && \
|
||||||
|
$(MAKE) runtime-fuse2 -e CC=$($(package)_cc) LDLAGS="$($(package)_ldflags)" && \
|
||||||
|
"${HOST}-strip" runtime-fuse2 && \
|
||||||
|
echo -ne 'AI\x02' | dd of=runtime-fuse2 bs=1 count=3 seek=8 conv=notrunc
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define $(package)_stage_cmds
|
define $(package)_stage_cmds
|
||||||
cp -a runtime $($(package)_staging_prefix_dir)/runtime
|
cd src/runtime && \
|
||||||
|
cp -a runtime-fuse2 $($(package)_staging_prefix_dir)/runtime
|
||||||
endef
|
endef
|
|
@ -1,25 +0,0 @@
|
||||||
package=libappimage
|
|
||||||
$(package)_version=v0.1.x-legacy
|
|
||||||
$(package)_download_path=https://github.com/AppImageCommunity/libappimage/archive/refs/heads/
|
|
||||||
$(package)_file_name=$($(package)_version).tar.gz
|
|
||||||
$(package)_sha256_hash=fef3962bfb75f986f24c530a6230e95b8c79e46da3dd581543f1b615d45e7389
|
|
||||||
$(package)_dependencies=liblzma libfuse libarchive
|
|
||||||
$(package)_patches=no-unneeded-deps.patch
|
|
||||||
|
|
||||||
define $(package)_preprocess_cmds
|
|
||||||
patch -p1 < $($(package)_patch_dir)/no-unneeded-deps.patch
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_config_cmds
|
|
||||||
$($(package)_cmake) -DCMAKE_INSTALL_PREFIX=$(host_prefix) -DCMAKE_C_COMPILER= -DUSE_SYSTEM_XZ=ON -DUSE_SYSTEM_SQUASHFUSE=ON -DUSE_SYSTEM_LIBARCHIVE=ON -DBUILD_TESTING=OFF .
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_build_cmds
|
|
||||||
$(MAKE)
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_stage_cmds
|
|
||||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install && \
|
|
||||||
cp src/libappimage_hashlib/include/hashlib.h $($(package)_staging_prefix_dir)/include/ && \
|
|
||||||
cp src/libappimage_hashlib/include/md5.h $($(package)_staging_prefix_dir)/include/
|
|
||||||
endef
|
|
|
@ -1,26 +0,0 @@
|
||||||
# Needed for libappimage
|
|
||||||
package=libarchive
|
|
||||||
$(package)_version=3.3.1
|
|
||||||
$(package)_download_path=https://www.libarchive.org/downloads/
|
|
||||||
$(package)_file_name=libarchive-$($(package)_version).tar.gz
|
|
||||||
$(package)_sha256_hash=29ca5bd1624ca5a007aa57e16080262ab4379dbf8797f5c52f7ea74a3b0424e7
|
|
||||||
|
|
||||||
define $(package)_set_vars
|
|
||||||
$(package)_config_opts=--with-pic --disable-shared --enable-static --disable-bsdtar --disable-bsdcat
|
|
||||||
$(package)_config_opts+=--disable-bsdcpio --with-zlib --without-bz2lib --without-iconv --without-lz4 --without-lzma
|
|
||||||
$(package)_config_opts+=--without-lzo2 --without-nettle --without-openssl --without-xml2 --without-expat
|
|
||||||
$(package)_config_opts+=--prefix=$(host_prefix)
|
|
||||||
$(package)_config_opts+=--libdir=$(host_prefix)/lib
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_config_cmds
|
|
||||||
$($(package)_autoconf) $($(package)_config_opts)
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_build_cmds
|
|
||||||
$(MAKE)
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_stage_cmds
|
|
||||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install
|
|
||||||
endef
|
|
|
@ -4,14 +4,15 @@ $(package)_version=2.9.9
|
||||||
$(package)_download_path=https://github.com/libfuse/libfuse/releases/download/fuse-2.9.9/
|
$(package)_download_path=https://github.com/libfuse/libfuse/releases/download/fuse-2.9.9/
|
||||||
$(package)_file_name=fuse-$($(package)_version).tar.gz
|
$(package)_file_name=fuse-$($(package)_version).tar.gz
|
||||||
$(package)_sha256_hash=d0e69d5d608cc22ff4843791ad097f554dd32540ddc9bed7638cc6fea7c1b4b5
|
$(package)_sha256_hash=d0e69d5d608cc22ff4843791ad097f554dd32540ddc9bed7638cc6fea7c1b4b5
|
||||||
$(package)_patches = arm64.patch
|
$(package)_patches = arm64.patch no-dlopen.patch
|
||||||
|
|
||||||
define $(package)_config_cmds
|
define $(package)_config_cmds
|
||||||
$($(package)_autoconf)
|
$($(package)_autoconf)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define $(package)_preprocess_cmds
|
define $(package)_preprocess_cmds
|
||||||
patch -p1 -i $($(package)_patch_dir)/arm64.patch
|
patch -p1 -i $($(package)_patch_dir)/arm64.patch && \
|
||||||
|
patch -p1 -i $($(package)_patch_dir)/no-dlopen.patch
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define $(package)_build_cmds
|
define $(package)_build_cmds
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
# Needed for libappimage
|
|
||||||
package=liblzma
|
|
||||||
$(package)_version=5.2.3
|
|
||||||
$(package)_download_path=https://netcologne.dl.sourceforge.net/project/lzmautils/
|
|
||||||
$(package)_file_name=xz-$($(package)_version).tar.gz
|
|
||||||
$(package)_sha256_hash=71928b357d0a09a12a4b4c5fafca8c31c19b0e7d3b8ebb19622e96f26dbf28cb
|
|
||||||
|
|
||||||
define $(package)_set_vars
|
|
||||||
$(package)_config_opts=--with-pic --disable-shared --enable-static --disable-xz --disable-xzdec
|
|
||||||
$(package)_config_opts+=--prefix=$(host_prefix)
|
|
||||||
$(package)_config_opts+=--libdir=$(host_prefix)/lib
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_config_cmds
|
|
||||||
$($(package)_autoconf) $($(package)_config_opts)
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_build_cmds
|
|
||||||
$(MAKE)
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_stage_cmds
|
|
||||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install
|
|
||||||
endef
|
|
|
@ -1,45 +1,28 @@
|
||||||
# Needed for libappimage
|
|
||||||
package=libsquashfuse
|
package=libsquashfuse
|
||||||
$(package)_version=1f980303b89c779eabfd0a0fdd36d6a7a311bf92
|
$(package)_version=e51978cd6bb5c4d16fae9eee43d0b258f570bb0f
|
||||||
$(package)_download_path=https://github.com/vasi/squashfuse/archive/
|
$(package)_download_path=https://github.com/vasi/squashfuse/archive/
|
||||||
$(package)_file_name=$($(package)_version).tar.gz
|
$(package)_file_name=$($(package)_version).tar.gz
|
||||||
$(package)_sha256_hash=8cef1539bd9c9efd3c407004fdd7a3bbef44102a5966b892819a275d609013a3
|
$(package)_sha256_hash=f544029ad30d8fbde4e4540c574b8cdc6d38b94df025a98d8551a9441f07d341
|
||||||
$(package)_dependencies=liblzma libfuse zlib
|
$(package)_dependencies=libfuse zstd
|
||||||
$(package)_patches=squashfuse.patch squashfuse_dlopen.patch squashfuse_dlopen.c squashfuse_dlopen.h
|
|
||||||
|
|
||||||
# for some reason, a first run may fail, but it seems just running it a second time fixes the issues
|
|
||||||
define $(package)_preprocess_cmds
|
define $(package)_preprocess_cmds
|
||||||
patch -p1 < $($(package)_patch_dir)/squashfuse.patch && \
|
./autogen.sh
|
||||||
patch -p1 < $($(package)_patch_dir)/squashfuse_dlopen.patch && \
|
|
||||||
cp -v $($(package)_patch_dir)/squashfuse_dlopen.c $($(package)_patch_dir)/squashfuse_dlopen.h . && \
|
|
||||||
libtoolize --force && \
|
|
||||||
./autogen.sh || true && \
|
|
||||||
./autogen.sh && \
|
|
||||||
sed -i "/PKG_CHECK_MODULES.*/,/,:./d" configure && \
|
|
||||||
sed -i "s/typedef off_t sqfs_off_t/typedef int64_t sqfs_off_t/g" common.h
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_set_vars
|
|
||||||
$(package)_config_opts=--disable-demo --disable-high-level --without-lzo --without-lz4
|
|
||||||
$(package)_config_opts+=--prefix=$(host_prefix)
|
|
||||||
$(package)_config_opts+=--libdir=$(host_prefix)/lib
|
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define $(package)_config_cmds
|
define $(package)_config_cmds
|
||||||
$($(package)_autoconf) $($(package)_config_opts)
|
$($(package)_autoconf) --with-zstd=$(host_prefix) --without-zlib CFLAGS=-no-pie LDFLAGS=-static
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define $(package)_build_cmds
|
define $(package)_build_cmds
|
||||||
$(MAKE) && \
|
$(MAKE)
|
||||||
ls .libs
|
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define $(package)_stage_cmds
|
define $(package)_stage_cmds
|
||||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install && \
|
$(MAKE) DESTDIR=$($(package)_staging_dir) install && \
|
||||||
mkdir -p $($(package)_staging_prefix_dir)/lib && \
|
mkdir -p $($(package)_staging_prefix_dir)/lib && \
|
||||||
mkdir -p $($(package)_staging_prefix_dir)/include && \
|
mkdir -p $($(package)_staging_prefix_dir)/include/squashfuse && \
|
||||||
cp .libs/libfuseprivate.a $($(package)_staging_prefix_dir)/lib/ && \
|
cp .libs/libfuseprivate.a $($(package)_staging_prefix_dir)/lib/ && \
|
||||||
cp .libs/libsquashfuse.a $($(package)_staging_prefix_dir)/lib/ && \
|
cp .libs/libsquashfuse.a $($(package)_staging_prefix_dir)/lib/ && \
|
||||||
cp .libs/libsquashfuse_ll.a $($(package)_staging_prefix_dir)/lib/ && \
|
cp .libs/libsquashfuse_ll.a $($(package)_staging_prefix_dir)/lib/ && \
|
||||||
find . -name "*.h" -exec cp --parents '{}' $($(package)_staging_prefix_dir)/include/ \;
|
find . -name "*.h" -exec cp --parents '{}' $($(package)_staging_prefix_dir)/include/squashfuse \;
|
||||||
endef
|
endef
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
packages := boost openssl libiconv unbound qrencode zbar sodium polyseed hidapi protobuf libusb zlib libgpg-error libgcrypt expat libzip
|
packages := boost openssl libiconv unbound qrencode zbar sodium polyseed hidapi protobuf libusb zlib libgpg-error libgcrypt expat libzip
|
||||||
native_packages := native_libxcb native_xcb_proto native_libXau native_xproto native_libxkbcommon native_qt native_protobuf
|
native_packages := native_libxcb native_xcb_proto native_libXau native_xproto native_libxkbcommon native_qt native_protobuf
|
||||||
|
|
||||||
linux_packages := eudev liblzma libarchive libfuse libsquashfuse libappimage appimage_runtime
|
linux_packages := eudev libfuse libsquashfuse zstd appimage_runtime
|
||||||
linux_native_packages =
|
linux_native_packages =
|
||||||
|
|
||||||
darwin_packages :=
|
darwin_packages :=
|
||||||
|
|
|
@ -308,23 +308,23 @@ endif
|
||||||
|
|
||||||
ifeq ($(host_os),darwin)
|
ifeq ($(host_os),darwin)
|
||||||
define $(package)_build_cmds
|
define $(package)_build_cmds
|
||||||
export LD_LIBRARY_PATH=${build_prefix}/lib/ && \
|
export LD_LIBRARY_PATH="${build_prefix}/lib/:$(QT_LIBS_LIBS)" && \
|
||||||
env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH -u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH -u LIBRARY_PATH $(MAKE)
|
env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH -u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH -u LIBRARY_PATH $(MAKE)
|
||||||
endef
|
endef
|
||||||
else ifeq ($(host_os),mingw32)
|
else ifeq ($(host_os),mingw32)
|
||||||
define $(package)_build_cmds
|
define $(package)_build_cmds
|
||||||
export LD_LIBRARY_PATH=${build_prefix}/lib/ && \
|
export LD_LIBRARY_PATH="${build_prefix}/lib/:$(QT_LIBS_LIBS)" && \
|
||||||
$(MAKE)
|
$(MAKE)
|
||||||
endef
|
endef
|
||||||
else ifneq (,$(findstring x86_64,$(HOST)))
|
else ifneq (,$(findstring x86_64,$(HOST)))
|
||||||
define $(package)_build_cmds
|
define $(package)_build_cmds
|
||||||
export LD_LIBRARY_PATH=${host_prefix}/lib/ && \
|
export LD_LIBRARY_PATH="${build_prefix}/lib/:$(QT_LIBS_LIBS)" && \
|
||||||
cmake --build . --target syncqt_build && \
|
cmake --build . --target syncqt_build && \
|
||||||
$(MAKE)
|
$(MAKE)
|
||||||
endef
|
endef
|
||||||
else
|
else
|
||||||
define $(package)_build_cmds
|
define $(package)_build_cmds
|
||||||
export LD_LIBRARY_PATH=${build_prefix}/lib/ && \
|
export LD_LIBRARY_PATH="${build_prefix}/lib/:$(QT_LIBS_LIBS)" && \
|
||||||
$(MAKE)
|
$(MAKE)
|
||||||
endef
|
endef
|
||||||
endif
|
endif
|
||||||
|
|
16
contrib/depends/packages/zstd.mk
Normal file
16
contrib/depends/packages/zstd.mk
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package=zstd
|
||||||
|
$(package)_version=1.5.4
|
||||||
|
$(package)_download_path=https://github.com/facebook/zstd/releases/download/v$($(package)_version)
|
||||||
|
$(package)_file_name=zstd-$($(package)_version).tar.gz
|
||||||
|
$(package)_sha256_hash=0f470992aedad543126d06efab344dc5f3e171893810455787d38347343a4424
|
||||||
|
|
||||||
|
define $(package)_build_cmds
|
||||||
|
$($(package)_cmake) -DCMAKE_INSTALL_PREFIX=$(host_prefix) -DHOST=$(host) -DZSTD_LEGACY_SUPPORT=OFF -B build-cmake-debug -S build/cmake && \
|
||||||
|
cd build-cmake-debug && \
|
||||||
|
$(MAKE)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define $(package)_stage_cmds
|
||||||
|
cd build-cmake-debug && \
|
||||||
|
$(MAKE) DESTDIR=$($(package)_staging_dir) install
|
||||||
|
endef
|
|
@ -1,137 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 3.2)
|
|
||||||
project(appimage_runtime)
|
|
||||||
|
|
||||||
# DISCLAIMER:
|
|
||||||
# Feather builds should be bootstrappable. For this reason we cannot use the runtime binaries provided by the AppImage devs.
|
|
||||||
# This directory exists to allow the AppImage runtime to be compiled from source using the depends build system.
|
|
||||||
# We strongly discourage other projects from copying this code, as it WILL NOT produce a standard runtime.
|
|
||||||
# The runtime produced here is not guaranteed to run on all officially supported platforms.
|
|
||||||
# You have been warned.
|
|
||||||
|
|
||||||
# TODO: Switch to https://github.com/AppImageCrafters/appimage-runtime
|
|
||||||
|
|
||||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
|
||||||
|
|
||||||
# C and C++ versions
|
|
||||||
set(CMAKE_C_STANDARD 99)
|
|
||||||
set(CMAKE_CXX_STANDARD 98)
|
|
||||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
||||||
|
|
||||||
# sanitizer support
|
|
||||||
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/sanitizers-cmake/cmake" ${CMAKE_MODULE_PATH})
|
|
||||||
|
|
||||||
set(APPIMAGEKIT_RUNTIME_ENABLE_SETPROCTITLE OFF CACHE BOOL "Useful for $TARGET_APPIMAGE; see issue #763")
|
|
||||||
|
|
||||||
# check type of current build
|
|
||||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE_UPPER)
|
|
||||||
if (BUILD_TYPE_UPPER STREQUAL DEBUG)
|
|
||||||
set(BUILD_DEBUG TRUE)
|
|
||||||
else()
|
|
||||||
set(BUILD_DEBUG FALSE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# must not include -flto in the following flags, otherwise the data sections will be stripped out
|
|
||||||
set(runtime_cflags
|
|
||||||
-std=c99 -ffunction-sections -fdata-sections
|
|
||||||
-I/feather/contrib/depends/${HOST}/include
|
|
||||||
-I/feather/contrib/depends/${HOST}/include/appimage
|
|
||||||
)
|
|
||||||
# must not include -Wl,--gc-sections in the following flags, otherwise the data sections will be stripped out
|
|
||||||
set(runtime_ldflags -s -ffunction-sections -fdata-sections -flto)
|
|
||||||
|
|
||||||
if(BUILD_DEBUG)
|
|
||||||
message(WARNING "Debug build, adding debug information")
|
|
||||||
set(runtime_cflags -g ${runtime_cflags})
|
|
||||||
else()
|
|
||||||
message(STATUS "Release build, optimizing runtime")
|
|
||||||
set(runtime_cflags -Os ${runtime_cflags})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(APPIMAGEKIT_RUNTIME_ENABLE_SETPROCTITLE)
|
|
||||||
set(runtime_cflags ${runtime_cflags} -DENABLE_SETPROCTITLE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# objcopy requires actual files for creating new sections to populate the new section
|
|
||||||
# therefore, we generate 3 suitable files containing blank bytes in the right sizes
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/16_blank_bytes
|
|
||||||
COMMAND dd if=/dev/zero bs=1 count=16 of=${CMAKE_CURRENT_BINARY_DIR}/16_blank_bytes
|
|
||||||
)
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/1024_blank_bytes
|
|
||||||
COMMAND dd if=/dev/zero bs=1 count=1024 of=${CMAKE_CURRENT_BINARY_DIR}/1024_blank_bytes
|
|
||||||
)
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/8192_blank_bytes
|
|
||||||
COMMAND dd if=/dev/zero bs=1 count=8192 of=${CMAKE_CURRENT_BINARY_DIR}/8192_blank_bytes
|
|
||||||
)
|
|
||||||
|
|
||||||
# compile first raw object (not linked yet) into which the sections will be embedded
|
|
||||||
# TODO: find out how this .o object can be generated using a normal add_executable call
|
|
||||||
# that'd allow us to get rid of the -I parameters in runtime_cflags
|
|
||||||
add_custom_command(
|
|
||||||
MAIN_DEPENDENCY runtime.c
|
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/runtime.0.o
|
|
||||||
COMMAND ${CMAKE_C_COMPILER} ${runtime_cflags} -c ${CMAKE_CURRENT_SOURCE_DIR}/runtime.c -o runtime.0.o
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# embed the sections, one by one
|
|
||||||
# TODO: find out whether all the sections can be embedded in a single objcopy call
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/runtime.1.o
|
|
||||||
COMMAND ${HOST}-objcopy --add-section .digest_md5=16_blank_bytes --set-section-flags .digest_md5=noload,readonly runtime.0.o runtime.1.o
|
|
||||||
MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR}/runtime.0.o
|
|
||||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/16_blank_bytes
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
)
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/runtime.2.o
|
|
||||||
COMMAND ${HOST}-objcopy --add-section .upd_info=1024_blank_bytes --set-section-flags .upd_info=noload,readonly runtime.1.o runtime.2.o
|
|
||||||
MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR}/runtime.1.o
|
|
||||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/1024_blank_bytes
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
)
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/runtime.3.o
|
|
||||||
COMMAND ${HOST}-objcopy --add-section .sha256_sig=1024_blank_bytes --set-section-flags .sha256_sig=noload,readonly runtime.2.o runtime.3.o
|
|
||||||
MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR}/runtime.2.o
|
|
||||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/1024_blank_bytes
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
)
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/runtime.4.o
|
|
||||||
COMMAND ${HOST}-objcopy --add-section .sig_key=8192_blank_bytes --set-section-flags .sig_key=noload,readonly runtime.3.o runtime.4.o
|
|
||||||
MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR}/runtime.3.o
|
|
||||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/8192_blank_bytes
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# add the runtime as a normal executable
|
|
||||||
# CLion will recognize it as a normal executable, one can simply step into the code
|
|
||||||
add_executable(runtime ${CMAKE_CURRENT_BINARY_DIR}/runtime.4.o notify.c)
|
|
||||||
if(COMMAND target_link_options)
|
|
||||||
target_link_options(runtime PRIVATE ${runtime_ldflags})
|
|
||||||
else()
|
|
||||||
message(WARNING "CMake version < 3.13, falling back to using target_link_libraries instead of target_link_options")
|
|
||||||
target_link_libraries(runtime PRIVATE ${runtime_ldflags})
|
|
||||||
endif()
|
|
||||||
# CMake gets confused by the .o object, therefore we need to tell it that it shall link everything using the C compiler
|
|
||||||
set_property(TARGET runtime PROPERTY LINKER_LANGUAGE C)
|
|
||||||
target_link_libraries(runtime PRIVATE -Wl,--as-needed -Wl,--dynamic-linker=${GLIBC_DYNAMIC_LINKER} -static-libstdc++ -Wl,-no-pie -Wl,-O2 -zmuldefs -L/feather/contrib/depends/${HOST}/lib squashfuse squashfuse_ll fuseprivate lzma z dl pthread appimage_shared appimage_hashlib )
|
|
||||||
|
|
||||||
target_include_directories(runtime PRIVATE ${PROJECT_SOURCE_DIR}/include)
|
|
||||||
|
|
||||||
add_custom_command(
|
|
||||||
TARGET runtime
|
|
||||||
POST_BUILD
|
|
||||||
COMMAND ${HOST}-strip ${CMAKE_CURRENT_BINARY_DIR}/runtime
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_command(
|
|
||||||
TARGET runtime
|
|
||||||
POST_BUILD
|
|
||||||
COMMAND echo -ne 'AI\\x02' | dd of="${CMAKE_CURRENT_BINARY_DIR}/runtime" bs=1 count=3 seek=8 conv=notrunc
|
|
||||||
)
|
|
24
contrib/depends/patches/appimage_runtime/depends-fix.patch
Normal file
24
contrib/depends/patches/appimage_runtime/depends-fix.patch
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
--- a/src/runtime/Makefile
|
||||||
|
+++ b/src/runtime/Makefile
|
||||||
|
@@ -1,15 +1,15 @@
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = -std=gnu99 -s -Os -D_FILE_OFFSET_BITS=64 -DGIT_COMMIT=\"${GIT_COMMIT}\" -T data_sections.ld -ffunction-sections -fdata-sections -Wl,--gc-sections -static
|
||||||
|
-LIBS = -lsquashfuse -lsquashfuse_ll -lzstd -lz
|
||||||
|
+LIBS = -lsquashfuse -lsquashfuse_ll -lzstd -lpthread
|
||||||
|
|
||||||
|
all: runtime-fuse2 runtime-fuse3
|
||||||
|
|
||||||
|
# Compile runtime
|
||||||
|
runtime-fuse2.o: runtime.c
|
||||||
|
- $(CC) -I/usr/local/include/squashfuse -I/usr/include/fuse -o runtime-fuse2.o -c $(CFLAGS) $^
|
||||||
|
+ $(CC) -I${host_prefix}/include -I${host_prefix}/include/fuse -o runtime-fuse2.o -c $(CFLAGS) $^
|
||||||
|
|
||||||
|
runtime-fuse2: runtime-fuse2.o
|
||||||
|
- $(CC) $(CFLAGS) $^ $(LIBS) -lfuse -o runtime-fuse2
|
||||||
|
+ $(CC) $(CFLAGS) $^ -L${host_prefix}/lib $(LIBS) -lfuse -lpthread -o runtime-fuse2
|
||||||
|
|
||||||
|
runtime-fuse3.o: runtime.c
|
||||||
|
$(CC) -I/usr/local/include/squashfuse -I/usr/include/fuse3 -o runtime-fuse3.o -c $(CFLAGS) $^
|
||||||
|
--
|
||||||
|
2.40.0
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
/* Try to show a notification on the GUI, fall back to the command line
|
|
||||||
* timeout is the timeout in milliseconds. timeout = NULL seems to trigger a
|
|
||||||
* GUI error dialog rather than a notification */
|
|
||||||
int notify(char *title, char *body, int timeout)
|
|
||||||
{
|
|
||||||
/* http://stackoverflow.com/questions/13204177/how-to-find-out-if-running-from-terminal-or-gui */
|
|
||||||
if (isatty(fileno(stdin))){
|
|
||||||
/* We were launched from the command line. */
|
|
||||||
printf("\n%s\n", title);
|
|
||||||
printf("%s\n", body);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* We were launched from inside the desktop */
|
|
||||||
printf("\n%s\n", title);
|
|
||||||
printf("%s\n", body);
|
|
||||||
/* https://debian-administration.org/article/407/Creating_desktop_notifications */
|
|
||||||
void *handle, *n;
|
|
||||||
typedef void (*notify_init_t)(char *);
|
|
||||||
typedef void *(*notify_notification_new_t)( char *, char *, char *, char *);
|
|
||||||
typedef void (*notify_notification_set_timeout_t)( void *, int );
|
|
||||||
typedef void (*notify_notification_show_t)(void *, char *);
|
|
||||||
handle = NULL;
|
|
||||||
if(handle == NULL)
|
|
||||||
handle= dlopen("libnotify.so.3", RTLD_LAZY);
|
|
||||||
if(handle == NULL)
|
|
||||||
handle= dlopen("libnotify.so.4", RTLD_LAZY);
|
|
||||||
if(handle == NULL)
|
|
||||||
handle= dlopen("libnotify.so.5", RTLD_LAZY);
|
|
||||||
if(handle == NULL)
|
|
||||||
handle= dlopen("libnotify.so.6", RTLD_LAZY);
|
|
||||||
if(handle == NULL)
|
|
||||||
handle= dlopen("libnotify.so.7", RTLD_LAZY);
|
|
||||||
if(handle == NULL)
|
|
||||||
handle= dlopen("libnotify.so.8", RTLD_LAZY);
|
|
||||||
|
|
||||||
if(handle == NULL)
|
|
||||||
{
|
|
||||||
printf("Failed to open libnotify.\n\n" );
|
|
||||||
}
|
|
||||||
notify_init_t init = (notify_init_t)dlsym(handle, "notify_init");
|
|
||||||
if ( init == NULL )
|
|
||||||
{
|
|
||||||
dlclose( handle );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
init("AppImage");
|
|
||||||
|
|
||||||
notify_notification_new_t nnn = (notify_notification_new_t)dlsym(handle, "notify_notification_new");
|
|
||||||
if ( nnn == NULL )
|
|
||||||
{
|
|
||||||
dlclose( handle );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
n = nnn(title, body, NULL, NULL);
|
|
||||||
notify_notification_set_timeout_t nnst = (notify_notification_set_timeout_t)dlsym(handle, "notify_notification_set_timeout");
|
|
||||||
if ( nnst == NULL )
|
|
||||||
{
|
|
||||||
dlclose( handle );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
nnst(n, timeout);
|
|
||||||
notify_notification_show_t show = (notify_notification_show_t)dlsym(handle, "notify_notification_show");
|
|
||||||
if ( init == NULL )
|
|
||||||
{
|
|
||||||
dlclose( handle );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
show(n, NULL );
|
|
||||||
dlclose(handle );
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,946 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (c) 2004-18 Simon Peter
|
|
||||||
* Portions Copyright (c) 2007 Alexander Larsson
|
|
||||||
*
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ident "AppImage by Simon Peter, http://appimage.org/"
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
|
|
||||||
#include "squashfuse.h"
|
|
||||||
#include <squashfs_fs.h>
|
|
||||||
#include <nonstd.h>
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <ftw.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <wait.h>
|
|
||||||
#include <fnmatch.h>
|
|
||||||
|
|
||||||
#include <appimage/appimage_shared.h>
|
|
||||||
#include <hashlib.h>
|
|
||||||
|
|
||||||
#ifndef ENABLE_DLOPEN
|
|
||||||
#define ENABLE_DLOPEN
|
|
||||||
#endif
|
|
||||||
#include "squashfuse_dlopen.h"
|
|
||||||
|
|
||||||
/* Exit status to use when launching an AppImage fails.
|
|
||||||
* For applications that assign meanings to exit status codes (e.g. rsync),
|
|
||||||
* we avoid "cluttering" pre-defined exit status codes by using 127 which
|
|
||||||
* is known to alias an application exit status and also known as launcher
|
|
||||||
* error, see SYSTEM(3POSIX).
|
|
||||||
*/
|
|
||||||
#define EXIT_EXECERROR 127 /* Execution error exit status. */
|
|
||||||
|
|
||||||
//#include "notify.c"
|
|
||||||
extern int notify(char *title, char *body, int timeout);
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
static ssize_t fs_offset; // The offset at which a filesystem image is expected = end of this ELF
|
|
||||||
|
|
||||||
static void die(const char *msg) {
|
|
||||||
fprintf(stderr, "%s\n", msg);
|
|
||||||
exit(EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check whether directory is writable */
|
|
||||||
bool is_writable_directory(char* str) {
|
|
||||||
if(access(str, W_OK) == 0) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool startsWith(const char *pre, const char *str)
|
|
||||||
{
|
|
||||||
size_t lenpre = strlen(pre),
|
|
||||||
lenstr = strlen(str);
|
|
||||||
return lenstr < lenpre ? false : strncmp(pre, str, lenpre) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in a stat structure. Does not set st_ino */
|
|
||||||
sqfs_err private_sqfs_stat(sqfs *fs, sqfs_inode *inode, struct stat *st) {
|
|
||||||
sqfs_err err = SQFS_OK;
|
|
||||||
uid_t id;
|
|
||||||
|
|
||||||
memset(st, 0, sizeof(*st));
|
|
||||||
st->st_mode = inode->base.mode;
|
|
||||||
st->st_nlink = inode->nlink;
|
|
||||||
st->st_mtime = st->st_ctime = st->st_atime = inode->base.mtime;
|
|
||||||
|
|
||||||
if (S_ISREG(st->st_mode)) {
|
|
||||||
/* FIXME: do symlinks, dirs, etc have a size? */
|
|
||||||
st->st_size = inode->xtra.reg.file_size;
|
|
||||||
st->st_blocks = st->st_size / 512;
|
|
||||||
} else if (S_ISBLK(st->st_mode) || S_ISCHR(st->st_mode)) {
|
|
||||||
st->st_rdev = sqfs_makedev(inode->xtra.dev.major,
|
|
||||||
inode->xtra.dev.minor);
|
|
||||||
} else if (S_ISLNK(st->st_mode)) {
|
|
||||||
st->st_size = inode->xtra.symlink_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
st->st_blksize = fs->sb.block_size; /* seriously? */
|
|
||||||
|
|
||||||
err = sqfs_id_get(fs, inode->base.uid, &id);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
st->st_uid = id;
|
|
||||||
err = sqfs_id_get(fs, inode->base.guid, &id);
|
|
||||||
st->st_gid = id;
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
return SQFS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ================= End ELF parsing */
|
|
||||||
|
|
||||||
extern int fusefs_main(int argc, char *argv[], void (*mounted) (void));
|
|
||||||
// extern void ext2_quit(void);
|
|
||||||
|
|
||||||
static pid_t fuse_pid;
|
|
||||||
static int keepalive_pipe[2];
|
|
||||||
|
|
||||||
static void *
|
|
||||||
write_pipe_thread (void *arg)
|
|
||||||
{
|
|
||||||
char c[32];
|
|
||||||
int res;
|
|
||||||
// sprintf(stderr, "Called write_pipe_thread");
|
|
||||||
memset (c, 'x', sizeof (c));
|
|
||||||
while (1) {
|
|
||||||
/* Write until we block, on broken pipe, exit */
|
|
||||||
res = write (keepalive_pipe[1], c, sizeof (c));
|
|
||||||
if (res == -1) {
|
|
||||||
kill (fuse_pid, SIGTERM);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fuse_mounted (void)
|
|
||||||
{
|
|
||||||
pthread_t thread;
|
|
||||||
fuse_pid = getpid();
|
|
||||||
pthread_create(&thread, NULL, write_pipe_thread, keepalive_pipe);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* getArg(int argc, char *argv[],char chr)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i=1; i<argc; ++i)
|
|
||||||
if ((argv[i][0]=='-') && (argv[i][1]==chr))
|
|
||||||
return &(argv[i][2]);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* mkdir -p implemented in C, needed for https://github.com/AppImage/AppImageKit/issues/333
|
|
||||||
* https://gist.github.com/JonathonReinhart/8c0d90191c38af2dcadb102c4e202950 */
|
|
||||||
int
|
|
||||||
mkdir_p(const char* const path)
|
|
||||||
{
|
|
||||||
/* Adapted from http://stackoverflow.com/a/2336245/119527 */
|
|
||||||
const size_t len = strlen(path);
|
|
||||||
char _path[PATH_MAX];
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
/* Copy string so its mutable */
|
|
||||||
if (len > sizeof(_path)-1) {
|
|
||||||
errno = ENAMETOOLONG;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
strcpy(_path, path);
|
|
||||||
|
|
||||||
/* Iterate the string */
|
|
||||||
for (p = _path + 1; *p; p++) {
|
|
||||||
if (*p == '/') {
|
|
||||||
/* Temporarily truncate */
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
if (mkdir(_path, 0755) != 0) {
|
|
||||||
if (errno != EEXIST)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*p = '/';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mkdir(_path, 0755) != 0) {
|
|
||||||
if (errno != EEXIST)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
print_help(const char *appimage_path)
|
|
||||||
{
|
|
||||||
// TODO: "--appimage-list List content from embedded filesystem image\n"
|
|
||||||
fprintf(stderr,
|
|
||||||
"AppImage options:\n\n"
|
|
||||||
" --appimage-extract [<pattern>] Extract content from embedded filesystem image\n"
|
|
||||||
" If pattern is passed, only extract matching files\n"
|
|
||||||
" --appimage-help Print this help\n"
|
|
||||||
" --appimage-mount Mount embedded filesystem image and print\n"
|
|
||||||
" mount point and wait for kill with Ctrl-C\n"
|
|
||||||
" --appimage-offset Print byte offset to start of embedded\n"
|
|
||||||
" filesystem image\n"
|
|
||||||
" --appimage-portable-home Create a portable home folder to use as $HOME\n"
|
|
||||||
" --appimage-portable-config Create a portable config folder to use as\n"
|
|
||||||
" $XDG_CONFIG_HOME\n"
|
|
||||||
" --appimage-signature Print digital signature embedded in AppImage\n"
|
|
||||||
" --appimage-updateinfo[rmation] Print update info embedded in AppImage\n"
|
|
||||||
"\n"
|
|
||||||
"Portable home:\n"
|
|
||||||
"\n"
|
|
||||||
" If you would like the application contained inside this AppImage to store its\n"
|
|
||||||
" data alongside this AppImage rather than in your home directory, then you can\n"
|
|
||||||
" place a directory named\n"
|
|
||||||
"\n"
|
|
||||||
" %s.home\n"
|
|
||||||
"\n"
|
|
||||||
" Or you can invoke this AppImage with the --appimage-portable-home option,\n"
|
|
||||||
" which will create this directory for you. As long as the directory exists\n"
|
|
||||||
" and is neither moved nor renamed, the application contained inside this\n"
|
|
||||||
" AppImage to store its data in this directory rather than in your home\n"
|
|
||||||
" directory\n"
|
|
||||||
, appimage_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
portable_option(const char *arg, const char *appimage_path, const char *name)
|
|
||||||
{
|
|
||||||
char option[32];
|
|
||||||
sprintf(option, "appimage-portable-%s", name);
|
|
||||||
|
|
||||||
if (arg && strcmp(arg, option)==0) {
|
|
||||||
char portable_dir[PATH_MAX];
|
|
||||||
char fullpath[PATH_MAX];
|
|
||||||
|
|
||||||
ssize_t length = readlink(appimage_path, fullpath, sizeof(fullpath));
|
|
||||||
if (length < 0) {
|
|
||||||
fprintf(stderr, "Error getting realpath for %s\n", appimage_path);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
fullpath[length] = '\0';
|
|
||||||
|
|
||||||
sprintf(portable_dir, "%s.%s", fullpath, name);
|
|
||||||
if (!mkdir(portable_dir, S_IRWXU))
|
|
||||||
fprintf(stderr, "Portable %s directory created at %s\n", name, portable_dir);
|
|
||||||
else
|
|
||||||
fprintf(stderr, "Error creating portable %s directory at %s: %s\n", name, portable_dir, strerror(errno));
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool extract_appimage(const char* const appimage_path, const char* const _prefix, const char* const _pattern, const bool overwrite, const bool verbose) {
|
|
||||||
sqfs_err err = SQFS_OK;
|
|
||||||
sqfs_traverse trv;
|
|
||||||
sqfs fs;
|
|
||||||
char prefixed_path_to_extract[1024];
|
|
||||||
|
|
||||||
// local copy we can modify safely
|
|
||||||
// allocate 1 more byte than we would need so we can add a trailing slash if there is none yet
|
|
||||||
char* prefix = malloc(strlen(_prefix) + 2);
|
|
||||||
strcpy(prefix, _prefix);
|
|
||||||
|
|
||||||
// sanitize prefix
|
|
||||||
if (prefix[strlen(prefix) - 1] != '/')
|
|
||||||
strcat(prefix, "/");
|
|
||||||
|
|
||||||
if (access(prefix, F_OK) == -1) {
|
|
||||||
if (mkdir_p(prefix) == -1) {
|
|
||||||
perror("mkdir_p error");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = sqfs_open_image(&fs, appimage_path, (size_t) fs_offset))) {
|
|
||||||
fprintf(stderr, "Failed to open squashfs image\n");
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// track duplicate inodes for hardlinks
|
|
||||||
char** created_inode = calloc(fs.sb.inodes, sizeof(char*));
|
|
||||||
if (created_inode == NULL) {
|
|
||||||
fprintf(stderr, "Failed allocating memory to track hardlinks\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = sqfs_traverse_open(&trv, &fs, sqfs_inode_root(&fs)))) {
|
|
||||||
fprintf(stderr, "sqfs_traverse_open error\n");
|
|
||||||
free(created_inode);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool rv = true;
|
|
||||||
|
|
||||||
while (sqfs_traverse_next(&trv, &err)) {
|
|
||||||
if (!trv.dir_end) {
|
|
||||||
if (_pattern == NULL || fnmatch(_pattern, trv.path, FNM_FILE_NAME | FNM_LEADING_DIR) == 0) {
|
|
||||||
// fprintf(stderr, "trv.path: %s\n", trv.path);
|
|
||||||
// fprintf(stderr, "sqfs_inode_id: %lu\n", trv.entry.inode);
|
|
||||||
sqfs_inode inode;
|
|
||||||
if (sqfs_inode_get(&fs, &inode, trv.entry.inode)) {
|
|
||||||
fprintf(stderr, "sqfs_inode_get error\n");
|
|
||||||
rv = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// fprintf(stderr, "inode.base.inode_type: %i\n", inode.base.inode_type);
|
|
||||||
// fprintf(stderr, "inode.xtra.reg.file_size: %lu\n", inode.xtra.reg.file_size);
|
|
||||||
strcpy(prefixed_path_to_extract, "");
|
|
||||||
strcat(strcat(prefixed_path_to_extract, prefix), trv.path);
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
fprintf(stdout, "%s\n", prefixed_path_to_extract);
|
|
||||||
|
|
||||||
if (inode.base.inode_type == SQUASHFS_DIR_TYPE || inode.base.inode_type == SQUASHFS_LDIR_TYPE) {
|
|
||||||
// fprintf(stderr, "inode.xtra.dir.parent_inode: %ui\n", inode.xtra.dir.parent_inode);
|
|
||||||
// fprintf(stderr, "mkdir_p: %s/\n", prefixed_path_to_extract);
|
|
||||||
if (access(prefixed_path_to_extract, F_OK) == -1) {
|
|
||||||
if (mkdir_p(prefixed_path_to_extract) == -1) {
|
|
||||||
perror("mkdir_p error");
|
|
||||||
rv = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (inode.base.inode_type == SQUASHFS_REG_TYPE || inode.base.inode_type == SQUASHFS_LREG_TYPE) {
|
|
||||||
// if we've already created this inode, then this is a hardlink
|
|
||||||
char* existing_path_for_inode = created_inode[inode.base.inode_number - 1];
|
|
||||||
if (existing_path_for_inode != NULL) {
|
|
||||||
unlink(prefixed_path_to_extract);
|
|
||||||
if (link(existing_path_for_inode, prefixed_path_to_extract) == -1) {
|
|
||||||
fprintf(stderr, "Couldn't create hardlink from \"%s\" to \"%s\": %s\n",
|
|
||||||
prefixed_path_to_extract, existing_path_for_inode, strerror(errno));
|
|
||||||
rv = false;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
struct stat st;
|
|
||||||
if (!overwrite && stat(prefixed_path_to_extract, &st) == 0 && st.st_size == inode.xtra.reg.file_size) {
|
|
||||||
fprintf(stderr, "File exists and file size matches, skipping\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// track the path we extract to for this inode, so that we can `link` if this inode is found again
|
|
||||||
created_inode[inode.base.inode_number - 1] = strdup(prefixed_path_to_extract);
|
|
||||||
// fprintf(stderr, "Extract to: %s\n", prefixed_path_to_extract);
|
|
||||||
if (private_sqfs_stat(&fs, &inode, &st) != 0)
|
|
||||||
die("private_sqfs_stat error");
|
|
||||||
|
|
||||||
// create parent dir
|
|
||||||
char* p = strrchr(prefixed_path_to_extract, '/');
|
|
||||||
if (p) {
|
|
||||||
// set an \0 to end the split the string
|
|
||||||
*p = '\0';
|
|
||||||
mkdir_p(prefixed_path_to_extract);
|
|
||||||
|
|
||||||
// restore dir seprator
|
|
||||||
*p = '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the file in chunks
|
|
||||||
off_t bytes_already_read = 0;
|
|
||||||
sqfs_off_t bytes_at_a_time = 64 * 1024;
|
|
||||||
FILE* f;
|
|
||||||
f = fopen(prefixed_path_to_extract, "w+");
|
|
||||||
if (f == NULL) {
|
|
||||||
perror("fopen error");
|
|
||||||
rv = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while (bytes_already_read < inode.xtra.reg.file_size) {
|
|
||||||
char buf[bytes_at_a_time];
|
|
||||||
if (sqfs_read_range(&fs, &inode, (sqfs_off_t) bytes_already_read, &bytes_at_a_time, buf)) {
|
|
||||||
perror("sqfs_read_range error");
|
|
||||||
rv = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// fwrite(buf, 1, bytes_at_a_time, stdout);
|
|
||||||
fwrite(buf, 1, bytes_at_a_time, f);
|
|
||||||
bytes_already_read = bytes_already_read + bytes_at_a_time;
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
chmod(prefixed_path_to_extract, st.st_mode);
|
|
||||||
if (!rv)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (inode.base.inode_type == SQUASHFS_SYMLINK_TYPE || inode.base.inode_type == SQUASHFS_LSYMLINK_TYPE) {
|
|
||||||
size_t size;
|
|
||||||
sqfs_readlink(&fs, &inode, NULL, &size);
|
|
||||||
char buf[size];
|
|
||||||
int ret = sqfs_readlink(&fs, &inode, buf, &size);
|
|
||||||
if (ret != 0) {
|
|
||||||
perror("symlink error");
|
|
||||||
rv = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// fprintf(stderr, "Symlink: %s to %s \n", prefixed_path_to_extract, buf);
|
|
||||||
unlink(prefixed_path_to_extract);
|
|
||||||
ret = symlink(buf, prefixed_path_to_extract);
|
|
||||||
if (ret != 0)
|
|
||||||
fprintf(stderr, "WARNING: could not create symlink\n");
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "TODO: Implement inode.base.inode_type %i\n", inode.base.inode_type);
|
|
||||||
}
|
|
||||||
// fprintf(stderr, "\n");
|
|
||||||
|
|
||||||
if (!rv)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < fs.sb.inodes; i++) {
|
|
||||||
free(created_inode[i]);
|
|
||||||
}
|
|
||||||
free(created_inode);
|
|
||||||
|
|
||||||
if (err != SQFS_OK) {
|
|
||||||
fprintf(stderr, "sqfs_traverse_next error\n");
|
|
||||||
rv = false;
|
|
||||||
}
|
|
||||||
sqfs_traverse_close(&trv);
|
|
||||||
sqfs_fd_close(fs.fd);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rm_recursive_callback(const char* path, const struct stat* stat, const int type, struct FTW* ftw) {
|
|
||||||
(void) stat;
|
|
||||||
(void) ftw;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case FTW_NS:
|
|
||||||
case FTW_DNR:
|
|
||||||
fprintf(stderr, "%s: ftw error: %s\n",
|
|
||||||
path, strerror(errno));
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
case FTW_D:
|
|
||||||
// ignore directories at first, will be handled by FTW_DP
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FTW_F:
|
|
||||||
case FTW_SL:
|
|
||||||
case FTW_SLN:
|
|
||||||
if (remove(path) != 0) {
|
|
||||||
fprintf(stderr, "Failed to remove %s: %s\n", path, strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
case FTW_DP:
|
|
||||||
if (rmdir(path) != 0) {
|
|
||||||
fprintf(stderr, "Failed to remove directory %s: %s\n", path, strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Unexpected fts_info\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool rm_recursive(const char* const path) {
|
|
||||||
// FTW_DEPTH: perform depth-first search to make sure files are deleted before the containing directories
|
|
||||||
// FTW_MOUNT: prevent deletion of files on other mounted filesystems
|
|
||||||
// FTW_PHYS: do not follow symlinks, but report symlinks as such; this way, the symlink targets, which might point
|
|
||||||
// to locations outside path will not be deleted accidentally (attackers might abuse this)
|
|
||||||
int rv = nftw(path, &rm_recursive_callback, 0, FTW_DEPTH | FTW_MOUNT | FTW_PHYS);
|
|
||||||
|
|
||||||
return rv == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool build_mount_point(char* mount_dir, const char* const argv0, char const* const temp_base, const size_t templen) {
|
|
||||||
const size_t maxnamelen = 6;
|
|
||||||
|
|
||||||
// when running for another AppImage, we should use that for building the mountpoint name instead
|
|
||||||
char* target_appimage = getenv("TARGET_APPIMAGE");
|
|
||||||
|
|
||||||
char* path_basename;
|
|
||||||
if (target_appimage != NULL) {
|
|
||||||
path_basename = basename(target_appimage);
|
|
||||||
} else {
|
|
||||||
path_basename = basename(argv0);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t namelen = strlen(path_basename);
|
|
||||||
// limit length of tempdir name
|
|
||||||
if (namelen > maxnamelen) {
|
|
||||||
namelen = maxnamelen;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(mount_dir, temp_base);
|
|
||||||
strncpy(mount_dir + templen, "/.mount_", 8);
|
|
||||||
strncpy(mount_dir + templen + 8, path_basename, namelen);
|
|
||||||
strncpy(mount_dir+templen+8+namelen, "XXXXXX", 6);
|
|
||||||
mount_dir[templen+8+namelen+6] = 0; // null terminate destination
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
char appimage_path[PATH_MAX];
|
|
||||||
char argv0_path[PATH_MAX];
|
|
||||||
char * arg;
|
|
||||||
|
|
||||||
/* We might want to operate on a target appimage rather than this file itself,
|
|
||||||
* e.g., for appimaged which must not run untrusted code from random AppImages.
|
|
||||||
* This variable is intended for use by e.g., appimaged and is subject to
|
|
||||||
* change any time. Do not rely on it being present. We might even limit this
|
|
||||||
* functionality specifically for builds used by appimaged.
|
|
||||||
*/
|
|
||||||
if (getenv("TARGET_APPIMAGE") == NULL) {
|
|
||||||
strcpy(appimage_path, "/proc/self/exe");
|
|
||||||
strcpy(argv0_path, argv[0]);
|
|
||||||
} else {
|
|
||||||
strcpy(appimage_path, getenv("TARGET_APPIMAGE"));
|
|
||||||
strcpy(argv0_path, getenv("TARGET_APPIMAGE"));
|
|
||||||
|
|
||||||
#ifdef ENABLE_SETPROCTITLE
|
|
||||||
// load libbsd dynamically to change proc title
|
|
||||||
// this is an optional feature, therefore we don't hard require it
|
|
||||||
void* libbsd = dlopen("libbsd.so", RTLD_NOW);
|
|
||||||
|
|
||||||
if (libbsd != NULL) {
|
|
||||||
// clear error state
|
|
||||||
dlerror();
|
|
||||||
|
|
||||||
// try to load the two required symbols
|
|
||||||
void (*setproctitle_init)(int, char**, char**) = dlsym(libbsd, "setproctitle_init");
|
|
||||||
|
|
||||||
char* error;
|
|
||||||
|
|
||||||
if ((error = dlerror()) == NULL) {
|
|
||||||
void (*setproctitle)(const char*, char*) = dlsym(libbsd, "setproctitle");
|
|
||||||
|
|
||||||
if (dlerror() == NULL) {
|
|
||||||
char buffer[1024];
|
|
||||||
strcpy(buffer, getenv("TARGET_APPIMAGE"));
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
strcat(buffer, " ");
|
|
||||||
strcat(buffer, argv[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
(*setproctitle_init)(argc, argv, environ);
|
|
||||||
(*setproctitle)("%s", buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dlclose(libbsd);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// temporary directories are required in a few places
|
|
||||||
// therefore we implement the detection of the temp base dir at the top of the code to avoid redundancy
|
|
||||||
char temp_base[PATH_MAX] = P_tmpdir;
|
|
||||||
|
|
||||||
{
|
|
||||||
const char* const TMPDIR = getenv("TMPDIR");
|
|
||||||
if (TMPDIR != NULL)
|
|
||||||
strcpy(temp_base, getenv("TMPDIR"));
|
|
||||||
}
|
|
||||||
|
|
||||||
fs_offset = appimage_get_elf_size(appimage_path);
|
|
||||||
|
|
||||||
// error check
|
|
||||||
if (fs_offset < 0) {
|
|
||||||
fprintf(stderr, "Failed to get fs offset for %s\n", appimage_path);
|
|
||||||
exit(EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
arg=getArg(argc,argv,'-');
|
|
||||||
|
|
||||||
/* Print the help and then exit */
|
|
||||||
if(arg && strcmp(arg,"appimage-help")==0) {
|
|
||||||
char fullpath[PATH_MAX];
|
|
||||||
|
|
||||||
ssize_t length = readlink(appimage_path, fullpath, sizeof(fullpath));
|
|
||||||
if (length < 0) {
|
|
||||||
fprintf(stderr, "Error getting realpath for %s\n", appimage_path);
|
|
||||||
exit(EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
fullpath[length] = '\0';
|
|
||||||
|
|
||||||
print_help(fullpath);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Just print the offset and then exit */
|
|
||||||
if(arg && strcmp(arg,"appimage-offset")==0) {
|
|
||||||
printf("%lu\n", fs_offset);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
arg=getArg(argc,argv,'-');
|
|
||||||
|
|
||||||
/* extract the AppImage */
|
|
||||||
if(arg && strcmp(arg,"appimage-extract")==0) {
|
|
||||||
char* pattern;
|
|
||||||
|
|
||||||
// default use case: use standard prefix
|
|
||||||
if (argc == 2) {
|
|
||||||
pattern = NULL;
|
|
||||||
} else if (argc == 3) {
|
|
||||||
pattern = argv[2];
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Unexpected argument count: %d\n", argc - 1);
|
|
||||||
fprintf(stderr, "Usage: %s --appimage-extract [<prefix>]\n", argv0_path);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!extract_appimage(appimage_path, "squashfs-root/", pattern, true, true)) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate full path of AppImage
|
|
||||||
int length;
|
|
||||||
char fullpath[PATH_MAX];
|
|
||||||
|
|
||||||
if(getenv("TARGET_APPIMAGE") == NULL) {
|
|
||||||
// If we are operating on this file itself
|
|
||||||
ssize_t len = readlink(appimage_path, fullpath, sizeof(fullpath));
|
|
||||||
if (len < 0) {
|
|
||||||
perror("Failed to obtain absolute path");
|
|
||||||
exit(EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
fullpath[len] = '\0';
|
|
||||||
} else {
|
|
||||||
char* abspath = realpath(appimage_path, NULL);
|
|
||||||
if (abspath == NULL) {
|
|
||||||
perror("Failed to obtain absolute path");
|
|
||||||
exit(EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
strcpy(fullpath, abspath);
|
|
||||||
free(abspath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getenv("APPIMAGE_EXTRACT_AND_RUN") != NULL || (arg && strcmp(arg, "appimage-extract-and-run") == 0)) {
|
|
||||||
char* hexlified_digest = NULL;
|
|
||||||
|
|
||||||
// calculate MD5 hash of file, and use it to make extracted directory name "content-aware"
|
|
||||||
// see https://github.com/AppImage/AppImageKit/issues/841 for more information
|
|
||||||
{
|
|
||||||
FILE* f = fopen(appimage_path, "rb");
|
|
||||||
if (f == NULL) {
|
|
||||||
perror("Failed to open AppImage file");
|
|
||||||
exit(EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
Md5Context ctx;
|
|
||||||
Md5Initialise(&ctx);
|
|
||||||
|
|
||||||
char buf[4096];
|
|
||||||
for (size_t bytes_read; (bytes_read = fread(buf, sizeof(char), sizeof(buf), f)); bytes_read > 0) {
|
|
||||||
Md5Update(&ctx, buf, (uint32_t) bytes_read);
|
|
||||||
}
|
|
||||||
|
|
||||||
MD5_HASH digest;
|
|
||||||
Md5Finalise(&ctx, &digest);
|
|
||||||
|
|
||||||
hexlified_digest = appimage_hexlify(digest.bytes, sizeof(digest.bytes));
|
|
||||||
}
|
|
||||||
|
|
||||||
char* prefix = malloc(strlen(temp_base) + 20 + strlen(hexlified_digest) + 2);
|
|
||||||
strcpy(prefix, temp_base);
|
|
||||||
strcat(prefix, "/appimage_extracted_");
|
|
||||||
strcat(prefix, hexlified_digest);
|
|
||||||
free(hexlified_digest);
|
|
||||||
|
|
||||||
const bool verbose = (getenv("VERBOSE") != NULL);
|
|
||||||
|
|
||||||
if (!extract_appimage(appimage_path, prefix, NULL, false, verbose)) {
|
|
||||||
fprintf(stderr, "Failed to extract AppImage\n");
|
|
||||||
exit(EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
int pid;
|
|
||||||
if ((pid = fork()) == -1) {
|
|
||||||
int error = errno;
|
|
||||||
fprintf(stderr, "fork() failed: %s\n", strerror(error));
|
|
||||||
exit(EXIT_EXECERROR);
|
|
||||||
} else if (pid == 0) {
|
|
||||||
const char apprun_fname[] = "AppRun";
|
|
||||||
char* apprun_path = malloc(strlen(prefix) + 1 + strlen(apprun_fname) + 1);
|
|
||||||
strcpy(apprun_path, prefix);
|
|
||||||
strcat(apprun_path, "/");
|
|
||||||
strcat(apprun_path, apprun_fname);
|
|
||||||
|
|
||||||
// create copy of argument list without the --appimage-extract-and-run parameter
|
|
||||||
char* new_argv[argc];
|
|
||||||
int new_argc = 0;
|
|
||||||
new_argv[new_argc++] = strdup(apprun_path);
|
|
||||||
for (int i = 1; i < argc; ++i) {
|
|
||||||
if (strcmp(argv[i], "--appimage-extract-and-run") != 0) {
|
|
||||||
new_argv[new_argc++] = strdup(argv[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
new_argv[new_argc] = NULL;
|
|
||||||
|
|
||||||
/* Setting some environment variables that the app "inside" might use */
|
|
||||||
setenv("APPIMAGE", fullpath, 1);
|
|
||||||
setenv("ARGV0", argv0_path, 1);
|
|
||||||
setenv("APPDIR", prefix, 1);
|
|
||||||
|
|
||||||
execv(apprun_path, new_argv);
|
|
||||||
|
|
||||||
int error = errno;
|
|
||||||
fprintf(stderr, "Failed to run %s: %s\n", apprun_path, strerror(error));
|
|
||||||
|
|
||||||
free(apprun_path);
|
|
||||||
exit(EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
int status = 0;
|
|
||||||
int rv = waitpid(pid, &status, 0);
|
|
||||||
status = rv > 0 && WIFEXITED (status) ? WEXITSTATUS (status) : EXIT_EXECERROR;
|
|
||||||
|
|
||||||
if (getenv("NO_CLEANUP") == NULL) {
|
|
||||||
if (!rm_recursive(prefix)) {
|
|
||||||
fprintf(stderr, "Failed to clean up cache directory\n");
|
|
||||||
if (status == 0) /* avoid messing existing failure exit status */
|
|
||||||
status = EXIT_EXECERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// template == prefix, must be freed only once
|
|
||||||
free(prefix);
|
|
||||||
|
|
||||||
exit(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(arg && (strcmp(arg,"appimage-updateinformation")==0 || strcmp(arg,"appimage-updateinfo")==0)) {
|
|
||||||
unsigned long offset = 0;
|
|
||||||
unsigned long length = 0;
|
|
||||||
appimage_get_elf_section_offset_and_length(appimage_path, ".upd_info", &offset, &length);
|
|
||||||
// fprintf(stderr, "offset: %lu\n", offset);
|
|
||||||
// fprintf(stderr, "length: %lu\n", length);
|
|
||||||
// print_hex(appimage_path, offset, length);
|
|
||||||
appimage_print_binary(appimage_path, offset, length);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(arg && strcmp(arg,"appimage-signature")==0) {
|
|
||||||
unsigned long offset = 0;
|
|
||||||
unsigned long length = 0;
|
|
||||||
appimage_get_elf_section_offset_and_length(appimage_path, ".sha256_sig", &offset, &length);
|
|
||||||
// fprintf(stderr, "offset: %lu\n", offset);
|
|
||||||
// fprintf(stderr, "length: %lu\n", length);
|
|
||||||
// print_hex(appimage_path, offset, length);
|
|
||||||
appimage_print_binary(appimage_path, offset, length);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
portable_option(arg, appimage_path, "home");
|
|
||||||
portable_option(arg, appimage_path, "config");
|
|
||||||
|
|
||||||
// If there is an argument starting with appimage- (but not appimage-mount which is handled further down)
|
|
||||||
// then stop here and print an error message
|
|
||||||
if((arg && strncmp(arg, "appimage-", 8) == 0) && (arg && strcmp(arg,"appimage-mount")!=0)) {
|
|
||||||
fprintf(stderr,"--%s is not yet implemented\n", arg);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOAD_LIBRARY; /* exit if libfuse is missing */
|
|
||||||
|
|
||||||
int dir_fd, res;
|
|
||||||
|
|
||||||
size_t templen = strlen(temp_base);
|
|
||||||
|
|
||||||
// allocate enough memory (size of name won't exceed 60 bytes)
|
|
||||||
char mount_dir[templen + 60];
|
|
||||||
|
|
||||||
build_mount_point(mount_dir, argv[0], temp_base, templen);
|
|
||||||
|
|
||||||
size_t mount_dir_size = strlen(mount_dir);
|
|
||||||
pid_t pid;
|
|
||||||
char **real_argv;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (mkdtemp(mount_dir) == NULL) {
|
|
||||||
perror ("create mount dir error");
|
|
||||||
exit (EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pipe (keepalive_pipe) == -1) {
|
|
||||||
perror ("pipe error");
|
|
||||||
exit (EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
pid = fork ();
|
|
||||||
if (pid == -1) {
|
|
||||||
perror ("fork error");
|
|
||||||
exit (EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid == 0) {
|
|
||||||
/* in child */
|
|
||||||
|
|
||||||
char *child_argv[5];
|
|
||||||
|
|
||||||
/* close read pipe */
|
|
||||||
close (keepalive_pipe[0]);
|
|
||||||
|
|
||||||
char *dir = realpath(appimage_path, NULL );
|
|
||||||
|
|
||||||
char options[100];
|
|
||||||
sprintf(options, "ro,offset=%lu", fs_offset);
|
|
||||||
|
|
||||||
child_argv[0] = dir;
|
|
||||||
child_argv[1] = "-o";
|
|
||||||
child_argv[2] = options;
|
|
||||||
child_argv[3] = dir;
|
|
||||||
child_argv[4] = mount_dir;
|
|
||||||
|
|
||||||
if(0 != fusefs_main (5, child_argv, fuse_mounted)){
|
|
||||||
char *title;
|
|
||||||
char *body;
|
|
||||||
title = "Cannot mount AppImage, please check your FUSE setup.";
|
|
||||||
body = "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";
|
|
||||||
notify(title, body, 0); // 3 seconds timeout
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
/* in parent, child is $pid */
|
|
||||||
int c;
|
|
||||||
|
|
||||||
/* close write pipe */
|
|
||||||
close (keepalive_pipe[1]);
|
|
||||||
|
|
||||||
/* Pause until mounted */
|
|
||||||
read (keepalive_pipe[0], &c, 1);
|
|
||||||
|
|
||||||
/* Fuse process has now daemonized, reap our child */
|
|
||||||
waitpid(pid, NULL, 0);
|
|
||||||
|
|
||||||
dir_fd = open (mount_dir, O_RDONLY);
|
|
||||||
if (dir_fd == -1) {
|
|
||||||
perror ("open dir error");
|
|
||||||
exit (EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
res = dup2 (dir_fd, 1023);
|
|
||||||
if (res == -1) {
|
|
||||||
perror ("dup2 error");
|
|
||||||
exit (EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
close (dir_fd);
|
|
||||||
|
|
||||||
real_argv = malloc (sizeof (char *) * (argc + 1));
|
|
||||||
for (i = 0; i < argc; i++) {
|
|
||||||
real_argv[i] = argv[i];
|
|
||||||
}
|
|
||||||
real_argv[i] = NULL;
|
|
||||||
|
|
||||||
if(arg && strcmp(arg, "appimage-mount") == 0) {
|
|
||||||
char real_mount_dir[PATH_MAX];
|
|
||||||
|
|
||||||
if (realpath(mount_dir, real_mount_dir) == real_mount_dir) {
|
|
||||||
printf("%s\n", real_mount_dir);
|
|
||||||
} else {
|
|
||||||
printf("%s\n", mount_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
// stdout is, by default, buffered (unlike stderr), therefore in order to allow other processes to read
|
|
||||||
// the path from stdout, we need to flush the buffers now
|
|
||||||
// this is a less-invasive alternative to setbuf(stdout, NULL);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
for (;;) pause();
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Setting some environment variables that the app "inside" might use */
|
|
||||||
setenv( "APPIMAGE", fullpath, 1 );
|
|
||||||
setenv( "ARGV0", argv0_path, 1 );
|
|
||||||
setenv( "APPDIR", mount_dir, 1 );
|
|
||||||
|
|
||||||
char portable_home_dir[PATH_MAX];
|
|
||||||
char portable_config_dir[PATH_MAX];
|
|
||||||
|
|
||||||
/* If there is a directory with the same name as the AppImage plus ".home", then export $HOME */
|
|
||||||
strcpy (portable_home_dir, fullpath);
|
|
||||||
strcat (portable_home_dir, ".home");
|
|
||||||
if(is_writable_directory(portable_home_dir)){
|
|
||||||
fprintf(stderr, "Setting $HOME to %s\n", portable_home_dir);
|
|
||||||
setenv("HOME",portable_home_dir,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If there is a directory with the same name as the AppImage plus ".config", then export $XDG_CONFIG_HOME */
|
|
||||||
strcpy (portable_config_dir, fullpath);
|
|
||||||
strcat (portable_config_dir, ".config");
|
|
||||||
if(is_writable_directory(portable_config_dir)){
|
|
||||||
fprintf(stderr, "Setting $XDG_CONFIG_HOME to %s\n", portable_config_dir);
|
|
||||||
setenv("XDG_CONFIG_HOME",portable_config_dir,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Original working directory */
|
|
||||||
char cwd[1024];
|
|
||||||
if (getcwd(cwd, sizeof(cwd)) != NULL) {
|
|
||||||
setenv( "OWD", cwd, 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
char filename[mount_dir_size + 8]; /* enough for mount_dir + "/AppRun" */
|
|
||||||
strcpy (filename, mount_dir);
|
|
||||||
strcat (filename, "/AppRun");
|
|
||||||
|
|
||||||
/* TODO: Find a way to get the exit status and/or output of this */
|
|
||||||
execv (filename, real_argv);
|
|
||||||
/* Error if we continue here */
|
|
||||||
perror("execv error");
|
|
||||||
exit(EXIT_EXECERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,163 +0,0 @@
|
||||||
From b7875398d91821a49b7b0233950a3e687257c790 Mon Sep 17 00:00:00 2001
|
|
||||||
From: tobtoht <tob@featherwallet.org>
|
|
||||||
Date: Mon, 7 Nov 2022 11:30:46 +0100
|
|
||||||
Subject: [PATCH] no unneeded deps
|
|
||||||
|
|
||||||
---
|
|
||||||
cmake/dependencies.cmake | 78 +++++++++++++++----------------
|
|
||||||
cmake/imported_dependencies.cmake | 10 ++--
|
|
||||||
cmake/tools.cmake | 3 --
|
|
||||||
src/CMakeLists.txt | 12 ++---
|
|
||||||
4 files changed, 50 insertions(+), 53 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake
|
|
||||||
index 7c65e85..5bf5e51 100644
|
|
||||||
--- a/cmake/dependencies.cmake
|
|
||||||
+++ b/cmake/dependencies.cmake
|
|
||||||
@@ -55,45 +55,45 @@ endif()
|
|
||||||
# for distro packaging, it can be linked to an existing package just fine
|
|
||||||
set(USE_SYSTEM_SQUASHFUSE OFF CACHE BOOL "Use system libsquashfuse instead of building our own")
|
|
||||||
|
|
||||||
-if(NOT USE_SYSTEM_SQUASHFUSE)
|
|
||||||
- message(STATUS "Downloading and building squashfuse")
|
|
||||||
-
|
|
||||||
- # 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
|
|
||||||
- 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
|
|
||||||
- # for some reason, a first run may fail, but it seems just running it a second time fixes the issues
|
|
||||||
- COMMAND env PKG_CONFIG_PATH=${xz_LIBRARY_DIRS}/pkgconfig ./autogen.sh || true
|
|
||||||
- COMMAND env PKG_CONFIG_PATH=${xz_LIBRARY_DIRS}/pkgconfig ./autogen.sh
|
|
||||||
- COMMAND ${SED} -i "/PKG_CHECK_MODULES.*/,/,:./d" configure # https://github.com/vasi/squashfuse/issues/12
|
|
||||||
- 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} <SOURCE_DIR>/configure --disable-demo --disable-high-level --without-lzo --without-lz4 --prefix=<INSTALL_DIR> --libdir=<INSTALL_DIR>/lib --with-xz=${xz_PREFIX} ${EXTRA_CONFIGURE_FLAGS}
|
|
||||||
- COMMAND ${SED} -i "s|XZ_LIBS = -llzma |XZ_LIBS = -Bstatic ${xz_LIBRARIES}/|g" Makefile
|
|
||||||
- BUILD_COMMAND ${MAKE}
|
|
||||||
- BUILD_IN_SOURCE ON
|
|
||||||
- INSTALL_COMMAND ${MAKE} install
|
|
||||||
- )
|
|
||||||
-
|
|
||||||
- import_external_project(
|
|
||||||
- TARGET_NAME libsquashfuse
|
|
||||||
- EXT_PROJECT_NAME squashfuse-EXTERNAL
|
|
||||||
- LIBRARIES "<SOURCE_DIR>/.libs/libsquashfuse.a;<SOURCE_DIR>/.libs/libsquashfuse_ll.a;<SOURCE_DIR>/.libs/libfuseprivate.a"
|
|
||||||
- INCLUDE_DIRS "<SOURCE_DIR>"
|
|
||||||
- )
|
|
||||||
-else()
|
|
||||||
- message(STATUS "Using system squashfuse")
|
|
||||||
-
|
|
||||||
- import_pkgconfig_target(TARGET_NAME libsquashfuse PKGCONFIG_TARGET squashfuse)
|
|
||||||
-endif()
|
|
||||||
+#if(NOT USE_SYSTEM_SQUASHFUSE)
|
|
||||||
+# message(STATUS "Downloading and building squashfuse")
|
|
||||||
+#
|
|
||||||
+# # 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
|
|
||||||
+# 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
|
|
||||||
+# # for some reason, a first run may fail, but it seems just running it a second time fixes the issues
|
|
||||||
+# COMMAND env PKG_CONFIG_PATH=${xz_LIBRARY_DIRS}/pkgconfig ./autogen.sh || true
|
|
||||||
+# COMMAND env PKG_CONFIG_PATH=${xz_LIBRARY_DIRS}/pkgconfig ./autogen.sh
|
|
||||||
+# COMMAND ${SED} -i "/PKG_CHECK_MODULES.*/,/,:./d" configure # https://github.com/vasi/squashfuse/issues/12
|
|
||||||
+# 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} <SOURCE_DIR>/configure --disable-demo --disable-high-level --without-lzo --without-lz4 --prefix=<INSTALL_DIR> --libdir=<INSTALL_DIR>/lib --with-xz=${xz_PREFIX} ${EXTRA_CONFIGURE_FLAGS}
|
|
||||||
+# COMMAND ${SED} -i "s|XZ_LIBS = -llzma |XZ_LIBS = -Bstatic ${xz_LIBRARIES}/|g" Makefile
|
|
||||||
+# BUILD_COMMAND ${MAKE}
|
|
||||||
+# BUILD_IN_SOURCE ON
|
|
||||||
+# INSTALL_COMMAND ${MAKE} install
|
|
||||||
+# )
|
|
||||||
+#
|
|
||||||
+# import_external_project(
|
|
||||||
+# TARGET_NAME libsquashfuse
|
|
||||||
+# EXT_PROJECT_NAME squashfuse-EXTERNAL
|
|
||||||
+# LIBRARIES "<SOURCE_DIR>/.libs/libsquashfuse.a;<SOURCE_DIR>/.libs/libsquashfuse_ll.a;<SOURCE_DIR>/.libs/libfuseprivate.a"
|
|
||||||
+# INCLUDE_DIRS "<SOURCE_DIR>"
|
|
||||||
+# )
|
|
||||||
+#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")
|
|
||||||
diff --git a/cmake/imported_dependencies.cmake b/cmake/imported_dependencies.cmake
|
|
||||||
index 56d7fc0..2a709c9 100644
|
|
||||||
--- a/cmake/imported_dependencies.cmake
|
|
||||||
+++ b/cmake/imported_dependencies.cmake
|
|
||||||
@@ -3,8 +3,8 @@ include(${CMAKE_CURRENT_LIST_DIR}/scripts.cmake)
|
|
||||||
# the names of the targets need to differ from the library filenames
|
|
||||||
# this is especially an issue with libcairo, where the library is called libcairo
|
|
||||||
# therefore, all libs imported this way have been prefixed with lib
|
|
||||||
-import_pkgconfig_target(TARGET_NAME libglib PKGCONFIG_TARGET glib-2.0>=2.40)
|
|
||||||
-import_pkgconfig_target(TARGET_NAME libgobject PKGCONFIG_TARGET gobject-2.0>=2.40)
|
|
||||||
-import_pkgconfig_target(TARGET_NAME libgio PKGCONFIG_TARGET gio-2.0>=2.40)
|
|
||||||
-import_pkgconfig_target(TARGET_NAME libzlib PKGCONFIG_TARGET zlib)
|
|
||||||
-import_pkgconfig_target(TARGET_NAME libcairo PKGCONFIG_TARGET cairo)
|
|
||||||
+#import_pkgconfig_target(TARGET_NAME libglib PKGCONFIG_TARGET glib-2.0>=2.40)
|
|
||||||
+#import_pkgconfig_target(TARGET_NAME libgobject PKGCONFIG_TARGET gobject-2.0>=2.40)
|
|
||||||
+#import_pkgconfig_target(TARGET_NAME libgio PKGCONFIG_TARGET gio-2.0>=2.40)
|
|
||||||
+#import_pkgconfig_target(TARGET_NAME libzlib PKGCONFIG_TARGET zlib)
|
|
||||||
+#import_pkgconfig_target(TARGET_NAME libcairo PKGCONFIG_TARGET cairo)
|
|
||||||
diff --git a/cmake/tools.cmake b/cmake/tools.cmake
|
|
||||||
index d0941bb..c93b6b3 100644
|
|
||||||
--- a/cmake/tools.cmake
|
|
||||||
+++ b/cmake/tools.cmake
|
|
||||||
@@ -50,9 +50,6 @@ check_program(NAME autoreconf)
|
|
||||||
check_program(NAME libtoolize)
|
|
||||||
check_program(NAME patch)
|
|
||||||
check_program(NAME sed)
|
|
||||||
-check_program(NAME wget)
|
|
||||||
-check_program(NAME xxd)
|
|
||||||
-check_program(NAME desktop-file-validate)
|
|
||||||
check_program(NAME objcopy FORCE_PREFIX)
|
|
||||||
check_program(NAME objdump FORCE_PREFIX)
|
|
||||||
check_program(NAME readelf FORCE_PREFIX)
|
|
||||||
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
|
|
||||||
index 664bf2a..081523b 100644
|
|
||||||
--- a/src/CMakeLists.txt
|
|
||||||
+++ b/src/CMakeLists.txt
|
|
||||||
@@ -3,16 +3,16 @@ cmake_minimum_required(VERSION 3.6)
|
|
||||||
|
|
||||||
find_package(PkgConfig)
|
|
||||||
|
|
||||||
-pkg_check_modules(glib glib-2.0>=2.40 IMPORTED_TARGET)
|
|
||||||
-pkg_check_modules(gobject gobject-2.0>=2.40 IMPORTED_TARGET)
|
|
||||||
-pkg_check_modules(gio gio-2.0>=2.40 IMPORTED_TARGET)
|
|
||||||
-pkg_check_modules(zlib zlib IMPORTED_TARGET)
|
|
||||||
-pkg_check_modules(cairo cairo IMPORTED_TARGET)
|
|
||||||
+#pkg_check_modules(glib glib-2.0>=2.40 IMPORTED_TARGET)
|
|
||||||
+#pkg_check_modules(gobject gobject-2.0>=2.40 IMPORTED_TARGET)
|
|
||||||
+#pkg_check_modules(gio gio-2.0>=2.40 IMPORTED_TARGET)
|
|
||||||
+#pkg_check_modules(zlib zlib IMPORTED_TARGET)
|
|
||||||
+#pkg_check_modules(cairo cairo IMPORTED_TARGET)
|
|
||||||
|
|
||||||
add_subdirectory(xdg-basedir)
|
|
||||||
add_subdirectory(libappimage_hashlib)
|
|
||||||
add_subdirectory(libappimage_shared)
|
|
||||||
-add_subdirectory(libappimage)
|
|
||||||
+#add_subdirectory(libappimage)
|
|
||||||
|
|
||||||
# Export the package for use from the build-tree
|
|
||||||
# (this registers the build-tree with a global CMake-registry)
|
|
||||||
--
|
|
||||||
2.38.1
|
|
||||||
|
|
46
contrib/depends/patches/libfuse/no-dlopen.patch
Normal file
46
contrib/depends/patches/libfuse/no-dlopen.patch
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
--- a/lib/fuse.c
|
||||||
|
+++ b/lib/fuse.c
|
||||||
|
@@ -227,32 +227,6 @@ static struct fuse_module *fuse_modules;
|
||||||
|
|
||||||
|
static int fuse_load_so_name(const char *soname)
|
||||||
|
{
|
||||||
|
- struct fusemod_so *so;
|
||||||
|
-
|
||||||
|
- so = calloc(1, sizeof(struct fusemod_so));
|
||||||
|
- if (!so) {
|
||||||
|
- fprintf(stderr, "fuse: memory allocation failed\n");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- fuse_current_so = so;
|
||||||
|
- so->handle = dlopen(soname, RTLD_NOW);
|
||||||
|
- fuse_current_so = NULL;
|
||||||
|
- if (!so->handle) {
|
||||||
|
- fprintf(stderr, "fuse: %s\n", dlerror());
|
||||||
|
- goto err;
|
||||||
|
- }
|
||||||
|
- if (!so->ctr) {
|
||||||
|
- fprintf(stderr, "fuse: %s did not register any modules\n",
|
||||||
|
- soname);
|
||||||
|
- goto err;
|
||||||
|
- }
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
-err:
|
||||||
|
- if (so->handle)
|
||||||
|
- dlclose(so->handle);
|
||||||
|
- free(so);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -314,7 +288,6 @@ static void fuse_put_module(struct fuse_module *m)
|
||||||
|
else
|
||||||
|
mp = &(*mp)->next;
|
||||||
|
}
|
||||||
|
- dlclose(so->handle);
|
||||||
|
free(so);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.40.0
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
#include "squashfuse_dlopen.h"
|
|
||||||
|
|
||||||
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";
|
|
||||||
|
|
|
@ -1,262 +0,0 @@
|
||||||
#ifndef SQFS_DLOPEN_H
|
|
||||||
#define SQFS_DLOPEN_H
|
|
||||||
|
|
||||||
//#define ENABLE_DLOPEN
|
|
||||||
|
|
||||||
#ifdef ENABLE_DLOPEN
|
|
||||||
|
|
||||||
#include <dlfcn.h>
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <utime.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/statvfs.h>
|
|
||||||
#include <sys/uio.h>
|
|
||||||
|
|
||||||
|
|
||||||
/*** dlopen() stuff ***/
|
|
||||||
|
|
||||||
#define LIBNAME "libfuse.so.2"
|
|
||||||
|
|
||||||
void *libhandle;
|
|
||||||
int have_libloaded;
|
|
||||||
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 */
|
|
||||||
|
|
|
@ -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 <fuse.h>
|
|
||||||
+#include "squashfuse_dlopen.h"
|
|
||||||
+#ifndef ENABLE_DLOPEN
|
|
||||||
+# include <fuse.h>
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
--- a/hl.c
|
|
||||||
+++ b/hl.c
|
|
||||||
@@ -33,6 +33,7 @@
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
+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 <fuse_lowlevel.h>
|
|
||||||
+#include "squashfuse_dlopen.h"
|
|
||||||
+#ifndef ENABLE_DLOPEN
|
|
||||||
+# include <fuse_lowlevel.h>
|
|
||||||
+#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 <unistd.h>
|
|
||||||
-#include <fuse_lowlevel.h>
|
|
||||||
+
|
|
||||||
+#include "squashfuse_dlopen.h"
|
|
||||||
+#ifndef ENABLE_DLOPEN
|
|
||||||
+# include <fuse_lowlevel.h>
|
|
||||||
+#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;
|
|
||||||
}
|
|
|
@ -67,7 +67,8 @@ store_path() {
|
||||||
# includes/libs
|
# includes/libs
|
||||||
NATIVE_GCC="$(store_path gcc-toolchain)"
|
NATIVE_GCC="$(store_path gcc-toolchain)"
|
||||||
NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)"
|
NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)"
|
||||||
QT_LIBS="$(store_path xcb-util):$(store_path xcb-util-renderutil):$(store_path xcb-util-keysyms):$(store_path xcb-util-cursor):$(store_path xcb-util-image):$(store_path xcb-util-wm)"
|
QT_LIBS="$(store_path xcb-util):$(store_path xcb-util-renderutil):$(store_path xcb-util-keysyms):$(store_path xcb-util-cursor):$(store_path xcb-util-image):$(store_path xcb-util-wm):"
|
||||||
|
QT_LIBS_LIBS="$(echo "${QT_LIBS}" | sed 's/:/\/lib:/g')"
|
||||||
|
|
||||||
unset LIBRARY_PATH
|
unset LIBRARY_PATH
|
||||||
unset CPATH
|
unset CPATH
|
||||||
|
@ -82,6 +83,7 @@ export CPLUS_INCLUDE_PATH="${NATIVE_GCC}/include/c++:${NATIVE_GCC}/include"
|
||||||
export OBJC_INCLUDE_PATH="${NATIVE_GCC}/include"
|
export OBJC_INCLUDE_PATH="${NATIVE_GCC}/include"
|
||||||
export OBJCPLUS_INCLUDE_PATH="${NATIVE_GCC}/include/c++:${NATIVE_GCC}/include"
|
export OBJCPLUS_INCLUDE_PATH="${NATIVE_GCC}/include/c++:${NATIVE_GCC}/include"
|
||||||
export QT_LIBS
|
export QT_LIBS
|
||||||
|
export QT_LIBS_LIBS
|
||||||
|
|
||||||
prepend_to_search_env_var() {
|
prepend_to_search_env_var() {
|
||||||
export "${1}=${2}${!1:+:}${!1}"
|
export "${1}=${2}${!1:+:}${!1}"
|
||||||
|
|
Loading…
Reference in a new issue