diff --git a/backend/job.cpp b/backend/job.cpp index 330e492..68eda1a 100644 --- a/backend/job.cpp +++ b/backend/job.cpp @@ -16,7 +16,11 @@ module; #include #include #include +#include +#include +#include #include +#include export module katja.job; @@ -30,7 +34,7 @@ static std::forward_list> repos; void pk_backend_initialize(GKeyFile *conf) { - char *path, **groups; + char **groups; int ret; std::uint8_t i; std::size_t groups_len; @@ -45,24 +49,23 @@ void pk_backend_initialize(GKeyFile *conf) curl_global_init(CURL_GLOBAL_DEFAULT); /* Open the database. We will need it to save the time the configuration file was last modified. */ - path = g_build_filename(LOCALSTATEDIR, "cache", "katja", "metadata.db", nullptr); - if (sqlite3_open(path, &db) != SQLITE_OK) + auto path = std::filesystem::path(LOCALSTATEDIR) / "cache" / "katja" / "metadata.db"; + if (sqlite3_open(path.c_str(), &db) != SQLITE_OK) { - g_error("%s: %s", path, sqlite3_errmsg(db)); + g_error("%s: %s", path.c_str(), sqlite3_errmsg(db)); } - g_free(path); /* Read the configuration file */ key_conf = g_key_file_new(); - path = g_build_filename(SYSCONFDIR, "PackageKit", "Slackware.conf", nullptr); - g_key_file_load_from_file(key_conf, path, G_KEY_FILE_NONE, &err); + 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) { - g_error("%s: %s", path, err->message); + g_error("%s: %s", path.c_str(), err->message); g_error_free(err); } - conf_file = g_file_new_for_path(path); + conf_file = g_file_new_for_path(path.c_str()); if (!(file_info = g_file_query_info(conf_file, "time::modified-usec", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, @@ -87,17 +90,16 @@ void pk_backend_initialize(GKeyFile *conf) } if ((ret != SQLITE_OK) && (ret != SQLITE_DONE)) { - g_error("%s: %s", path, sqlite3_errstr(ret)); + g_error("%s: %s", path.c_str(), sqlite3_errstr(ret)); } else if (!sqlite3_changes(db)) { - g_error("Failed to update database: %s", path); + g_error("Failed to update database: %s", path.c_str()); } g_object_unref(file_info); g_object_unref(conf_file); sqlite3_close_v2(db); - g_free(path); /* Initialize an object for each well-formed repository */ groups = g_key_file_get_groups(key_conf, &groups_len); @@ -130,22 +132,16 @@ void pk_backend_destroy() JobData *pk_backend_start_job() { - char *db_filename = nullptr; - JobData *job_data = g_new0(JobData, 1); + JobData *job_data = new DummyJobData(); + auto db_filename = std::filesystem::path(LOCALSTATEDIR) / "cache" / "katja" / "metadata.db"; - db_filename = g_build_filename(LOCALSTATEDIR, "cache", "katja", "metadata.db", nullptr); - if (sqlite3_open(db_filename, &job_data->db) == SQLITE_OK) { /* Some SQLite settings */ + if (sqlite3_open(db_filename.native().c_str(), &job_data->db) == SQLITE_OK) { /* Some SQLite settings */ sqlite3_exec(job_data->db, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr); } else { std::cerr << db_filename << ": " << sqlite3_errmsg(job_data->db) << std::endl; - goto out; } - -out: - g_free(db_filename); - return job_data; } @@ -157,22 +153,19 @@ void pk_backend_stop_job(JobData *job_data) } sqlite3_close(job_data->db); - g_free(job_data); + delete job_data; } -void pk_backend_search_thread(JobData *job_data, GVariant *params, const char *user_data) +// for filters -1 means requesting not installed, 1 - installed, 0 - no filters. +void pk_backend_search_thread(JobData *job_data, std::uint64_t filters, const std::vector& vals, + const char *user_data) { - char **vals; - // -1 means requesting not installed, 1 - installed, 0 - no filters. - guint64 filters; - g_variant_get(params, "(t^a&s)", &filters, &vals); - char *search = g_strjoinv("%", vals); - + std::string search = boost::algorithm::join(vals, "%"); const char *generate_query = "SELECT (p1.name || ';' || p1.ver || ';' || p1.arch || ';' || r.repo), p1.summary, " "p1.full_name FROM pkglist AS p1 NATURAL JOIN repos AS r " "WHERE p1.%s LIKE '%%%q%%' AND p1.ext NOT LIKE 'obsolete' AND p1.repo_order = " "(SELECT MIN(p2.repo_order) FROM pkglist AS p2 WHERE p2.name = p1.name GROUP BY p2.name)"; - char *query = sqlite3_mprintf(generate_query, user_data, search); + char *query = sqlite3_mprintf(generate_query, user_data, search.c_str()); sqlite3_stmt *stmt; if ((sqlite3_prepare_v2(job_data->db, query, -1, &stmt, nullptr) == SQLITE_OK)) @@ -204,21 +197,19 @@ void pk_backend_search_thread(JobData *job_data, GVariant *params, const char *u std::cerr << sqlite3_errmsg(job_data->db) << std::endl; } sqlite3_free(query); - g_free(search); } -void pk_backend_search_files(JobData *job_data, char **values) +void pk_backend_search_files(JobData *job_data, const std::vector& values) { - char *search; char *query; sqlite3_stmt *stmt; Info ret; - search = g_strjoinv("%", values); + std::string search = boost::algorithm::join(values, "%"); query = sqlite3_mprintf("SELECT (p.name || ';' || p.ver || ';' || p.arch || ';' || r.repo), p.summary, " "p.full_name FROM filelist AS f NATURAL JOIN pkglist AS p NATURAL JOIN repos AS r " - "WHERE f.filename LIKE '%%%q%%' GROUP BY f.full_name", search); + "WHERE f.filename LIKE '%%%q%%' GROUP BY f.full_name", search.c_str()); if ((sqlite3_prepare_v2(job_data->db, query, -1, &stmt, nullptr) == SQLITE_OK)) { @@ -246,19 +237,20 @@ void pk_backend_search_files(JobData *job_data, char **values) std::cerr << sqlite3_errmsg(job_data->db) << std::endl; } sqlite3_free(query); - g_free(search); } void pk_backend_get_details(JobData *job_data, char **package_ids) { - char *homepage = nullptr; - char** tokens; + std::optional homepage; std::size_t i; - GString *desc; GRegex *expr; GMatchInfo *match_info; GError *err = nullptr; sqlite3_stmt *stmt; + std::string desc; + + std::vector tokens; + boost::split(tokens, package_ids[i], boost::is_any_of(";")); if ((sqlite3_prepare_v2(job_data->db, "SELECT p.desc, p.cat, p.uncompressed FROM pkglist AS p NATURAL JOIN repos AS r " @@ -269,17 +261,14 @@ void pk_backend_get_details(JobData *job_data, char **package_ids) std::cerr << sqlite3_errmsg(job_data->db) << std::endl; goto out; } - - tokens = g_strsplit(package_ids[0], ";", 4); - sqlite3_bind_text(stmt, 1, tokens[0], -1, SQLITE_TRANSIENT); - sqlite3_bind_text(stmt, 2, tokens[3], -1, SQLITE_TRANSIENT); - g_strfreev(tokens); + sqlite3_bind_text(stmt, 1, tokens[0].c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 2, tokens[3].c_str(), -1, SQLITE_TRANSIENT); if (sqlite3_step(stmt) != SQLITE_ROW) { goto out; } - desc = g_string_new((char *) sqlite3_column_text(stmt, 0)); + desc = reinterpret_cast(sqlite3_column_text(stmt, 0)); /* Regular expression for searching a homepage */ expr = g_regex_new("(?:http|ftp):\\/\\/[[:word:]\\/\\-\\.]+[[:word:]\\/](?=\\.?$)", @@ -292,15 +281,15 @@ void pk_backend_get_details(JobData *job_data, char **package_ids) g_error_free(err); goto out; } - if (g_regex_match(expr, desc->str, (GRegexMatchFlags) 0, &match_info)) + if (g_regex_match(expr, desc.c_str(), (GRegexMatchFlags) 0, &match_info)) { homepage = g_match_info_fetch(match_info, 0); /* URL */ /* Remove the last sentence with the copied URL */ - for (i = desc->len - 1; i > 0; i--) + for (i = desc.size() - 1; i > 0; i--) { - if ((desc->str[i - 1] == '.') && (desc->str[i] == ' ')) + if ((desc[i - 1] == '.') && (desc[i] == ' ')) { - g_string_truncate(desc, i); + desc.erase(std::cbegin(desc) + i); break; } } @@ -311,16 +300,10 @@ void pk_backend_get_details(JobData *job_data, char **package_ids) /* Ready */ job_data->details(package_ids[0], (char *) sqlite3_column_text(stmt, 1), - desc->str, - homepage, + desc.c_str(), + homepage.has_value() ? homepage.value().c_str() : nullptr, sqlite3_column_int(stmt, 2)); - g_free(homepage); - if (desc) - { - g_string_free(desc, true); - } - out: sqlite3_finalize(stmt); } @@ -363,7 +346,6 @@ void pk_backend_resolve(JobData *job_data, char **packages) void pk_backend_download_packages(JobData *job_data, char **package_ids, const char *directory) { - char *path, *to_strv[] = {nullptr, nullptr}; unsigned i; sqlite3_stmt *stmt; @@ -380,39 +362,38 @@ void pk_backend_download_packages(JobData *job_data, char **package_ids, const c for (i = 0; package_ids[i]; ++i) { - char **tokens = g_strsplit(package_ids[i], ";", 4); + std::vector tokens; + boost::split(tokens, package_ids[i], boost::is_any_of(";")); - sqlite3_bind_text(stmt, 1, tokens[0], -1, SQLITE_TRANSIENT); - sqlite3_bind_text(stmt, 2, tokens[1], -1, SQLITE_TRANSIENT); - sqlite3_bind_text(stmt, 3, tokens[2], -1, SQLITE_TRANSIENT); - sqlite3_bind_text(stmt, 4, tokens[3], -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 1, tokens[0].c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 2, tokens[1].c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 3, tokens[2].c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 4, tokens[3].c_str(), -1, SQLITE_TRANSIENT); if (sqlite3_step(stmt) == SQLITE_ROW) { - auto repo = cmp_repo(std::begin(repos), std::end(repos), tokens[3]); + auto repo = cmp_repo(std::begin(repos), std::end(repos), tokens[3].c_str()); if (repo != std::end(repos)) { - (*repo)->download(job_data, directory, tokens[0]); - path = g_build_filename(directory, (char *) sqlite3_column_text(stmt, 1), nullptr); - to_strv[0] = path; + (*repo)->download(job_data, directory, tokens[0].c_str()); + auto path = std::filesystem::path(directory) + / reinterpret_cast(sqlite3_column_text(stmt, 1)); + std::vector to_strv{ path }; job_data->files(to_strv); - g_free(path); } } sqlite3_clear_bindings(stmt); sqlite3_reset(stmt); - g_strfreev(tokens); } out: sqlite3_finalize(stmt); } -void pk_backend_install_packages(JobData *job_data, char **package_ids) +void pk_backend_install_packages(JobData *job_data, const std::vector package_ids) { - char *dest_dir_name; unsigned i; gdouble percent_step; - GSList *install_list = nullptr, *l; + std::list install_list; sqlite3_stmt *pkglist_stmt = nullptr, *collection_stmt = nullptr; if ((sqlite3_prepare_v2(job_data->db, @@ -435,33 +416,35 @@ void pk_backend_install_packages(JobData *job_data, char **package_ids) goto out; } - for (i = 0; package_ids[i]; i++) + for (const std::string& package_id : package_ids) { - char **tokens = g_strsplit(package_ids[i], ";", 4); - sqlite3_bind_text(pkglist_stmt, 1, tokens[0], -1, SQLITE_TRANSIENT); - sqlite3_bind_text(pkglist_stmt, 2, tokens[1], -1, SQLITE_TRANSIENT); - sqlite3_bind_text(pkglist_stmt, 3, tokens[2], -1, SQLITE_TRANSIENT); - sqlite3_bind_text(pkglist_stmt, 4, tokens[3], -1, SQLITE_TRANSIENT); + std::vector tokens; + boost::split(tokens, package_id, boost::is_any_of(";")); + + sqlite3_bind_text(pkglist_stmt, 1, tokens[0].c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(pkglist_stmt, 2, tokens[1].c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(pkglist_stmt, 3, tokens[2].c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(pkglist_stmt, 4, tokens[3].c_str(), -1, SQLITE_TRANSIENT); if (sqlite3_step(pkglist_stmt) == SQLITE_ROW) { /* If it isn't a collection */ - if (g_strcmp0((char *) sqlite3_column_text(pkglist_stmt, 1), "collections")) + if (strcmp(reinterpret_cast(sqlite3_column_text(pkglist_stmt, 1)), "collections")) { - install_list = g_slist_append(install_list, g_strdup(package_ids[i])); + install_list.push_back(package_id); } else { - sqlite3_bind_text(collection_stmt, 1, tokens[0], -1, SQLITE_TRANSIENT); - sqlite3_bind_text(collection_stmt, 2, tokens[3], -1, SQLITE_TRANSIENT); + sqlite3_bind_text(collection_stmt, 1, tokens[0].c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(collection_stmt, 2, tokens[3].c_str(), -1, SQLITE_TRANSIENT); while (sqlite3_step(collection_stmt) == SQLITE_ROW) { katja::Info ret = is_installed((char*) sqlite3_column_text(collection_stmt, 2)); if ((ret == Info::installing) || (ret == Info::updating)) { - install_list = g_slist_append(install_list, - g_strdup((char *) sqlite3_column_text(collection_stmt, 0))); + install_list.push_back( + reinterpret_cast(sqlite3_column_text(collection_stmt, 0))); } } sqlite3_clear_bindings(collection_stmt); @@ -471,71 +454,68 @@ void pk_backend_install_packages(JobData *job_data, char **package_ids) sqlite3_clear_bindings(pkglist_stmt); sqlite3_reset(pkglist_stmt); - g_strfreev(tokens); } - if (install_list) + if (!install_list.empty()) { /* / 2 means total percentage for installing and for downloading */ - percent_step = 100.0 / g_slist_length(install_list) / 2; + percent_step = 100.0 / install_list.size() / 2; /* Download the packages */ - dest_dir_name = g_build_filename(LOCALSTATEDIR, "cache", "katja", "downloads", nullptr); - for (l = install_list, i = 0; l; l = g_slist_next(l), i++) + auto dest_dir_name = std::filesystem::path(LOCALSTATEDIR) / "cache" / "katja" / "downloads"; + for (const auto& l : install_list) { job_data->set_percentage(percent_step * i); - char **tokens = g_strsplit((char *)(l->data), ";", 4); - auto repo = cmp_repo(std::begin(repos), std::end(repos), tokens[3]); + std::vector tokens; + boost::split(tokens, l, boost::is_any_of(";")); + + auto repo = cmp_repo(std::begin(repos), std::end(repos), tokens[3].c_str()); if (repo != std::end(repos)) { - (*repo)->download(job_data, dest_dir_name, tokens[0]); + (*repo)->download(job_data, dest_dir_name.native().c_str(), tokens[0].c_str()); } - g_strfreev(tokens); } - g_free(dest_dir_name); /* Install the packages */ - for (l = install_list; l; l = g_slist_next(l), i++) + for (const auto& l : install_list) { job_data->set_percentage(percent_step * i); - char **tokens = g_strsplit((char *)(l->data), ";", 4); - auto repo = cmp_repo(std::begin(repos), std::end(repos), tokens[3]); + std::vector tokens; + boost::split(tokens, l, boost::is_any_of(";")); + + auto repo = cmp_repo(std::begin(repos), std::end(repos), tokens[3].c_str()); if (repo != std::end(repos)) { - (*repo)->install(job_data, tokens[0]); + (*repo)->install(job_data, tokens[0].c_str()); } - g_strfreev(tokens); } } - g_slist_free_full(install_list, g_free); out: sqlite3_finalize(pkglist_stmt); sqlite3_finalize(collection_stmt); } -void pk_backend_remove_packages(JobData* job_data, char **package_ids) +void pk_backend_remove_packages(JobData* job_data, const std::vector& package_ids) { - char *cmd_line; unsigned i; double percent_step; GError *err = nullptr; /* Add percent_step percents per removed package */ - percent_step = 100.0 / g_strv_length(package_ids); - for (i = 0; package_ids[i]; i++) + percent_step = 100.0 / package_ids.size(); + for (i = 0; i < package_ids[i].size(); i++) { job_data->set_percentage(percent_step * i); - char **tokens = g_strsplit(package_ids[i], ";", 4); - cmd_line = g_strconcat("/sbin/removepkg ", tokens[0], nullptr); + std::vector tokens; + boost::split(tokens, package_ids[i], boost::is_any_of(";")); + + std::string cmd_line = "/sbin/removepkg " + tokens[0]; /* Pkgtools return always 0 */ - g_spawn_command_line_sync(cmd_line, nullptr, nullptr, nullptr, &err); - - g_free(cmd_line); - g_strfreev(tokens); + g_spawn_command_line_sync(cmd_line.c_str(), nullptr, nullptr, nullptr, &err); if (err) { @@ -551,7 +531,6 @@ void pk_backend_remove_packages(JobData* job_data, char **package_ids) void pk_backend_get_updates(JobData *job_data) { - char *pkg_id, *full_name, *desc; const char *pkg_metadata_filename; GFile *pkg_metadata_dir; GFileEnumerator *pkg_metadata_enumerator; @@ -588,44 +567,37 @@ void pk_backend_get_updates(JobData *job_data) while ((pkg_metadata_file_info = g_file_enumerator_next_file(pkg_metadata_enumerator, nullptr, nullptr))) { - char **tokens; - pkg_metadata_filename = g_file_info_get_name(pkg_metadata_file_info); - tokens = split_package_name(pkg_metadata_filename); + std::vector tokens = split_package_name(pkg_metadata_filename).value(); /* Select the package from the database */ - sqlite3_bind_text(stmt, 1, tokens[0], -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 1, tokens[0].c_str(), -1, SQLITE_TRANSIENT); /* If there are more packages with the same name, remember the one from the * repository with the lowest order. */ if ((sqlite3_step(stmt) == SQLITE_ROW) || cmp_repo(std::begin(repos), std::end(repos), (const char *) sqlite3_column_text(stmt, 4)) != std::end(repos)) { + std::string full_name{ reinterpret_cast(sqlite3_column_text(stmt, 0)) }; - full_name = g_strdup((char *) sqlite3_column_text(stmt, 0)); - - if (g_strcmp0(pkg_metadata_filename, full_name)) + if (full_name != pkg_metadata_filename) { /* Update available */ - pkg_id = g_strjoin(";", - (char *) sqlite3_column_text(stmt, 1), - (char *) sqlite3_column_text(stmt, 2), - (char *) sqlite3_column_text(stmt, 3), - (char *) sqlite3_column_text(stmt, 4), - nullptr); - desc = g_strdup((char *) sqlite3_column_text(stmt, 5)); + std::array id_parts{ + reinterpret_cast(sqlite3_column_text(stmt, 1)), + reinterpret_cast(sqlite3_column_text(stmt, 2)), + reinterpret_cast(sqlite3_column_text(stmt, 3)), + reinterpret_cast(sqlite3_column_text(stmt, 4)) + }; + std::string pkg_id = boost::algorithm::join(id_parts, ";"); + std::string desc{ reinterpret_cast(sqlite3_column_text(stmt, 5)) }; - job_data->package(katja::Info::updating, pkg_id, desc); - - g_free(desc); - g_free(pkg_id); + job_data->package(katja::Info::updating, pkg_id.c_str(), desc.c_str()); } - g_free(full_name); } sqlite3_clear_bindings(stmt); sqlite3_reset(stmt); - g_strfreev(tokens); g_object_unref(pkg_metadata_file_info); } g_object_unref(pkg_metadata_enumerator); @@ -636,42 +608,40 @@ out: void pk_backend_update_packages(JobData *job_data, char **package_ids) { - char *dest_dir_name, *cmd_line; + char *cmd_line; unsigned i; /* Download the packages */ - dest_dir_name = g_build_filename(LOCALSTATEDIR, "cache", "katja", "downloads", nullptr); + auto dest_dir_name = std::filesystem::path(LOCALSTATEDIR) / "cache" / "katja" / "downloads"; for (i = 0; package_ids[i]; i++) { - char **tokens = g_strsplit(package_ids[i], ";", 4); - auto repo = cmp_repo(std::begin(repos), std::end(repos), tokens[3]); + std::vector tokens; + boost::split(tokens, package_ids[i], boost::is_any_of(";")); + auto repo = cmp_repo(std::begin(repos), std::end(repos), tokens[3].c_str()); if (repo != std::end(repos)) { - (*repo)->download(job_data, dest_dir_name, tokens[0]); + (*repo)->download(job_data, dest_dir_name.c_str(), tokens[0].c_str()); } - g_strfreev(tokens); } - g_free(dest_dir_name); /* Install the packages */ for (i = 0; package_ids[i]; i++) { - char **tokens = g_strsplit(package_ids[i], ";", 4); - auto repo = cmp_repo(std::begin(repos), std::end(repos), tokens[3]); + std::vector tokens; + boost::split(tokens, package_ids[i], boost::is_any_of(";")); + auto repo = cmp_repo(std::begin(repos), std::end(repos), tokens[3].c_str()); if (repo != std::end(repos)) { - (*repo)->install(job_data, tokens[0]); + (*repo)->install(job_data, tokens[0].c_str()); } - g_strfreev(tokens); } } void pk_backend_refresh_cache(JobData *job_data, bool force) { - char *db_err, *path = nullptr; - std::filesystem::path tmp_dir_name; + char *db_err; int ret; std::forward_list file_list; GFile *db_file = nullptr; @@ -680,14 +650,15 @@ void pk_backend_refresh_cache(JobData *job_data, bool force) sqlite3_stmt *stmt = nullptr; /* Create temporary directory */ - tmp_dir_name = std::filesystem::temp_directory_path() / boost::filesystem::unique_path("katja.%%%%%%").native(); + std::filesystem::path 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) { - path = g_build_filename(LOCALSTATEDIR, "cache", "katja", "metadata.db", nullptr); - db_file = g_file_new_for_path(path); + auto path = std::filesystem::path(LOCALSTATEDIR) / "cache" / "katja" / "metadata.db"; + db_file = g_file_new_for_path(path.native().c_str()); file_info = g_file_query_info(db_file, "time::modified-usec", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, nullptr, &err); if (err) { @@ -748,8 +719,6 @@ out: { g_object_unref(db_file); } - g_free(path); - std::filesystem::remove_all(tmp_dir_name); } } diff --git a/backend/pkgtools.cpp b/backend/pkgtools.cpp index 6c387f3..f6c9b00 100644 --- a/backend/pkgtools.cpp +++ b/backend/pkgtools.cpp @@ -79,7 +79,7 @@ public: * * Returns: %TRUE on success, %FALSE otherwise. **/ - bool download(JobData *job_data, const char *dest_dir_name, char *pkg_name) noexcept + bool download(JobData *job_data, const char *dest_dir_name, const char *pkg_name) noexcept { std::filesystem::path dest_filename; std::string source_url; @@ -108,7 +108,7 @@ public: + "/" + reinterpret_cast(sqlite3_column_text(statement, 1)); - ret = g_file_test(dest_filename.native().c_str(), G_FILE_TEST_EXISTS) + ret = std::filesystem::exists(dest_filename) || get_file(&curl, source_url.c_str(), dest_filename.native().c_str()) == CURLE_OK; if (curl) @@ -128,7 +128,7 @@ public: * * Install a package. **/ - void install(JobData *job_data, char *pkg_name) noexcept + void install(JobData *job_data, const char *pkg_name) noexcept { std::filesystem::path pkg_filename; sqlite3_stmt *statement = nullptr; diff --git a/backend/slackpkg.cpp b/backend/slackpkg.cpp index b179da0..2f418a8 100644 --- a/backend/slackpkg.cpp +++ b/backend/slackpkg.cpp @@ -126,7 +126,7 @@ public: **/ void generate_cache(JobData *job_data, const std::filesystem::path& tmpl) noexcept { - char **pkg_tokens = nullptr; + std::vector pkg_tokens; char *query = nullptr, *filename = nullptr, *location = nullptr, *summary = nullptr, *line; unsigned pkg_compressed = 0, pkg_uncompressed = 0; std::uint8_t pkg_name_len; @@ -241,10 +241,10 @@ public: { summary = g_strndup(summary + 1, strlen(summary) - 2); /* Without ( ) */ } - pkg_tokens = split_package_name(filename); - pkg_name_len = strlen(pkg_tokens[0]); /* Description begins with pkg_name: */ + pkg_tokens = split_package_name(filename).value(); + pkg_name_len = pkg_tokens[0].size(); /* Description begins with pkg_name: */ } - else if (filename && !strncmp(line, pkg_tokens[0], pkg_name_len)) + else if (filename && !strncmp(line, pkg_tokens[0].c_str(), pkg_name_len)) { g_string_append(desc, line + pkg_name_len + 1); } @@ -270,23 +270,22 @@ public: { statement = update_statement; } - sqlite3_bind_text(statement, 1, pkg_tokens[3], -1, SQLITE_TRANSIENT); - sqlite3_bind_text(statement, 2, pkg_tokens[1], -1, SQLITE_TRANSIENT); - sqlite3_bind_text(statement, 3, pkg_tokens[2], -1, SQLITE_TRANSIENT); - sqlite3_bind_text(statement, 4, pkg_tokens[4], -1, SQLITE_TRANSIENT); + sqlite3_bind_text(statement, 1, pkg_tokens[3].c_str(), -1, SQLITE_TRANSIENT); + 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_int(statement, 8, pkg_compressed); sqlite3_bind_int(statement, 9, pkg_uncompressed); - sqlite3_bind_text(statement, 10, pkg_tokens[0], -1, SQLITE_TRANSIENT); + sqlite3_bind_text(statement, 10, pkg_tokens[0].c_str(), -1, SQLITE_TRANSIENT); sqlite3_step(statement); sqlite3_clear_bindings(statement); sqlite3_reset(statement); /* Reset for the next package */ - g_strfreev(pkg_tokens); g_free(filename); g_free(location); g_free(summary); diff --git a/backend/utils.cpp b/backend/utils.cpp index 19d0b39..871fad8 100644 --- a/backend/utils.cpp +++ b/backend/utils.cpp @@ -11,6 +11,9 @@ module; #include #include #include +#include +#include +#include export module katja.utils; @@ -36,12 +39,33 @@ struct JobData CURL *curl; virtual void package(Info info, const char *package_id, const char *summary) = 0; - virtual void files(char **) = 0; + virtual void files(const std::vector&) = 0; virtual void details(char *package_id, const char *group, const char *description, const char *homepage, int uncompressed) = 0; virtual void set_percentage(double) = 0; }; +struct DummyJobData final : JobData +{ + + void package(Info info, const char *package_id, const char *summary) override + { + } + + void files(const std::vector&) override + { + } + + void details(char *package_id, + const char *group, const char *description, const char *homepage, int uncompressed) override + { + } + + void set_percentage(double) override + { + } +}; + /** * katja::get_file: * @curl: curl easy handle. @@ -106,37 +130,30 @@ CURLcode get_file(CURL **curl, const char *source_url, const char *dest) * katja::split_package_name: * Got the name of a package, without version-arch-release data. **/ -char **split_package_name(const char *pkg_filename) +std::optional> split_package_name(const std::string& pkg_filename) { char *pkg_full_name; - char **pkg_tokens; - g_return_val_if_fail(pkg_filename != nullptr, nullptr); - - int len = strlen(pkg_filename); + int len = pkg_filename.size(); if (len < 4) { - return nullptr; + return std::nullopt; } + std::vector pkg_tokens(5); if (pkg_filename[len - 4] == '.') { - pkg_tokens = static_cast(g_malloc_n (6, sizeof (char *))); - /* Full name without extension */ len -= 4; - pkg_full_name = g_strndup(pkg_filename, len); + pkg_full_name = g_strndup(pkg_filename.data(), len); pkg_tokens[3] = g_strdup(pkg_full_name); /* The last 3 characters should be the file extension */ - pkg_tokens[4] = g_strdup(pkg_filename + len + 1); - pkg_tokens[5] = nullptr; + pkg_tokens[4] = g_strdup(pkg_filename.data() + len + 1); } else { - pkg_tokens = static_cast(g_malloc_n (4, sizeof (char *))); - pkg_full_name = g_strdup(pkg_filename); - pkg_tokens[3] = nullptr; + pkg_full_name = g_strdup(pkg_filename.c_str()); } /* Reverse all of the bytes in the package filename to get the name, version and the architecture */