diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt index fe2bfbf..4c5a123 100644 --- a/backend/CMakeLists.txt +++ b/backend/CMakeLists.txt @@ -5,6 +5,7 @@ find_package(CURL) find_package(PkgConfig REQUIRED) find_package(SQLite3) +find_package(Boost REQUIRED COMPONENTS filesystem process) pkg_check_modules(deps REQUIRED IMPORTED_TARGET glib-2.0 gio-2.0 bzip2) add_library(backend) @@ -16,6 +17,6 @@ target_sources(backend configure_file(config.h.in ${CMAKE_BINARY_DIR}/generated/config.h) include_directories(${CMAKE_BINARY_DIR}/generated/) -target_link_libraries(backend PkgConfig::deps CURL::libcurl ${SQLite3_LIBRARIES}) +target_link_libraries(backend PkgConfig::deps CURL::libcurl ${SQLite3_LIBRARIES} Boost::filesystem Boost::process) file(COPY metadata.db DESTINATION ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LOCALSTATEDIR}) diff --git a/backend/job.cpp b/backend/job.cpp index 68a2090..330e492 100644 --- a/backend/job.cpp +++ b/backend/job.cpp @@ -16,6 +16,7 @@ module; #include #include #include +#include export module katja.job; @@ -669,7 +670,8 @@ void pk_backend_update_packages(JobData *job_data, char **package_ids) void pk_backend_refresh_cache(JobData *job_data, bool force) { - char *tmp_dir_name, *db_err, *path = nullptr; + char *db_err, *path = nullptr; + std::filesystem::path tmp_dir_name; int ret; std::forward_list file_list; GFile *db_file = nullptr; @@ -678,13 +680,8 @@ void pk_backend_refresh_cache(JobData *job_data, bool force) sqlite3_stmt *stmt = nullptr; /* Create temporary directory */ - tmp_dir_name = g_dir_make_tmp("katja.XXXXXX", &err); - if (!tmp_dir_name) - { - std::cerr << err->message << std::endl; - g_error_free(err); - return; - } + tmp_dir_name = std::filesystem::temp_directory_path() / boost::filesystem::unique_path("katja.%%%%%%").native(); + std::filesystem::create_directories(tmp_dir_name); /* Force the complete cache refresh if the read configuration file is newer than the metadata cache */ if (!force) @@ -754,7 +751,5 @@ out: g_free(path); std::filesystem::remove_all(tmp_dir_name); - g_rmdir(tmp_dir_name); - g_free(tmp_dir_name); } } diff --git a/backend/pkgtools.cpp b/backend/pkgtools.cpp index 80dc4d8..6c387f3 100644 --- a/backend/pkgtools.cpp +++ b/backend/pkgtools.cpp @@ -81,7 +81,8 @@ public: **/ bool download(JobData *job_data, const char *dest_dir_name, char *pkg_name) noexcept { - char *dest_filename, *source_url; + std::filesystem::path dest_filename; + std::string source_url; bool ret = false; sqlite3_stmt *statement = nullptr; CURL *curl = nullptr; @@ -100,22 +101,20 @@ public: 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); + 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, G_FILE_TEST_EXISTS) - || get_file(&curl, source_url, dest_filename) == CURLE_OK; + 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); } - g_free(source_url); - g_free(dest_filename); } sqlite3_finalize(statement); @@ -131,7 +130,7 @@ public: **/ void install(JobData *job_data, char *pkg_name) noexcept { - char *pkg_filename, *cmd_line; + std::filesystem::path pkg_filename; sqlite3_stmt *statement = nullptr; if ((sqlite3_prepare_v2(job_data->db, @@ -149,23 +148,18 @@ public: 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); + pkg_filename = std::filesystem::path(LOCALSTATEDIR) + / "cache" / "katja" / "downloads" + / reinterpret_cast(sqlite3_column_text(statement, 0)); - g_free(pkg_filename); + 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 char *tmpl) noexcept = 0; - virtual void generate_cache(JobData *job_data, const char *tmpl) noexcept = 0; + 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; diff --git a/backend/slackpkg.cpp b/backend/slackpkg.cpp index d546b5e..b179da0 100644 --- a/backend/slackpkg.cpp +++ b/backend/slackpkg.cpp @@ -67,7 +67,7 @@ public: * * Returns: List of files needed for building the cache. **/ - std::forward_list collect_cache_info(const char *tmpl) noexcept + std::forward_list collect_cache_info(const std::filesystem::path& tmpl) noexcept { CURL *curl = nullptr; cache_entry source_dest; @@ -75,7 +75,7 @@ public: GFile *tmp_dir, *repo_tmp_dir; /* Create the temporary directory for the repository */ - tmp_dir = g_file_new_for_path(tmpl); + tmp_dir = g_file_new_for_path(tmpl.native().c_str()); repo_tmp_dir = g_file_get_child(tmp_dir, this->name.c_str()); g_file_make_directory(repo_tmp_dir, nullptr, nullptr); @@ -83,7 +83,7 @@ public: for (const std::string& current_priority : this->priority) { source_dest.first = this->mirror + current_priority + "/PACKAGES.TXT"; - source_dest.second = std::filesystem::path(tmpl) / this->name / "PACKAGES.TXT"; + source_dest.second = tmpl / this->name / "PACKAGES.TXT"; if (get_file(&curl, source_dest.first.c_str(), nullptr) == CURLE_OK) { @@ -96,7 +96,7 @@ public: /* Download file lists if available */ source_dest.first = this->mirror + current_priority + "/MANIFEST.bz2"; - source_dest.second = std::filesystem::path(tmpl) / this->name / (current_priority + "-MANIFEST.bz2"); + source_dest.second = tmpl / this->name / (current_priority + "-MANIFEST.bz2"); if (get_file(&curl, source_dest.first.c_str(), nullptr) == CURLE_OK) { @@ -124,10 +124,10 @@ public: * * Returns: List of files needed for building the cache. **/ - void generate_cache(JobData *job_data, const char *tmpl) noexcept + void generate_cache(JobData *job_data, const std::filesystem::path& tmpl) noexcept { char **pkg_tokens = nullptr; - char *query = nullptr, *filename = nullptr, *location = nullptr, *summary = nullptr, *line, *packages_txt; + char *query = nullptr, *filename = nullptr, *location = nullptr, *summary = nullptr, *line; unsigned pkg_compressed = 0, pkg_uncompressed = 0; std::uint8_t pkg_name_len; GString *desc; @@ -138,11 +138,11 @@ public: sqlite3_stmt *statement; /* Check if the temporary directory for this repository exists, then the file metadata have to be generated */ - packages_txt = g_build_filename(tmpl, this->name.c_str(), "PACKAGES.TXT", nullptr); - list_file = g_file_new_for_path(packages_txt); + std::filesystem::path packages_txt = tmpl / this->name / "PACKAGES.TXT"; + list_file = g_file_new_for_path(packages_txt.native().c_str()); fin = g_file_read(list_file, nullptr, nullptr); g_object_unref(list_file); - g_free(packages_txt); + if (!fin) { goto out; @@ -304,9 +304,7 @@ public: /* Parse MANIFEST.bz2 */ for (const std::string& current_priority : this->priority) { - filename = g_strconcat(current_priority.c_str(), "-MANIFEST.bz2", nullptr); - manifest(job_data, tmpl, filename); - g_free(filename); + manifest(job_data, tmpl, current_priority + "-MANIFEST.bz2"); } out: sqlite3_finalize(update_statement); @@ -333,12 +331,13 @@ private: * Parse the manifest file and save the file list in the database. */ - void manifest(JobData *job_data, const char *tmpl, char *filename) noexcept + void manifest(JobData *job_data, const std::filesystem::path& tmpl, const std::string& filename) noexcept { FILE *manifest; int err, read_len; unsigned pos; - char buf[max_buf_size], *path, *pkg_filename, *rest = nullptr, *start; + char buf[max_buf_size], *pkg_filename, *rest = nullptr, *start; + std::filesystem::path path; char *full_name = nullptr; char **line, **lines; BZFILE *manifest_bz2; @@ -346,9 +345,8 @@ private: GMatchInfo *match_info; sqlite3_stmt *statement = nullptr; - path = g_build_filename(tmpl, this->name.c_str(), filename, nullptr); - manifest = fopen(path, "rb"); - g_free(path); + path = tmpl / this->name / filename; + manifest = fopen(path.native().c_str(), "rb"); if (!manifest) {