#pragma once #include #include #include #include struct sqlite3; namespace versiond { std::string sha256_hex(const std::string& d); std::string sha256_file(const std::string& path); struct Config { std::string host = "127.0.0.1"; int port = 9922; uint64_t max_file_bytes = 10485760; std::string home, config_dir, data_dir, spool_dir, index_file, config_file; std::string remote_url, remote_user, remote_password, remote_base = "/versioned/"; bool verify_tls = true; int keep_days = 5; }; Config default_config(); Config load_config(const std::string& home = ""); class Db { public: explicit Db(const std::string& p); ~Db(); void exec(const std::string& s); std::vector> query(const std::string& s); int64_t last_id(); void* handle(); void migrate(); private: sqlite3* h_ = nullptr; }; class Store { public: explicit Store(const std::string& d); std::string put(const std::string& digest, const std::string& raw); std::string get(const std::string& digest); std::string path_for(const std::string& h); private: std::string dir_; }; bool should_ignore(const std::string& p, const std::vector& e = {}); bool match_glob(const std::string& pat, const std::string& s); bool should_ignore_glob(const std::string& p, const std::vector& pats); std::map collect_stats(Db& db); int cli_main(int argc, char** argv); int api_main(const Config& c); struct ApiResp{int code;std::string ctype;std::string body;}; ApiResp api_build_response(Db& db, const std::string& path); std::string api_format_response(const ApiResp& r); int64_t ingest_file(Db& db, Store& st, const Config& c, const std::string& path, const std::string& reason = "manual"); int64_t ingest_bytes(Db& db, Store& st, const std::string& path, const std::string& raw, const std::string& reason = "manual"); int purge_old(Db& db, Store& st, int keep_days); int gc_blobs(Db& db, Store& st); bool snapshot_sqlite(const std::string& src, const std::string& dst, std::string& err); bool restore_blob(Store& st, const std::string& digest, const std::string& dst, std::string& err); bool recover_index(const Config& c, std::string& err); std::string diff_unified(const std::string& a, const std::string& b); std::string diff_files(Store& st, const std::string& da, const std::string& db); bool remote_upload_wolfssh(const std::string& host, const std::string& user, const std::string& local, const std::string& remote, std::string& err); int uploader_sync(Db& db, const Config& c); void monitor_once(Db& db, Store& st, const Config& c, const std::vector& roots); void monitor_poll(Db& db, Store& st, const Config& c, const std::vector& roots, int n); void dbsafe_exec(Db& db, const std::string& s); std::string db_safe_string(const std::string& s); }