/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ module; #include "config.h" #include #include #include #include #include #include #include #include export module katja.pkgtools; import katja.utils; export namespace katja { using cache_entry = std::pair; class Pkgtools { public: /** * Repository name. */ const std::string name; /** * Repository mirror. */ const std::string mirror; /** * Repository order. */ const std::uint8_t order; /** * katja::Pkgtools::Pkgtools: * @name: Repository name. * @mirror: Repository mirror. * @order: Repository order. */ Pkgtools(const std::string& name, const std::string& mirror, std::uint8_t order) : name(name), mirror(mirror), order(order) { } /** * katja::Pkgtools:is_blacklisted: * @pkg: Package name to check for. * * Checks whether a package is blacklisted. * * Returns: %TRUE if the package is blacklisted, %FALSE otherwise. **/ bool is_blacklisted(const std::string_view& pkg) const noexcept { return std::regex_match(std::cbegin(pkg), std::cend(pkg), this->blacklist); } virtual ~Pkgtools() noexcept { } /** * katja::Pkgtools::download: * @job_data: A #JobData. * @dest_dir_name: Destination directory. * @pkg_name: Package name. * * Download a package. * * Returns: %TRUE on success, %FALSE otherwise. **/ bool download(JobData *job_data, const char *dest_dir_name, char *pkg_name) noexcept { std::filesystem::path dest_filename; std::string source_url; bool ret = false; sqlite3_stmt *statement = nullptr; CURL *curl = nullptr; if ((sqlite3_prepare_v2(job_data->db, "SELECT location, (full_name || '.' || ext) FROM pkglist " "WHERE name LIKE @name AND repo_order = @repo_order", -1, &statement, nullptr) != SQLITE_OK)) { return false; } sqlite3_bind_text(statement, 1, pkg_name, -1, SQLITE_TRANSIENT); sqlite3_bind_int(statement, 2, this->order); if (sqlite3_step(statement) == SQLITE_ROW) { dest_filename = std::filesystem::path(dest_dir_name) / reinterpret_cast(sqlite3_column_text(statement, 1)); source_url = this->mirror + reinterpret_cast(sqlite3_column_text(statement, 0)) + "/" + reinterpret_cast(sqlite3_column_text(statement, 1)); ret = g_file_test(dest_filename.native().c_str(), G_FILE_TEST_EXISTS) || get_file(&curl, source_url.c_str(), dest_filename.native().c_str()) == CURLE_OK; if (curl) { curl_easy_cleanup(curl); } } sqlite3_finalize(statement); return ret; } /** * katja::Pkgtools::install: * @job_data: A #JobData. * @pkg_name: Package name. * * Install a package. **/ void install(JobData *job_data, char *pkg_name) noexcept { std::filesystem::path pkg_filename; sqlite3_stmt *statement = nullptr; if ((sqlite3_prepare_v2(job_data->db, "SELECT (full_name || '.' || ext) FROM pkglist " "WHERE name LIKE @name AND repo_order = @repo_order", -1, &statement, nullptr) != SQLITE_OK)) { return; } sqlite3_bind_text(statement, 1, pkg_name, -1, SQLITE_TRANSIENT); sqlite3_bind_int(statement, 2, this->order); if (sqlite3_step(statement) == SQLITE_ROW) { pkg_filename = std::filesystem::path(LOCALSTATEDIR) / "cache" / "katja" / "downloads" / reinterpret_cast(sqlite3_column_text(statement, 0)); std::string cmd_line = "/sbin/upgradepkg --install-new " + pkg_filename.native(); g_spawn_command_line_sync(cmd_line.c_str(), nullptr, nullptr, nullptr, nullptr); } sqlite3_finalize(statement); } virtual std::forward_list collect_cache_info(const std::filesystem::path& tmpl) noexcept = 0; virtual void generate_cache(JobData *job_data, const std::filesystem::path& tmpl) noexcept = 0; protected: std::regex blacklist; }; /** * katja::cmp_repo: **/ template InputIt cmp_repo(InputIt first, InputIt last, const char *a) { return std::find_if(first, last, [a](std::unique_ptr& repo) { return repo->name == a; }); } }