feat: x3-backup v1.0.0 initial release

GTK3 backup/snapshot tool using rsync backend.

Features:
- rsync-based snapshots with hardlink delta for space efficiency
- Snapshot sidebar with date-sorted list
- Full file browser with permissions display (name, size, perms, mtime)
- Right-click context menu: Restore file/dir with sudo prompt
- System tray icon: backup status, context menu (show/backup/settings/quit)
- Menu system: File, Backup, System, Help
- Settings dialog: backup destination, source path, retention, exclusions
- Cronjob management: install/remove scheduled backups
- Live Log tab: real-time rsync output during backup
- History Log tab: full log file viewer with color-coded entries
- System Backup mode: full root filesystem backup
- System Restore mode: restore entire system from snapshot
- CLI mode: --backup, --system-backup for cron/headless use
- /mnt always excluded from backups
- Preserves permissions, ACLs, xattrs (-aAX flags)
- Log file: ~/.config/x3-backup/x3-backup.log
- Config: ~/.config/x3-backup/settings.json
- uninstall.sh for clean removal
This commit is contained in:
x3
2026-09-07 17:20:41 +00:00
commit c8ef700612
20 changed files with 2535 additions and 0 deletions
+57
View File
@@ -0,0 +1,57 @@
#pragma once
#include <string>
#include <vector>
#include <functional>
#include <atomic>
#include <thread>
#include <mutex>
#include "config.h"
struct RsyncProgress {
int64_t files_transferred = 0;
int64_t files_total = 0;
int64_t bytes_transferred = 0;
int64_t bytes_total = 0;
int speed = 0;
std::string current_file;
std::string log_line;
bool finished = false;
bool error = false;
std::string error_message;
};
class RsyncManager {
public:
RsyncManager(Config& config);
bool create_snapshot(const std::string& snapshot_name,
const std::string& source,
const std::string& dest,
const std::string& link_dest = "");
bool restore_files(const std::string& snapshot_path,
const std::vector<std::string>& files,
const std::string& restore_dest,
const std::string& sudo_password);
bool restore_full_snapshot(const std::string& snapshot_path,
const std::string& restore_dest,
const std::string& sudo_password);
void cancel();
bool is_running() const { return running_; }
std::function<void(const RsyncProgress&)> on_progress;
private:
Config& config_;
std::atomic<bool> running_{false};
std::atomic<bool> cancel_requested_{false};
std::thread worker_;
std::mutex log_mutex_;
std::vector<std::string> log_buffer_;
std::vector<std::string> build_exclude_args();
bool run_rsync(const std::vector<std::string>& args);
void parse_progress_line(const std::string& line, RsyncProgress& prog);
};