/* * 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 { char *dest_filename, *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 = g_build_filename(dest_dir_name, sqlite3_column_text(statement, 1), nullptr); source_url = g_strconcat(this->mirror.c_str(), sqlite3_column_text(statement, 0), "/", sqlite3_column_text(statement, 1), nullptr); ret = g_file_test(dest_filename, G_FILE_TEST_EXISTS) || get_file(&curl, source_url, dest_filename) == CURLE_OK; if (curl) { curl_easy_cleanup(curl); } g_free(source_url); g_free(dest_filename); } 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 { char *pkg_filename, *cmd_line; 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 = g_build_filename(LOCALSTATEDIR, "cache", "katja", "downloads", sqlite3_column_text(statement, 0), nullptr); cmd_line = g_strconcat("/sbin/upgradepkg --install-new ", pkg_filename, nullptr); g_spawn_command_line_sync(cmd_line, nullptr, nullptr, nullptr, nullptr); g_free(cmd_line); g_free(pkg_filename); } sqlite3_finalize(statement); } virtual std::forward_list collect_cache_info(const char *tmpl) noexcept = 0; virtual void generate_cache(JobData *job_data, const char *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; }); } }