* Add psignal module for centralized signal handling
- Added pclsync/psignal.h with psignal_register() and psignal_check_pending() API
- Added pclsync/psignal.c with async-signal-safe handlers for SIGINT, SIGTERM, SIGHUP
- Implements flag-based deferred signal handling pattern
* Integrate psignal into main loop and remove conflicting handlers
- Added extern "C" linkage to psignal.h for C++ compatibility
- Integrated psignal_check_pending() into pclsync_lib.cpp main loop
- Integrated psignal_check_pending() into ptimer.c timer loop
- Removed conflicting signal handlers from pfs.c
* Migrate psync_set_signal to psignal module
- Added psignal_set_custom_handler() to psignal.h and psignal.c
- Replaced psync_set_signal() calls in pfs.c with psignal_set_custom_handler()
- Centralizes all signal handling in psignal module
---------
Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Renamed psync_delete_sync_by_folderid to pfolder_delete_sync_by_id to align with pfolder API naming conventions. Updated all callers.
Fixes#100
Co-authored-by: Levi Neely <lkn@darkstar.example.net>
psync_status.status is written in pstatus_set() (pstatus.c:263) after
releasing status_internal_mutex, while status_change() (pclsync_lib.cpp:435)
reads it concurrently from the callback thread without any lock. TSan
reports the race between T9 (write in pstatus_set) and the status callback
thread (read in status_change).
Replace all reads and writes of psync_status.status with
__atomic_load_n/__atomic_store_n (__ATOMIC_RELAXED) across pstatus.c,
pqevent.c, and pclsync_lib.cpp. In status_change_thread, capture the
atomic value once into cur_status before the condition to avoid multiple
inconsistent loads. In status_change(), capture cur_status at entry and
use it throughout, also propagating it to the copied status_ struct.
Closes#334
Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- Wrap std::stoull() in try/catch to prevent daemon crash on invalid folder ID
- Add proper read loop for RPC messages to handle partial reads
- Validate msg->length before memcpy to prevent heap over-read
- Handle daemon bugs gracefully (EOF before full message)
- Fix operator precedence in sync remove command
Fixes#205, #206
Co-authored-by: Levi Neely <lkn@darkstar.example.net>
* Fix debug build segfault: add strong overrides for psql_lock/unlock functions
The weak/strong symbol approach requires that psql.c undefs the debug
macros to define function implementations. This means functions in psql.c
call psql_lock()/psql_unlock() as functions, not macros.
In debug builds, these must be strong overrides that call the _do_
variants to properly maintain lockctr/rdlockctr. Without these overrides,
the weak stubs are used which don't update counters, causing assertion
failures in psql_unlock().
Added strong overrides in psql_debug.c for:
- psql_lock() -> psql_do_lock(__FILE__, __LINE__)
- psql_rdlock() -> psql_do_rdlock(__FILE__, __LINE__)
- psql_statement() (calls psql_do_lock directly)
Also made psql_statement, psql_start, and all query/prepare functions
weak in psql.c to allow debug overrides.
Fixes#138
* Fix umask and password memory wipe
- Set umask(0077) in daemonize() to prevent world-readable files
- Wipe password from memory after psync_set_user_pass()
Fixes#203, #204
---------
Co-authored-by: Levi Neely <lkn@darkstar.example.net>
* Fix#103: Refactor putil to use putil_ namespace and enforce encapsulation
All public functions in putil now use the putil_ prefix (e.g., putil_strdup,
putil_strcat, putil_time_format, putil_base64_encode, etc.). Internal
variables (normalize_table, base64_reverse_table) and the constructor remain
static. Updated all 34 call-site files across pclsync accordingly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix#96: Refactor pfs to use pfs_ namespace and enforce encapsulation
All public functions in the pfs module renamed from psync_fs_ to pfs_
(e.g., pfs_update_openfile, pfs_refresh, pfs_start, pfs_stop, etc.).
Extern vars psync_fake_prefix/psync_fake_prefix_len renamed to
pfs_fake_prefix/pfs_fake_prefix_len. Functions only used within pfs.c
(pfs_update_openfile_fileid_locked, pfs_chown) made static. Updated all
call sites across 17 files including pclsync_lib.cpp.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Refactor pfsxattr to use pfs_xattr_ namespace
All psync_fs_ prefixed functions in the pfsxattr module renamed to
pfs_xattr_ (e.g., pfs_xattr_set, pfs_xattr_get, pfs_xattr_list,
pfs_xattr_remove, pfs_xattr_file_deleted, pfs_xattr_task_to_file, etc.).
Local macro psync_fs_set_thread_name renamed to pfs_xattr_set_thread_name.
Internal static helpers (delete_object_id, update_object_id,
xattr_get_object_id_locked) remain static and unchanged.
Updated all call sites in pfs.c, pfsupload.c, and pdiff.c.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Rename pfs_xattr_ namespace to pfs_xatr_
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Refactor pfs sub-modules to use namespaced function prefixes
- pfscrypto_* → pfs_crpt_*
- psync_fsstatic_* → pfs_stat_*
- psync_fsupload_* → pfs_upld_*
- psync_fstask_* → pfs_task_* (functions only; typedefs unchanged)
- psync_fsfolder_*/psync_fsfolderid_*/psync_fsfolderflags_*/
get_decname_for_folder/psync_get_folderid → pfs_fldr_*
Type names, macro constants, and typedef aliases are unchanged.
Updated all call sites across 17 files.
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>
* Fix#90: Support 2FA when running as a daemon
In daemon mode, when PSTATUS_TFA_REQUIRED fires:
- Automatically send an SMS 2FA code via psync_tfa_send_sms()
- Log delivery details to syslog with instructions to use
`echo 'tfa CODE' | pcloudcc -k`
- Block on a condition variable until the code arrives via RPC
Add a new `tfa <code>` command to the pcloudcc -k control interface.
This sends the code to the daemon over the existing Unix socket RPC
channel (SENDTFA message type).
Bad codes (PSTATUS_BAD_TFA_CODE) are handled: the daemon logs a syslog
warning and waits for a corrected code without re-sending SMS.
Devices are trusted by default (trusted=1 in psync_tfa_set_code) so
repeated 2FA prompts are avoided for the configured trust period.
TFA codes are wiped from memory after use.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add auth command: supply password to running daemon
Mirrors the tfa command pattern. When PSTATUS_LOGIN_REQUIRED fires in
daemon mode, read_password() now logs a syslog notice and blocks on a
condition variable rather than calling exit(1).
The new `auth <password>` control command (SENDAUTH RPC type) signals
the condvar and unblocks the daemon. Usage:
echo 'auth PASSWORD' | pcloudcc -k
The password is wiped from the CLI-side buffer immediately after the
RPC call. putil_wipe() is used for both the tfa and auth transient
strings on the sending side.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add status command: show current sync state from CLI
Adds a `status` (alias `st`) command to the interactive CLI and to the
pcloudcc -k control interface. The daemon-side handler calls
psync_get_status(), formats the status name plus download/upload
strings, and writes the result to shared memory. The client reads and
prints it.
Example output:
Status: READY
Download: idle
Upload: idle
Also works non-interactively:
echo 'status' | pcloudcc -k
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>
Wire psync_pause() and psync_resume() from the C library into the RPC
command layer, registering SYNCPAUSE and SYNCRESUME handlers and exposing
them as 'sync pause' and 'sync resume' CLI subcommands.
Note: daemon quit is already handled by the existing 'finalize' command,
which calls psync_destroy() and exits the daemon process cleanly.
Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add new 'pending' command (alias 'p') to check for pending transfers
- Enhance 'finalize' command to warn about pending transfers
- Prompt for confirmation in interactive mode before shutdown
- Use psync_get_status() API for reliable transfer detection
- Shows upload/download counts separately
- Fix mbedtls 3.6 compatibility issues in pssl.c
- Update Makefile for mbedtls 3.x static linking
- Enhance read_tfa_code() to offer SMS option
- User can type 'sms' to receive code via SMS
- Display phone number when SMS is sent
- Falls back to authenticator app if SMS fails
- Uses existing psync_tfa_send_sms() API
- DoD 5220.22-M compliant memory wipe replaces single-pass zero wipe
- Wipe in-memory request and response messages before freeing
- Wipe in-memory private keys and salt data before freeing
- Wipe all passwords on unlink / logout
- Wipe crypto password on all pcryptofolder_unlock return paths
* pcommands.h for command ids
* remove compiler compat junk
* transient and unnecessary includes resolved
* unnecessary goto
* function naming and whatnot
* use readline for better command line UX
* add readline to CI workflow
* code cleanup and removal
- remove useless wrapper functions
- remove obfuscating typedefs
- code reorganization and reformatting
- function renames for clarification
* prepare pcompat.h for decomposition
* remove dead function psync_rebuild_icons, reorganize pfsstatic.c headers
* separate pdevice from pcompat
* reorg function prototypes, remove more compat stuff
* renamed mutex for brevity
* remove dead debug code; plibs version is more sophisticated
* remove dead code, stale comments
* moved psync_delete_cached_crypto_keys to psynclib
* forgot to remove the function prototype from pdiff.h
* reorganized functions by accessibility, inlined useless psync_cache_contacts function
* remove unused header
* ppath object decomposed from pcompat
* ppath namespace
* ppath struct renames
* ppath final cleanup
* refactor, remove compatibility code
* format
* prun decomposed from pcompat for thread mgmt
* slim down prun.c
* remove useless comments
* move pagesize to pmemlock, pmemlock namespace
* pmem decomposed from pcompat, pmem namespace
* decompose psys from pcompat
* fix psys function names, remove more compatibility junk
* prand decomposed from pcompat
* psock decomposed from pcompat
* types renamed for ns consistency, brevity
* cleanup psock, remove unused proxy code
* remove unused headers psock
* putil for utility macros and functions
* forgot to move some psock constants
* move time macro to psys
* eliminate pcompat completely; new pfile namespace
* cleanup
- moved thread name definition
- explicit externs in implementation instead of headers for now
- better extern name
* small lsp error fixes
* simplify messaging and remove serialize/deserialize
- messaging is reverted to API requests and responses only
- remove serialize and deserialize functions
- implement shared memory (pshm) for overlay callback return values
* fix memory leak
Fix#64 and #71
* list_sync_folders seems to work
* list_sync_folders breaks with sync folders in db; message size problem?
* fixed sync folders list
* fix double free and buffer overflow
* wip: add and remove sync folder; need to fix request->value in instance_thread
* remove comment
* removed pclsync_lib_c.{h,cpp}
* cleanup get_answer_to_request
* update comment
* changed reply struct to type response containing payload and msg
* cleanup
* refactored overlay_client, and poverlay; added docs
* better naming
* sock path in poverlay_protocol.h
* clarify comment
* refactor psync_overlay_get_response
* clarifications
* response_messages work with and without payload
* removed commented code
* syncadd works, but i need to fix the error handling
* remove sync folder
* remove commented code, change printfs to debug or simply remove
* removed unnecessary print
* removed more prints
* removed dead var
* update error handling in add_sync_folder, fix memleak
* simplified finalize
* openssl is a dependency
* openssl is not a real dpendency
* static link by default
* wip: build containers
* rm comments
* build containers, fix DEADLYSIGNAL on run with no args
* debug tools in deb/ubuntu, fix#44
* no slack container :(
* ensure P_LINUX_OS always defined
* error check fuse unmount ops
* fsanitize=thread temporarily
* undo
* clang static analysis
* fix dead assignment
* makefile quality of life stuff
* make install and uninstall; ignore scan results
* addressed dead assignments from static analysis
* debug and release builds possible
* gcc still default compiler
* debug symbols on debug build only
* reorg source tree, link system mbedtls
* remove cmakelists.txt
* update ci workflow
* -Werror to -Wall
* libpcloudcc_so in makefile
* single makefile works
* removed extra makefiles