diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt index 4c5a123..da37652 100644 --- a/backend/CMakeLists.txt +++ b/backend/CMakeLists.txt @@ -6,7 +6,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) +pkg_check_modules(deps REQUIRED IMPORTED_TARGET bzip2) add_library(backend) target_sources(backend diff --git a/backend/job.cpp b/backend/job.cpp index f95b33a..21b3ebc 100644 --- a/backend/job.cpp +++ b/backend/job.cpp @@ -7,13 +7,11 @@ module; #include "config.h" #include -#include #include #include #include #include #include -#include #include #include #include @@ -33,14 +31,10 @@ namespace katja { static std::forward_list> repos; -void pk_backend_initialize(GKeyFile *conf) +void pk_backend_initialize() { - char **groups; int ret; std::uint8_t i; - std::size_t groups_len; - GKeyFile *key_conf; - GError *err = nullptr; sqlite3 *db; sqlite3_stmt *stmt; @@ -53,16 +47,6 @@ void pk_backend_initialize(GKeyFile *conf) std::cerr << path.native() << ": " << sqlite3_errmsg(db) << std::endl; } - /* Read the configuration file */ - key_conf = g_key_file_new(); - path = std::filesystem::path(SYSCONFDIR) / "PackageKit" / "Slackware.conf"; - g_key_file_load_from_file(key_conf, path.c_str(), G_KEY_FILE_NONE, &err); - if (err) - { - std::cerr << path.native() << ": " << err->message << std::endl; - g_error_free(err); - } - std::chrono::time_point file_info = std::filesystem::last_write_time(path); auto microseconds = std::chrono::duration_cast(file_info.time_since_epoch()); @@ -87,26 +71,6 @@ void pk_backend_initialize(GKeyFile *conf) std::cerr << "Failed to update database: " << path.native() << std::endl; } sqlite3_close_v2(db); - - /* Initialize an object for each well-formed repository */ - groups = g_key_file_get_groups(key_conf, &groups_len); - for (i = 0; i < groups_len; i++) - { - char *blacklist = g_key_file_get_string(key_conf, groups[i], "Blacklist", nullptr); - char *mirror = g_key_file_get_string(key_conf, groups[i], "Mirror", nullptr); - - if (g_key_file_has_key(key_conf, groups[i], "Priority", nullptr)) - { - auto repo = std::make_unique(groups[i], mirror, i + 1, blacklist, - g_key_file_get_string_list(key_conf, groups[i], "Priority", nullptr, nullptr)); - repos.emplace_front(std::move(repo)); - } - g_free(mirror); - g_free(blacklist); - } - g_free(groups); - - g_key_file_free(key_conf); } void pk_backend_destroy() @@ -230,7 +194,6 @@ void pk_backend_get_details(JobData *job_data, char **package_ids) std::size_t i; std::regex expr; std::smatch match_info; - GError *err = nullptr; sqlite3_stmt *stmt; std::string desc; @@ -368,7 +331,7 @@ out: void pk_backend_install_packages(JobData *job_data, const std::vector package_ids) { unsigned i; - gdouble percent_step; + double percent_step; std::list install_list; sqlite3_stmt *pkglist_stmt = nullptr, *collection_stmt = nullptr; @@ -478,7 +441,6 @@ void pk_backend_remove_packages(JobData* job_data, const std::vectormessage << std::endl; - g_error_free(err); - - return; - } + system(cmd_line.c_str()); job_data->set_percentage(100); } diff --git a/backend/pkgtools.cpp b/backend/pkgtools.cpp index e3f7355..45b159a 100644 --- a/backend/pkgtools.cpp +++ b/backend/pkgtools.cpp @@ -9,7 +9,6 @@ module; #include #include #include -#include #include #include #include @@ -153,7 +152,7 @@ public: / 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); + system(cmd_line.c_str()); } sqlite3_finalize(statement); } diff --git a/backend/slackpkg.cpp b/backend/slackpkg.cpp index c240088..4119625 100644 --- a/backend/slackpkg.cpp +++ b/backend/slackpkg.cpp @@ -11,13 +11,14 @@ module; #include #include #include -#include #include #include #include #include #include #include +#include +#include export module katja.slackpkg; @@ -72,18 +73,16 @@ public: CURL *curl = nullptr; cache_entry source_dest; std::forward_list file_list; - GFile *tmp_dir, *repo_tmp_dir; /* Create the temporary directory for the repository */ - 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); + std::filesystem::path tmp_dir = tmpl / this->name; + std::filesystem::create_directories(tmp_dir); /* Download PACKAGES.TXT. These files are most important, break if some of them couldn't be found */ for (const std::string& current_priority : this->priority) { source_dest.first = this->mirror + current_priority + "/PACKAGES.TXT"; - source_dest.second = tmpl / this->name / "PACKAGES.TXT"; + source_dest.second = tmp_dir / "PACKAGES.TXT"; if (get_file(&curl, source_dest.first.c_str(), std::nullopt) == CURLE_OK) { @@ -104,9 +103,6 @@ public: } } out: - g_object_unref(repo_tmp_dir); - g_object_unref(tmp_dir); - if (curl) { curl_easy_cleanup(curl); @@ -127,23 +123,19 @@ public: void generate_cache(JobData *job_data, const std::filesystem::path& tmpl) noexcept { std::vector pkg_tokens; - char *query = nullptr, *filename = nullptr, *location = nullptr, *summary = nullptr, *line; + char *query = nullptr; unsigned pkg_compressed = 0, pkg_uncompressed = 0; std::uint8_t pkg_name_len; - GString *desc; - GFile *list_file; - GFileInputStream *fin = nullptr; - GDataInputStream *data_in = nullptr; + std::string desc, line, location; sqlite3_stmt *insert_statement = nullptr, *update_statement = nullptr, *insert_default_statement = nullptr; sqlite3_stmt *statement; + std::optional filename, summary; /* Check if the temporary directory for this repository exists, then the file metadata have to be generated */ 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); + std::ifstream data_in(packages_txt); - if (!fin) + if (!data_in) { goto out; } @@ -201,64 +193,63 @@ public: goto out; } - data_in = g_data_input_stream_new(G_INPUT_STREAM(fin)); - desc = g_string_new(""); + desc = ""; sqlite3_exec(job_data->db, "BEGIN TRANSACTION", nullptr, nullptr, nullptr); - while ((line = g_data_input_stream_read_line(data_in, nullptr, nullptr, nullptr))) + while (std::getline(data_in, line)) { - if (!strncmp(line, "PACKAGE NAME: ", 15)) + if (boost::starts_with(line, "PACKAGE NAME: ")) { - filename = g_strdup(line + 15); - if (this->is_blacklisted(filename)) + filename = line.substr(15); + if (this->is_blacklisted(filename.value())) { - g_free(filename); - filename = nullptr; + filename.reset(); } } - else if (filename && !strncmp(line, "PACKAGE LOCATION: ", 19)) + else if (filename.has_value() && boost::starts_with(line, "PACKAGE LOCATION: ")) { - location = g_strdup(line + 21); /* Exclude ./ at the path beginning */ + location = line.substr(21); /* Exclude ./ at the path beginning */ } - else if (filename && !strncmp(line, "PACKAGE SIZE (compressed): ", 28)) + else if (filename.has_value() && boost::starts_with(line, "PACKAGE SIZE (compressed): ")) { /* Remove the unit (kilobytes) */ - pkg_compressed = atoi(g_strndup(line + 28, strlen(line + 28) - 2)) * 1024; + std::from_chars(line.c_str() + 28, line.c_str() + line.size() - 2, pkg_compressed); + pkg_compressed *= 1024; } - else if (filename && !strncmp(line, "PACKAGE SIZE (uncompressed): ", 30)) + else if (filename.has_value() && boost::starts_with(line, "PACKAGE SIZE (uncompressed): ")) { /* Remove the unit (kilobytes) */ - pkg_uncompressed = atoi(g_strndup(line + 30, strlen(line + 30) - 2)) * 1024; + std::from_chars(line.c_str() + 30, line.c_str() + line.size() - 2, pkg_uncompressed); + pkg_uncompressed *= 1024; } - else if (filename && !g_strcmp0(line, "PACKAGE DESCRIPTION:")) + else if (filename.has_value() && boost::starts_with(line, "PACKAGE DESCRIPTION:")) { - g_free(line); - line = g_data_input_stream_read_line(data_in, nullptr, nullptr, nullptr); /* Short description */ + std::getline(data_in, line); - summary = g_strstr_len(line, -1, "("); - if (summary) /* Else summary = nullptr */ + auto summary_position = line.find_first_of('('); + if (summary_position != std::string::npos) /* Else summary = nullptr */ { - summary = g_strndup(summary + 1, strlen(summary) - 2); /* Without ( ) */ + summary = line.substr(summary_position + 1, line.size() - summary_position - 2); /* Without ( ) */ } - pkg_tokens = split_package_name(filename).value(); + pkg_tokens = split_package_name(filename.value()).value(); pkg_name_len = pkg_tokens[0].size(); /* Description begins with pkg_name: */ } - else if (filename && !strncmp(line, pkg_tokens[0].c_str(), pkg_name_len)) + else if (filename.has_value() && boost::starts_with(line, pkg_tokens[0])) { - g_string_append(desc, line + pkg_name_len + 1); + desc += line.substr(pkg_name_len + 1); } - else if (filename && !g_strcmp0(line, "")) + else if (filename.has_value() && line == "") { - if (g_strcmp0(location, "patches/packages")) /* Insert a new package */ + if (location != "patches/packages") /* Insert a new package */ { /* Get the package group based on its location */ - const char *cat = g_strrstr(location, "/"); - if (cat) + auto category_position = location.find_last_of('/'); + if (category_position != std::string::npos) { - ++cat; statement = insert_statement; - sqlite3_bind_text(insert_statement, 12, cat, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(insert_statement, 12, + location.c_str() + category_position + 1, -1, SQLITE_TRANSIENT); } else { @@ -274,9 +265,10 @@ public: sqlite3_bind_text(statement, 2, pkg_tokens[1].c_str(), -1, SQLITE_TRANSIENT); sqlite3_bind_text(statement, 3, pkg_tokens[2].c_str(), -1, SQLITE_TRANSIENT); sqlite3_bind_text(statement, 4, pkg_tokens[4].c_str(), -1, SQLITE_TRANSIENT); - sqlite3_bind_text(statement, 5, location, -1, SQLITE_TRANSIENT); - sqlite3_bind_text(statement, 6, summary, -1, SQLITE_TRANSIENT); - sqlite3_bind_text(statement, 7, desc->str, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(statement, 5, location.c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(statement, 6, + summary.has_value() ? summary.value().c_str() : nullptr, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(statement, 7, desc.c_str(), -1, SQLITE_TRANSIENT); sqlite3_bind_int(statement, 8, pkg_compressed); sqlite3_bind_int(statement, 9, pkg_uncompressed); sqlite3_bind_text(statement, 10, pkg_tokens[0].c_str(), -1, SQLITE_TRANSIENT); @@ -286,20 +278,15 @@ public: sqlite3_reset(statement); /* Reset for the next package */ - g_free(filename); - g_free(location); - g_free(summary); - filename = location = summary = nullptr; - g_string_assign(desc, ""); + summary.reset(); + filename.reset(); + location = ""; + desc = ""; pkg_compressed = pkg_uncompressed = 0; } - g_free(line); } sqlite3_exec(job_data->db, "END TRANSACTION", nullptr, nullptr, nullptr); - g_string_free(desc, true); - g_object_unref(data_in); - /* Parse MANIFEST.bz2 */ for (const std::string& current_priority : this->priority) { @@ -310,11 +297,6 @@ public: sqlite3_free(query); sqlite3_finalize(insert_default_statement); sqlite3_finalize(insert_statement); - - if (fin) - { - g_object_unref(fin); - } } private: @@ -335,13 +317,13 @@ private: FILE *manifest; int err, read_len; unsigned pos; - char buf[max_buf_size], *pkg_filename, *rest = nullptr, *start; + char buf[max_buf_size]; + std::optional rest; std::filesystem::path path; - char *full_name = nullptr; - char **line, **lines; + std::vector lines; BZFILE *manifest_bz2; - GRegex *pkg_expr = nullptr, *file_expr = nullptr; - GMatchInfo *match_info; + std::regex pkg_expr, file_expr; + std::smatch match_info; sqlite3_stmt *statement = nullptr; path = tmpl / this->name / filename; @@ -357,21 +339,13 @@ private: } /* Prepare regular expressions */ - pkg_expr = g_regex_new("^\\|\\|[[:blank:]]+Package:[[:blank:]]+.+\\/(.+)\\.(t[blxg]z$)?", - static_cast (G_REGEX_OPTIMIZE | G_REGEX_DUPNAMES), - static_cast (0), - nullptr); - file_expr = g_regex_new("^[-bcdlps][-r][-w][-xsS][-r][-w][-xsS][-r][-w]" + pkg_expr = std::regex("^\\|\\|[[:blank:]]+Package:[[:blank:]]+.+\\/(.+)\\.(t[blxg]z$)?", + std::regex::optimize); + file_expr = std::regex("^[-bcdlps][-r][-w][-xsS][-r][-w][-xsS][-r][-w]" "[-xtT][[:space:]][^[:space:]]+[[:space:]]+" "[[:digit:]]+[[:space:]][[:digit:]-]+[[:space:]]" "[[:digit:]:]+[[:space:]](?!install\\/|\\.)(.*)", - static_cast (G_REGEX_OPTIMIZE | G_REGEX_DUPNAMES), - static_cast (0), - nullptr); - if (!(file_expr) || !(pkg_expr)) - { - goto out; - } + std::regex::optimize); /* Prepare SQL statements */ if (sqlite3_prepare_v2(job_data->db, @@ -393,66 +367,50 @@ private: buf[read_len] = '\0'; /* Split the read text into lines */ - lines = g_strsplit(buf, "\n", 0); - if (rest) + boost::split(lines, buf, boost::is_any_of("\n")); + if (rest.has_value()) { /* Add to the first line rest characters from the previous read operation */ - start = lines[0]; - lines[0] = g_strconcat(rest, lines[0], nullptr); - g_free(start); - g_free(rest); + lines[0] = rest.value() + lines[0]; + rest.reset(); } if (err != BZ_STREAM_END) /* The last line can be incomplete */ { - pos = g_strv_length(lines) - 1; + pos = lines.size() - 1; rest = lines[pos]; - lines[pos] = nullptr; } - for (line = lines; *line; line++) + for (const auto& line : lines) { - if (g_regex_match(pkg_expr, *line, static_cast (0), &match_info)) + std::optional full_name; + + if (std::regex_match(std::cbegin(line), std::cend(line), match_info, pkg_expr)) { - if (g_match_info_get_match_count(match_info) > 2) + if (match_info.size() > 2) { /* If the extension matches */ - g_free(full_name); - full_name = g_match_info_fetch(match_info, 1); + full_name = match_info.str(1); } else { - full_name = nullptr; + full_name.reset(); } } - g_match_info_free(match_info); - - match_info = nullptr; - if (full_name && g_regex_match(file_expr, *line, static_cast (0), &match_info)) + if (full_name.has_value() + && std::regex_match(std::cbegin(line), std::cend(line), match_info, file_expr)) { - pkg_filename = g_match_info_fetch(match_info, 1); - sqlite3_bind_text(statement, 1, full_name, -1, SQLITE_TRANSIENT); - sqlite3_bind_text(statement, 2, pkg_filename, -1, SQLITE_TRANSIENT); + std::string pkg_filename = match_info.str(1); + sqlite3_bind_text(statement, 1, full_name.value().c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(statement, 2, pkg_filename.c_str(), -1, SQLITE_TRANSIENT); sqlite3_step(statement); sqlite3_clear_bindings(statement); sqlite3_reset(statement); - g_free(pkg_filename); } - g_match_info_free(match_info); } - g_strfreev(lines); } sqlite3_exec(job_data->db, "END TRANSACTION", nullptr, nullptr, nullptr); - g_free(full_name); BZ2_bzReadClose(&err, manifest_bz2); out: sqlite3_finalize(statement); - if (file_expr) - { - g_regex_unref(file_expr); - } - if (pkg_expr) - { - g_regex_unref(pkg_expr); - } fclose(manifest); } }; diff --git a/backend/utils.cpp b/backend/utils.cpp index 816fcfd..27eeb7b 100644 --- a/backend/utils.cpp +++ b/backend/utils.cpp @@ -8,7 +8,6 @@ module; #include #include #include -#include #include #include #include @@ -82,7 +81,7 @@ CURLcode get_file(CURL **curl, const char *source_url, const std::optional