DRAFT — not yet tested end-to-end with a live XMPP session.
New commands:
/history export [<jid>] — copy messages from SQLite to flat-file
/history import [<jid>] — copy messages from flat-file to SQLite
Both merge with existing data; duplicates are skipped using stanza-id
or a SHA-256 fallback key (timestamp + sender + body prefix).
Implementation (src/database_export.c):
- Export: paginate SQLite via get_previous_chat, read existing flatfile
for dedup, write merged result via ff_write_line + atomic rename
- Import: parse flatfile lines via ff_parse_line, build dedup set from
SQLite, insert new messages via add_incoming (preserves original
timestamps for both directions)
- List all contacts: db_sqlite_list_contacts() queries UNION of
DISTINCT from_jid/to_jid; flatfile enumerates flatlog directories
Wiring:
- database.h: declare export/import functions + db_sqlite_list_contacts
- database_sqlite.c: add db_sqlite_list_contacts()
- cmd_defs.c: add export/import to /history synopsis and args
- cmd_funcs.c: add export/import handlers in cmd_history()
- cmd_ac.c: add 'export' and 'import' to history_ac
- Makefile.am: add database_export.c to core_sources
- stub_database.c: add stubs for test linking
- profanity.1: document export/import in man page
All code guarded with #ifdef HAVE_SQLITE — builds cleanly without it.
Build system:
- Add --without-sqlite configure flag (AM_CONDITIONAL BUILD_SQLITE)
- Guard database_sqlite.c with HAVE_SQLITE in Makefile.am, database.c,
database.h and stub_database.c
- Fall back to flatfile when SQLite not compiled in
Security (database_flatfile.c):
- MAM dedup: skip incoming messages with duplicate stanza-id (archive_id)
- LMC sender validation: reject corrections from mismatched JIDs
- Add flock() advisory locking to prevent interleaved writes from
concurrent instances
- Check fprintf return when writing file header
Autocomplete (cmd_ac.c):
- Add 'flatfile' to /privacy logging autocomplete
- Add dedicated /history autocomplete with on/off/verify (was boolean-only)
Code quality:
- Fix fwrite return type: size_t not ssize_t (database_flatfile_parser.c)
- Fix mixed allocators in ff_readline: use malloc() consistently for
overlength-line fallback instead of g_strdup()
- Fix index alignment in _ff_state_extend: use local counter so index
step doesn't depend on total_lines from initial build
Documentation:
- Fix page: correct directory structure (history.log not per-day files)
- Fix page: add aid:{archive_id} to line format example
- Fix page: missing newline before .SH BUGS
Replace per-contact directory structure with a single flat file per contact.
Each file uses pipe-delimited records with a sparse byte-offset index
that is rebuilt on demand and cached in memory.
- Rewrite _ff_write_record / _ff_read_records for single-file format
- Add sparse index (every Nth record) for O(log N) seek on history read
- Cursor-based pagination: _ff_get_previous_chat uses saved byte offset
- LMC corrections applied in-place during read (_ff_apply_lmc)
- Newline escaping (\n) in message bodies for line-based storage
- Simplify verify: parse + timestamp order + LMC reference check
- Update parser helpers for new field layout
Add pluggable storage backend abstraction (vtable) to the database layer,
allowing selection between SQLite (default) and a new flat-file backend
that stores messages as human-readable plain text files.
New files:
- database_sqlite.c: extracted SQLite backend from database.c
- database_flatfile.c: plain text backend with tolerant parser,
LMC correction chains, UTF-8/BOM/CRLF handling, integrity checks
Commands:
- /privacy logging flatfile — switch to flat-file backend
- /history verify [<jid>] — check integrity of stored history
Fixes:
- Add missing 'off' guard in flatfile backend
- Enable CHLOG/HISTORY prefs when switching to flatfile mode
Logs stored in ~/.local/share/profanity/flatlog/{account}/{contact}/{date}.log
Format: {ISO8601} [{type}|{enc}|id:{id}|corrects:{id}] {sender}: {message}
Updated: CHANGELOG, CONTRIBUTING.md, profrc.example, man page, cmd_defs,
Makefile.am, test stubs, functional test support (PROF_FLATFILE=1)
Per XEP-0030 section 3.1: 'if an entity has no associated items,
it MUST return an empty <query/> element.'
The client should display 'No service discovery items for X' when
receiving an empty result, not silently ignore it.
Previous version introduced in commit f28655c5c (2016-05-08) which added an early
return when child == NULL, preventing the message from being shown.
Major changes:
Run 4 build configurations in parallel with Valgrind on Linux
Add test failure detection verification (meta-test)
Port allocation per build to prevent conflicts in parallel runs
Add --coverage-only flag for dedicated coverage builds
Code quality:
Add TEST_GROUPS constant, CMOCKA patterns, helper functions
Organize ci-build.sh into sections
Remove -c http.sslverify=false from all git clones
(enables proper TLS verification, closes MITM risk).
Explicitly install ca-certificates in every CI Docker image.
Split functional tests into 4 parallel groups and add check-functional-parallel target (~3x faster CI runs).
Add branch-aware LCOV coverage reporting with new --enable-coverage option and lcov summary in CI pipeline.
Enable ccache via -C configure flag for faster recompilations.
Install lcov in all Docker images and use --depth 1 git clones + parallel make -j$(nproc) for quicker container builds.
Update CONTRIBUTING.md with instructions for parallel test groups and adding new ones.
All changes are tightly related CI/performance improvements developed in sequence. No external service uploads (e.g. Codecov skipped due to Gitea incompatibility).
- Add prof.supp with pthread TLS suppressions
- Update ci-build.sh with test configurations
- Document functional test best practices in CONTRIBUTING.md
- Replace stbbr_for_id() with stbbr_for_query()/stbbr_send()
- Content-based stubbing matches stanzas by namespace instead of ID
- Use regex assertions for flexible output matching
- Fix timing issues in chat_session and presence tests
- Add TERM=xterm-256color for PTY support in functional tests
- Disable SSL verification for git clone in restricted networks
- Add error handling for Arch reflector installation
The /connect command can take: account + server <s> + port <p> + tls <t> + auth <a>
which totals 9 arguments, not 7. This fixes argument parsing for full command usage.
- Track unread message indicators and paging state in the window component
- Clear and restore unread markers correctly when navigating between conversations
- Suppress buffer updates and message printing while viewing history to prevent
unwanted scroll jumps and viewport lock
Also includes minor code-style, whitespace, and comment cleanups as well as
updated documentation for metrics and buffer handling.
Add debug output tracking connection lifecycle.
- Track disconnects and reconnects
- Record session login, logout, and reconnection attempts
- Use [CONNDBG] tag for easy log filtering
Add prof_get_current_window API to retrieve the title of the currently active window, matching the titlebar display.
The feature is especially useful to track currently used plugin window.
Remove autodisable logic (prefs_set_autoping(0)) and early return in autoping
to treat intermittent false negatives from connection_supports(XMPP_FEATURE_PING).
Add one-time error display with debug features print for monitoring; warn on first failing
check without aborting to maintain functionality while investigating root cause.
Prior commit (6ad8a190) did not properly handle overflow by long (9000 lines) message,
to address this issue, multiple changes were made:
- Add lines recalculation on win_redraw
- Move `prof_buff_t` struct to header file so its lines could be externally changed
- Call win_redraw once overflow is detected: it allows to recalculate sizes in lines and apply changes to the buffer
Refactor buffer trimming logic to use dynamic line counts (_lines per entry)
against PAD_SIZE (10k) instead of fixed entry count (MAX_BUFFER_SIZE=200). This
prevents premature cleanups for short messages, reduces scrolling disruptions
during history loads, and scales better with rendered content size.
Delete oldest/newest entry from opposite end only when total lines approach
ncurses pad limit, minimizing unnecessary deletions.
Simplify overflow warning log by removing unused MAX_BUFFER_SIZE reference.
Update buffer.c header for improved DX:
- Add detailed module overview explaining role (in-memory UI buffer vs. DB
persistence), key features (trimming, metadata), and integration (ncurses).
- Shorten copyright/license boilerplate to concise pointer (LICENSE ref).
- Add fork notice; preserve original copyrights per GPLv3.
Partially addresses #36 (stuck scroll mitigation via fewer cleanups)
Related to #36
- Defined callback protocols for register_command, register_timed, win_create.
- Fixed Sphinx callable warnings with proper type hints.
- Align docs with the code
- Replace Profanity with CProof in all docstrings and examples.
- Remove Python 2 and unicode references, using Python 3 str types.
- Add type hints for all parameters and return types.
- Use :: for code blocks with blank lines to fix Sphinx errors.
- Improve wording for clarity and integrated examples into docstrings.
- Organize functions into logical sections with RST comments.
- Use double backticks for inline literals to resolve Sphinx warnings.
- Updated project references from Profanity to CProof.
- Removed Python 2 and unicode references.
- Added type hints for all parameters and return types.
- Organized functions into logical sections with RST comments for Sphinx.
- Improved wording for clarity and precision based on source code analysis.
- Ensured compliance with Google Python Style Guide for readable docstrings.
Related to #30
Introduce separate jobs to test C (Doxygen) and Python (Sphinx) API documentation generation. Ensures build failures are caught early, as API changes often produce warnings that developers miss without automated checks.
Includes were updated in 988d366, but the change did not propagate to forced_encryption.c due to the gap between the upstream Profanity and the CProof.