* Migrate to FUSE 3.x API - Update FUSE_USE_VERSION from 26 to 30 - Replace fuse_mount/fuse_unmount with fuse_session_mount/fuse_session_unmount - Update fuse_new() to take args first, remove channel parameter - Add flags parameter to readdir handler (enum fuse_readdir_flags) - Add flags parameter to rename handler (for renameat2 support) - Update filler function calls to include FUSE_FILL_DIR_PLUS flag - Merge ftruncate into truncate handler (FUSE 3 combines them) - Update fuse_loop_mt to fuse_loop_mt_31 with loop config - Link against libfuse3 instead of libfuse - Remove fuse_chan usage (deprecated in FUSE 3) Addresses #342 * Remove deprecated FUSE options nonempty and hard_remove - nonempty: Removed in FUSE 3.0, mounting on non-empty directories is now default behavior - hard_remove: High-level API option not available in FUSE 3, immediate unlink is standard These options are no longer recognized by FUSE 3 and cause mount errors. * Fix init handler signature for FUSE 3 FUSE 3 init handler requires struct fuse_config* parameter. This parameter provides access to high-level API configuration options that can be modified during initialization. Without this parameter, the init handler signature is incompatible with FUSE 3, causing filesystem operations to fail. * Add FUSE 2/3 backward compatibility Automatically detects and builds against either FUSE 2 or FUSE 3: - detect_fuse.sh script checks for fuse3 or fuse pkg-config - Makefile dynamically sets FUSE_USE_VERSION, CFLAGS, and LDFLAGS - Conditional compilation (#if FUSE_USE_VERSION >= 30) for API differences: * init handler signature (fuse_config parameter) * readdir handler signature (flags parameter) * rename handler signature (flags parameter) * truncate handler signature (fuse_file_info parameter) * filler function calls (flags parameter) * fuse_loop_mt vs fuse_loop_mt_31 * mount/unmount sequence (fuse_session_mount vs fuse_mount) * ftruncate operations struct member Maintains full compatibility with both FUSE 2.x (Debian Bookworm) and FUSE 3.x (Debian Testing+) without requiring separate code branches. * Add FORCE_FUSE build option and fix hardcoded version - Remove hardcoded FUSE_USE_VERSION defines from source files - Add FORCE_FUSE=2 or FORCE_FUSE=3 Makefile option to override detection - Fix FUSE 2 channel tracking (psync_fuse_channel variable) - Properly store and use channel in mount/unmount for FUSE 2 Usage: make # Auto-detect (prefers FUSE 3) make FORCE_FUSE=2 # Force FUSE 2 build make FORCE_FUSE=3 # Force FUSE 3 build Verified both FUSE 2 and FUSE 3 builds work correctly. * Fix CI/CD: Add fallback for systems without pkg-config - detect_fuse.sh now checks for pkg-config availability first - Falls back to checking for header files in standard locations - Makefile provides default CFLAGS when pkg-config unavailable - Fixes build on minimal CI/CD environments Fallback locations checked: - /usr/include/fuse3/fuse.h (FUSE 3) - /usr/local/include/fuse3/fuse.h (FUSE 3) - /usr/include/fuse/fuse.h (FUSE 2) - /usr/local/include/fuse/fuse.h (FUSE 2) * Enhance FUSE detection for non-standard locations Multi-stage detection strategy: 1. Try pkg-config (fastest, most reliable) 2. Search common header locations: - /usr/include, /usr/local/include - /opt/local/include, /opt/include 3. Compiler test as last resort: - Attempts to preprocess #include <fuse.h> - Tests both FUSE 3 and FUSE 2 versions This handles: - Minimal CI/CD environments (no pkg-config) - Non-standard install locations (Homebrew, custom builds) - Distro-specific paths (BSD, macOS, custom Linux) The compiler test ensures detection works even when headers are in unusual locations that gcc can find via its search paths. * Support FUSE 3.12+ API - Use fuse_loop_mt_312 for FUSE 3.12+, fuse_loop_mt_31 for 3.0-3.11 - Conditionally add fuse_file_info param to getattr/chmod/chown/utimens - Replace fuse_session_mount/unmount with fuse_mount/unmount - Tested with FUSE 3.18 on Debian forky * Fix pcl-1ib: correct FUSE 3.x handler signatures and loop_mt call - Replace FUSE_MINOR_VERSION >= 12 checks with FUSE_USE_VERSION >= 30 for getattr/chmod/chown/utimens handler signatures; FUSE 3.x always requires the extra struct fuse_file_info* parameter — the wrong signature caused type mismatches and "Transport endpoint is not connected" failures - Replace non-existent fuse_loop_mt_312 extern with correct conditional: FUSE_USE_VERSION >= 32 uses fuse_loop_mt(f, &config), else fuse_loop_mt_31(f, clone_fd) - Fix inverted return logic in is_fuse3_installed_on_system(): was returning 0 on success (when fusermount3 found), now correctly returns non-zero Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Remove unused is_fuse3_installed_on_system() from pfs.c The function was static and had no remaining call sites after the -ononempty/-ohard_remove args block was cleaned up, producing a -Wunused-function warning. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Restore shutdown_requested definition removed during rebase conflict resolution The variable is declared extern in pfs.h and referenced in both pfs.c (psync_signal_handler) and control_tools.cpp; the definition must exist in pfs.c. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix pfs_creat: missing canmodify assignment causes EACCES on write pfs_creat called pfs_create_file() but never set of->canmodify, leaving it zero-initialized. pfs_write and pfs_ftruncate both check canmodify and return -EACCES if false, making all writes to newly created files fail with Permission denied. All five open paths in pfs_open set canmodify correctly (added in #326), but pfs_creat was missed. Fix by applying the same pattern immediately after psql_unlock(), while fpath is still in scope. Caught during FUSE 2/3 regression testing (Phase 2 write test). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Extend CI matrix: add FUSE 2, FUSE 3 legacy/current/forky build jobs Replaces single build job with four jobs covering all tested FUSE configs: - fuse2: debian:trixie + libfuse-dev (FUSE_USE_VERSION=26) - fuse3-legacy: ubuntu:20.04 + libfuse3-dev 3.9.x (fuse_loop_mt_31 path) - fuse3-current: ubuntu:22.04 + libfuse3-dev 3.12.x - fuse3-forky: debian:forky + libfuse3-dev 3.18.1 Each job verifies correct symbol linkage after build. Runtime mount tests are outside CI scope (require privileged containers with /dev/fuse). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * CI: replace Ubuntu 20.04/22.04 with ubuntu:24.04 for FUSE3 job ubuntu:20.04 has old compiler (g++-9) and mbedTLS 2.x. ubuntu:22.04 ships mbedTLS 2.28.x; incompatible with our mbedTLS 3.x-only code. ubuntu:24.04 has mbedTLS 3.x and libfuse3 3.16.x, covering the 3.12-3.17 range. FUSE3 < 3.12 is verified locally but not representable in CI without fighting old toolchains. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * CI: add archlinux:latest job for rolling-release compatibility Arch Linux is a rolling distro shipping latest fuse3, mbedtls 3.x, and gcc — useful as an early-warning canary for future API breakage. Also directly covers the maintained Arch package. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * CI: add fedora:41 and fedora:latest jobs with mbedtls3-devel Fedora ships both mbedtls 2.x and 3.x; explicitly install mbedtls3-devel to match our mbedTLS 3.x-only requirement. fedora:41 pins a known-good release; fedora:latest tracks current as a rolling canary alongside Arch. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * README: add compatibility matrix with CI badge references Documents the 6-distro build matrix tested in CI, mbedTLS 3.x requirement, and notes on manual runtime mount testing coverage. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix CI package names; clean up README compatibility matrix - Fedora 41: mbedtls3-devel -> mbedtls3.6-devel (correct versioned name) - Fedora latest (43): mbedtls3-devel -> mbedtls-devel (now ships 3.6.5) - Ubuntu 24.04: replaced with debian:trixie FORCE_FUSE=3 (Ubuntu has no mbedTLS 3.x in standard repos; trixie has both libfuse3-dev and mbedTLS 3.x) - README: remove CI badge links from compatibility matrix Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Levi Neely <lkn@darkstar.example.net> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| .github/workflows | ||
| dev | ||
| doc | ||
| pclsync | ||
| tests | ||
| .clang-format | ||
| .clang-tidy | ||
| .envrc | ||
| .gitignore | ||
| CLI11.hpp | ||
| LOG-MANAGEMENT.md | ||
| Makefile | ||
| README.md | ||
| control_tools.cpp | ||
| control_tools.h | ||
| default.nix | ||
| detect_fuse.sh | ||
| flake.lock | ||
| flake.nix | ||
| main.cpp | ||
| pcloudcc.logrotate | ||
| pclsync_lib.cpp | ||
| pclsync_lib.h | ||
| rpcclient.cpp | ||
| rpcclient.h | ||
README.md
Introduction
pcloudcc is simple linux console client for pCloud cloud storage derived from the console-client developed by pCloud. This version is independently maintained by me, whose only affiliation with pCloud is as a user of their services. Due credit goes to Anton Titov, Ivan Stoev, and pCloud.
Supported Platforms & Distributions
The target operating system and platform for this program is linux/amd64, and has been reported to work on linux/aarch64. Program behavior on 32-bit architectures is considered undefined.
I aim to support as many distributions as possible. I maintain a package for AUR and Nix. I do not plan on providing or maintaining any other packages, but encourage anyone interested in doing so for their own distributions.
Compatibility Matrix
| Distribution | FUSE |
|---|---|
| Debian trixie | 2.x |
| Debian trixie | 3.x |
| Arch Linux (rolling) | 3.x latest |
| Fedora 41 | 3.x |
| Fedora (latest) | 3.x latest |
| Debian forky | 3.18+ |
All configurations require mbedTLS 3.x. Runtime mount testing was performed manually on FUSE 2 (libfuse 2.9.x), FUSE 3 (libfuse3 3.10.5), and FUSE 3.18+ (Debian forky container).
Notices
Security Notice
My code audits are best-effort, and I make security enhancements as I identify problems. However, I do not promise that this program is free of even older and well-known security vulnerabilities. Therefore, I recommend using this program only on a trusted single-user system. Security-related code audits and contributions are most welcome!
See Also
-
Contributing: Read this if you're interested in helping out. Short version: do your best to write good code, be courteous to maintainers, and most importantly: have fun!
-
Building: Read this if you're not sure how to build
pcloudcc. For most users,makeandmake installare enough. -
mbedtls 3.x migration notes: Read this if you use an older distribution such as
debian:bookwormand encounter build problems. -
Device Validation Guide: Read this if you're running
pcloudccand encounter device validation-related errors. -
Usage Guide: Read this if you're unsure how to start using
pcloudcc. -
Log Management Guide: Read this to configure log rotation, cache size limits, and custom log paths. To set up automatic log rotation, copy
pcloudcc.logrotateto/etc/logrotate.d/pcloudcc. -
pcloudcc-service: Container-based systemd service for running
pcloudccin userspace with podman. Includes multi-stage Dockerfile that buildspcloudccfrom source and Quadlet systemd unit for automated background syncing.