Query the modification time with std::filesystem
This commit is contained in:
+24
-83
@@ -21,6 +21,7 @@ module;
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
export module katja.job;
|
export module katja.job;
|
||||||
|
|
||||||
@@ -38,21 +39,18 @@ void pk_backend_initialize(GKeyFile *conf)
|
|||||||
int ret;
|
int ret;
|
||||||
std::uint8_t i;
|
std::uint8_t i;
|
||||||
std::size_t groups_len;
|
std::size_t groups_len;
|
||||||
GFile *conf_file;
|
|
||||||
GFileInfo *file_info;
|
|
||||||
GKeyFile *key_conf;
|
GKeyFile *key_conf;
|
||||||
GError *err = nullptr;
|
GError *err = nullptr;
|
||||||
sqlite3 *db;
|
sqlite3 *db;
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
g_debug("backend: initialize");
|
|
||||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||||
|
|
||||||
/* Open the database. We will need it to save the time the configuration file was last modified. */
|
/* Open the database. We will need it to save the time the configuration file was last modified. */
|
||||||
auto path = std::filesystem::path(LOCALSTATEDIR) / "cache" / "katja" / "metadata.db";
|
auto path = std::filesystem::path(LOCALSTATEDIR) / "cache" / "katja" / "metadata.db";
|
||||||
if (sqlite3_open(path.c_str(), &db) != SQLITE_OK)
|
if (sqlite3_open(path.c_str(), &db) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
g_error("%s: %s", path.c_str(), sqlite3_errmsg(db));
|
std::cerr << path.native() << ": " << sqlite3_errmsg(db) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the configuration file */
|
/* Read the configuration file */
|
||||||
@@ -61,27 +59,19 @@ void pk_backend_initialize(GKeyFile *conf)
|
|||||||
g_key_file_load_from_file(key_conf, path.c_str(), G_KEY_FILE_NONE, &err);
|
g_key_file_load_from_file(key_conf, path.c_str(), G_KEY_FILE_NONE, &err);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
g_error("%s: %s", path.c_str(), err->message);
|
std::cerr << path.native() << ": " << err->message << std::endl;
|
||||||
g_error_free(err);
|
g_error_free(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
conf_file = g_file_new_for_path(path.c_str());
|
std::chrono::time_point<std::chrono::file_clock> file_info = std::filesystem::last_write_time(path);
|
||||||
if (!(file_info = g_file_query_info(conf_file,
|
auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(file_info.time_since_epoch());
|
||||||
"time::modified-usec",
|
|
||||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
||||||
nullptr,
|
|
||||||
&err)))
|
|
||||||
{
|
|
||||||
g_error("%s", err->message);
|
|
||||||
g_error_free(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = sqlite3_prepare_v2(db,
|
if ((ret = sqlite3_prepare_v2(db,
|
||||||
"UPDATE cache_info SET value = ? WHERE key LIKE 'last_modification'",
|
"UPDATE cache_info SET value = ? WHERE key LIKE 'last_modification'",
|
||||||
-1,
|
-1,
|
||||||
&stmt,
|
&stmt,
|
||||||
nullptr)) == SQLITE_OK) {
|
nullptr)) == SQLITE_OK) {
|
||||||
ret = sqlite3_bind_int(stmt, 1, g_file_info_get_attribute_uint32(file_info, "time::modified-usec"));
|
ret = sqlite3_bind_int(stmt, 1, microseconds.count());
|
||||||
if (ret == SQLITE_OK)
|
if (ret == SQLITE_OK)
|
||||||
{
|
{
|
||||||
ret = sqlite3_step(stmt);
|
ret = sqlite3_step(stmt);
|
||||||
@@ -90,15 +80,12 @@ void pk_backend_initialize(GKeyFile *conf)
|
|||||||
}
|
}
|
||||||
if ((ret != SQLITE_OK) && (ret != SQLITE_DONE))
|
if ((ret != SQLITE_OK) && (ret != SQLITE_DONE))
|
||||||
{
|
{
|
||||||
g_error("%s: %s", path.c_str(), sqlite3_errstr(ret));
|
std::cerr << path.native() << ": " << sqlite3_errstr(ret) << std::endl;
|
||||||
}
|
}
|
||||||
else if (!sqlite3_changes(db))
|
else if (!sqlite3_changes(db))
|
||||||
{
|
{
|
||||||
g_error("Failed to update database: %s", path.c_str());
|
std::cerr << "Failed to update database: " << path.native() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref(file_info);
|
|
||||||
g_object_unref(conf_file);
|
|
||||||
sqlite3_close_v2(db);
|
sqlite3_close_v2(db);
|
||||||
|
|
||||||
/* Initialize an object for each well-formed repository */
|
/* Initialize an object for each well-formed repository */
|
||||||
@@ -124,8 +111,6 @@ void pk_backend_initialize(GKeyFile *conf)
|
|||||||
|
|
||||||
void pk_backend_destroy()
|
void pk_backend_destroy()
|
||||||
{
|
{
|
||||||
g_debug("backend: destroy");
|
|
||||||
|
|
||||||
repos.clear();
|
repos.clear();
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
}
|
}
|
||||||
@@ -243,8 +228,8 @@ void pk_backend_get_details(JobData *job_data, char **package_ids)
|
|||||||
{
|
{
|
||||||
std::optional<std::string> homepage;
|
std::optional<std::string> homepage;
|
||||||
std::size_t i;
|
std::size_t i;
|
||||||
GRegex *expr;
|
std::regex expr;
|
||||||
GMatchInfo *match_info;
|
std::smatch match_info;
|
||||||
GError *err = nullptr;
|
GError *err = nullptr;
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
std::string desc;
|
std::string desc;
|
||||||
@@ -271,19 +256,12 @@ void pk_backend_get_details(JobData *job_data, char **package_ids)
|
|||||||
desc = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
|
desc = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
|
||||||
|
|
||||||
/* Regular expression for searching a homepage */
|
/* Regular expression for searching a homepage */
|
||||||
expr = g_regex_new("(?:http|ftp):\\/\\/[[:word:]\\/\\-\\.]+[[:word:]\\/](?=\\.?$)",
|
expr = std::regex("(?:http|ftp):\\/\\/[[:word:]\\/\\-\\.]+[[:word:]\\/](?=\\.?$)",
|
||||||
(GRegexCompileFlags)(G_REGEX_OPTIMIZE | G_REGEX_DUPNAMES),
|
std::regex::optimize);
|
||||||
(GRegexMatchFlags)(0),
|
|
||||||
&err);
|
if (std::regex_match(std::cbegin(desc), std::cend(desc), match_info, expr))
|
||||||
if (err)
|
|
||||||
{
|
{
|
||||||
std::cerr << err->message << std::endl;
|
homepage = match_info[0]; /* URL */
|
||||||
g_error_free(err);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
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 */
|
/* Remove the last sentence with the copied URL */
|
||||||
for (i = desc.size() - 1; i > 0; i--)
|
for (i = desc.size() - 1; i > 0; i--)
|
||||||
{
|
{
|
||||||
@@ -293,9 +271,7 @@ void pk_backend_get_details(JobData *job_data, char **package_ids)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_match_info_free(match_info);
|
|
||||||
}
|
}
|
||||||
g_regex_unref(expr);
|
|
||||||
|
|
||||||
/* Ready */
|
/* Ready */
|
||||||
job_data->details(package_ids[0],
|
job_data->details(package_ids[0],
|
||||||
@@ -531,11 +507,8 @@ void pk_backend_remove_packages(JobData* job_data, const std::vector<std::string
|
|||||||
|
|
||||||
void pk_backend_get_updates(JobData *job_data)
|
void pk_backend_get_updates(JobData *job_data)
|
||||||
{
|
{
|
||||||
const char *pkg_metadata_filename;
|
std::filesystem::path pkg_metadata_filename;
|
||||||
GFile *pkg_metadata_dir;
|
std::filesystem::path pkg_metadata_dir;
|
||||||
GFileEnumerator *pkg_metadata_enumerator;
|
|
||||||
GFileInfo *pkg_metadata_file_info;
|
|
||||||
GError *err = nullptr;
|
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
if ((sqlite3_prepare_v2(job_data->db,
|
if ((sqlite3_prepare_v2(job_data->db,
|
||||||
@@ -552,22 +525,10 @@ void pk_backend_get_updates(JobData *job_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read the package metadata directory and comprare all installed packages with ones in the cache */
|
/* Read the package metadata directory and comprare all installed packages with ones in the cache */
|
||||||
pkg_metadata_dir = g_file_new_for_path("/var/log/packages");
|
pkg_metadata_dir = std::filesystem::path("/var/log/packages");
|
||||||
pkg_metadata_enumerator = g_file_enumerate_children(pkg_metadata_dir, "standard::name",
|
for (const auto& pkg_metadata_file_info : std::filesystem::directory_iterator{ pkg_metadata_dir })
|
||||||
G_FILE_QUERY_INFO_NONE,
|
|
||||||
nullptr,
|
|
||||||
&err);
|
|
||||||
g_object_unref(pkg_metadata_dir);
|
|
||||||
if (err)
|
|
||||||
{
|
{
|
||||||
std::cerr << "/var/log/packages: " << err->message << std::endl;
|
pkg_metadata_filename = pkg_metadata_file_info.path();
|
||||||
g_error_free(err);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((pkg_metadata_file_info = g_file_enumerator_next_file(pkg_metadata_enumerator, nullptr, nullptr)))
|
|
||||||
{
|
|
||||||
pkg_metadata_filename = g_file_info_get_name(pkg_metadata_file_info);
|
|
||||||
std::vector<std::string> tokens = split_package_name(pkg_metadata_filename).value();
|
std::vector<std::string> tokens = split_package_name(pkg_metadata_filename).value();
|
||||||
|
|
||||||
/* Select the package from the database */
|
/* Select the package from the database */
|
||||||
@@ -597,10 +558,7 @@ void pk_backend_get_updates(JobData *job_data)
|
|||||||
|
|
||||||
sqlite3_clear_bindings(stmt);
|
sqlite3_clear_bindings(stmt);
|
||||||
sqlite3_reset(stmt);
|
sqlite3_reset(stmt);
|
||||||
|
|
||||||
g_object_unref(pkg_metadata_file_info);
|
|
||||||
}
|
}
|
||||||
g_object_unref(pkg_metadata_enumerator);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
@@ -644,9 +602,6 @@ void pk_backend_refresh_cache(JobData *job_data, bool force)
|
|||||||
char *db_err;
|
char *db_err;
|
||||||
int ret;
|
int ret;
|
||||||
std::forward_list<katja::cache_entry> file_list;
|
std::forward_list<katja::cache_entry> file_list;
|
||||||
GFile *db_file = nullptr;
|
|
||||||
GFileInfo *file_info = nullptr;
|
|
||||||
GError *err = nullptr;
|
|
||||||
sqlite3_stmt *stmt = nullptr;
|
sqlite3_stmt *stmt = nullptr;
|
||||||
|
|
||||||
/* Create temporary directory */
|
/* Create temporary directory */
|
||||||
@@ -658,14 +613,8 @@ void pk_backend_refresh_cache(JobData *job_data, bool force)
|
|||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
auto path = std::filesystem::path(LOCALSTATEDIR) / "cache" / "katja" / "metadata.db";
|
auto path = std::filesystem::path(LOCALSTATEDIR) / "cache" / "katja" / "metadata.db";
|
||||||
db_file = g_file_new_for_path(path.native().c_str());
|
std::chrono::time_point<std::chrono::file_clock> file_info = std::filesystem::last_write_time(path);
|
||||||
file_info = g_file_query_info(db_file, "time::modified-usec", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, nullptr, &err);
|
auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(file_info.time_since_epoch());
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
std::cerr << path << ": " << err->message;
|
|
||||||
g_error_free(err);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ret = sqlite3_prepare_v2(job_data->db,
|
ret = sqlite3_prepare_v2(job_data->db,
|
||||||
"SELECT value FROM cache_info WHERE key LIKE 'last_modification'",
|
"SELECT value FROM cache_info WHERE key LIKE 'last_modification'",
|
||||||
-1,
|
-1,
|
||||||
@@ -676,7 +625,7 @@ void pk_backend_refresh_cache(JobData *job_data, bool force)
|
|||||||
std::cerr << path << ": " << sqlite3_errstr(ret) << std::endl;
|
std::cerr << path << ": " << sqlite3_errstr(ret) << std::endl;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if ((std::uint32_t) sqlite3_column_int(stmt, 0) > g_file_info_get_attribute_uint32(file_info, "time::modified-usec"))
|
if ((std::uint32_t) sqlite3_column_int(stmt, 0) > microseconds.count())
|
||||||
{
|
{
|
||||||
force = true;
|
force = true;
|
||||||
}
|
}
|
||||||
@@ -700,7 +649,7 @@ void pk_backend_refresh_cache(JobData *job_data, bool force)
|
|||||||
/* Download repository */
|
/* Download repository */
|
||||||
for (auto& l : file_list)
|
for (auto& l : file_list)
|
||||||
{
|
{
|
||||||
get_file(&job_data->curl, l.first.c_str(), l.second.native().c_str());
|
get_file(&job_data->curl, l.first.c_str(), l.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Refresh cache */
|
/* Refresh cache */
|
||||||
@@ -711,14 +660,6 @@ void pk_backend_refresh_cache(JobData *job_data, bool force)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
if (file_info)
|
|
||||||
{
|
|
||||||
g_object_unref(file_info);
|
|
||||||
}
|
|
||||||
if (db_file)
|
|
||||||
{
|
|
||||||
g_object_unref(db_file);
|
|
||||||
}
|
|
||||||
std::filesystem::remove_all(tmp_dir_name);
|
std::filesystem::remove_all(tmp_dir_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public:
|
|||||||
+ reinterpret_cast<const char *>(sqlite3_column_text(statement, 1));
|
+ reinterpret_cast<const char *>(sqlite3_column_text(statement, 1));
|
||||||
|
|
||||||
ret = std::filesystem::exists(dest_filename)
|
ret = std::filesystem::exists(dest_filename)
|
||||||
|| get_file(&curl, source_url.c_str(), dest_filename.native().c_str()) == CURLE_OK;
|
|| get_file(&curl, source_url.c_str(), dest_filename) == CURLE_OK;
|
||||||
|
|
||||||
if (curl)
|
if (curl)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public:
|
|||||||
source_dest.first = this->mirror + current_priority + "/PACKAGES.TXT";
|
source_dest.first = this->mirror + current_priority + "/PACKAGES.TXT";
|
||||||
source_dest.second = 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)
|
if (get_file(&curl, source_dest.first.c_str(), std::nullopt) == CURLE_OK)
|
||||||
{
|
{
|
||||||
file_list.emplace_front(std::move(source_dest));
|
file_list.emplace_front(std::move(source_dest));
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ public:
|
|||||||
source_dest.first = this->mirror + current_priority + "/MANIFEST.bz2";
|
source_dest.first = this->mirror + current_priority + "/MANIFEST.bz2";
|
||||||
source_dest.second = 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)
|
if (get_file(&curl, source_dest.first.c_str(), std::nullopt) == CURLE_OK)
|
||||||
{
|
{
|
||||||
file_list.emplace_front(std::move(source_dest));
|
file_list.emplace_front(std::move(source_dest));
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-47
@@ -14,6 +14,8 @@ module;
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
export module katja.utils;
|
export module katja.utils;
|
||||||
|
|
||||||
@@ -76,12 +78,12 @@ struct DummyJobData final : JobData
|
|||||||
*
|
*
|
||||||
* Returns: CURLE_OK (zero) on success, non-zero otherwise.
|
* Returns: CURLE_OK (zero) on success, non-zero otherwise.
|
||||||
**/
|
**/
|
||||||
CURLcode get_file(CURL **curl, const char *source_url, const char *dest)
|
CURLcode get_file(CURL **curl, const char *source_url, const std::optional<std::filesystem::path>& dest)
|
||||||
{
|
{
|
||||||
const char *dest_dir_name;
|
|
||||||
FILE *fout = nullptr;
|
FILE *fout = nullptr;
|
||||||
CURLcode ret;
|
CURLcode ret;
|
||||||
glong response_code;
|
glong response_code;
|
||||||
|
std::string dest_dir_name;
|
||||||
|
|
||||||
if ((*curl == nullptr) && (!(*curl = curl_easy_init())))
|
if ((*curl == nullptr) && (!(*curl = curl_easy_init())))
|
||||||
{
|
{
|
||||||
@@ -91,7 +93,7 @@ CURLcode get_file(CURL **curl, const char *source_url, const char *dest)
|
|||||||
curl_easy_setopt(*curl, CURLOPT_FOLLOWLOCATION, 1L);
|
curl_easy_setopt(*curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||||
curl_easy_setopt(*curl, CURLOPT_URL, source_url);
|
curl_easy_setopt(*curl, CURLOPT_URL, source_url);
|
||||||
|
|
||||||
if (dest == nullptr)
|
if (!dest.has_value())
|
||||||
{
|
{
|
||||||
curl_easy_setopt(*curl, CURLOPT_NOBODY, 1L);
|
curl_easy_setopt(*curl, CURLOPT_NOBODY, 1L);
|
||||||
curl_easy_setopt(*curl, CURLOPT_HEADER, 1L);
|
curl_easy_setopt(*curl, CURLOPT_HEADER, 1L);
|
||||||
@@ -105,13 +107,12 @@ CURLcode get_file(CURL **curl, const char *source_url, const char *dest)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (g_file_test(dest, G_FILE_TEST_IS_DIR))
|
dest_dir_name = dest.value().native();
|
||||||
|
if (std::filesystem::is_directory(dest.value()))
|
||||||
{
|
{
|
||||||
dest_dir_name = dest;
|
dest_dir_name += strrchr(source_url, '/');
|
||||||
dest = g_strconcat(dest_dir_name, g_strrstr(source_url, "/"), nullptr);
|
|
||||||
g_free(const_cast<char *>(dest_dir_name));
|
|
||||||
}
|
}
|
||||||
if ((fout = fopen(dest, "ab")) == nullptr)
|
if ((fout = fopen(dest_dir_name.c_str(), "ab")) == nullptr)
|
||||||
{
|
{
|
||||||
return CURLE_WRITE_ERROR;
|
return CURLE_WRITE_ERROR;
|
||||||
}
|
}
|
||||||
@@ -132,7 +133,7 @@ CURLcode get_file(CURL **curl, const char *source_url, const char *dest)
|
|||||||
**/
|
**/
|
||||||
std::optional<std::vector<std::string>> split_package_name(const std::string& pkg_filename)
|
std::optional<std::vector<std::string>> split_package_name(const std::string& pkg_filename)
|
||||||
{
|
{
|
||||||
char *pkg_full_name;
|
std::string pkg_full_name;
|
||||||
|
|
||||||
int len = pkg_filename.size();
|
int len = pkg_filename.size();
|
||||||
if (len < 4)
|
if (len < 4)
|
||||||
@@ -144,28 +145,23 @@ std::optional<std::vector<std::string>> split_package_name(const std::string& pk
|
|||||||
if (pkg_filename[len - 4] == '.')
|
if (pkg_filename[len - 4] == '.')
|
||||||
{
|
{
|
||||||
/* Full name without extension */
|
/* Full name without extension */
|
||||||
len -= 4;
|
pkg_tokens[3] = pkg_filename;
|
||||||
pkg_full_name = g_strndup(pkg_filename.data(), len);
|
pkg_full_name = std::string(std::crbegin(pkg_filename) + 4, std::crend(pkg_filename));
|
||||||
pkg_tokens[3] = g_strdup(pkg_full_name);
|
|
||||||
|
|
||||||
/* The last 3 characters should be the file extension */
|
/* The last 3 characters should be the file extension */
|
||||||
pkg_tokens[4] = g_strdup(pkg_filename.data() + len + 1);
|
pkg_tokens[4] = std::string(std::cbegin(pkg_filename) + len + 1, std::cend(pkg_filename));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pkg_full_name = g_strdup(pkg_filename.c_str());
|
pkg_full_name = std::string(std::crbegin(pkg_filename), std::crend(pkg_filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reverse all of the bytes in the package filename to get the name, version and the architecture */
|
/* Reverse all of the bytes in the package filename to get the name, version and the architecture */
|
||||||
g_strreverse (pkg_full_name);
|
std::vector<std::string> reversed_tokens;
|
||||||
char **reversed_tokens = g_strsplit(pkg_full_name, "-", 4);
|
boost::algorithm::split(reversed_tokens, pkg_full_name, boost::is_any_of("-"));
|
||||||
pkg_tokens[0] = g_strreverse(reversed_tokens[3]); /* Name */
|
pkg_tokens[0] = std::string(std::crbegin(reversed_tokens[3]), std::crend(reversed_tokens[3])); /* Name */
|
||||||
pkg_tokens[1] = g_strreverse(reversed_tokens[2]); /* Version */
|
pkg_tokens[1] = std::string(std::crbegin(reversed_tokens[2]), std::crend(reversed_tokens[2])); /* Version */
|
||||||
pkg_tokens[2] = g_strreverse(reversed_tokens[1]); /* Architecture */
|
pkg_tokens[2] = std::string(std::crbegin(reversed_tokens[1]), std::crend(reversed_tokens[1])); /* Architecture */
|
||||||
|
|
||||||
g_free(reversed_tokens[0]); /* Build number */
|
|
||||||
g_free(reversed_tokens);
|
|
||||||
g_free(pkg_full_name);
|
|
||||||
|
|
||||||
return pkg_tokens;
|
return pkg_tokens;
|
||||||
}
|
}
|
||||||
@@ -180,20 +176,18 @@ std::optional<std::vector<std::string>> split_package_name(const std::string& pk
|
|||||||
**/
|
**/
|
||||||
Info is_installed(const char *pkg_fullname)
|
Info is_installed(const char *pkg_fullname)
|
||||||
{
|
{
|
||||||
GFileEnumerator *pkg_metadata_enumerator;
|
|
||||||
GFileInfo *pkg_metadata_file_info;
|
|
||||||
GFile *pkg_metadata_dir;
|
|
||||||
Info ret = Info::installing;
|
Info ret = Info::installing;
|
||||||
const char *it;
|
const char *it;
|
||||||
std::uint8_t dashes = 0;
|
std::uint8_t dashes = 0;
|
||||||
ptrdiff_t pkg_name;
|
ptrdiff_t pkg_name;
|
||||||
|
|
||||||
g_return_val_if_fail(pkg_fullname != nullptr, Info::unknown);
|
if (pkg_fullname == nullptr)
|
||||||
|
{
|
||||||
|
return Info::unknown;
|
||||||
|
}
|
||||||
|
|
||||||
// We want to find the package name without version for the package we're
|
// We want to find the package name without version for the package we're
|
||||||
// looking for.
|
// looking for.
|
||||||
g_debug("Looking if %s is installed", pkg_fullname);
|
|
||||||
|
|
||||||
for (it = pkg_fullname + strlen(pkg_fullname); it != pkg_fullname; --it)
|
for (it = pkg_fullname + strlen(pkg_fullname); it != pkg_fullname; --it)
|
||||||
{
|
{
|
||||||
if (*it == '-')
|
if (*it == '-')
|
||||||
@@ -213,29 +207,21 @@ Info is_installed(const char *pkg_fullname)
|
|||||||
|
|
||||||
// Read the package metadata directory and comprare all installed packages
|
// Read the package metadata directory and comprare all installed packages
|
||||||
// with ones in the cache.
|
// with ones in the cache.
|
||||||
pkg_metadata_dir = g_file_new_for_path("/var/log/packages");
|
auto pkg_metadata_dir = std::filesystem::path("/var/log/packages");
|
||||||
if (!(pkg_metadata_enumerator = g_file_enumerate_children(pkg_metadata_dir,
|
|
||||||
"standard::name",
|
|
||||||
G_FILE_QUERY_INFO_NONE,
|
|
||||||
nullptr,
|
|
||||||
nullptr)))
|
|
||||||
{
|
|
||||||
g_object_unref(pkg_metadata_dir);
|
|
||||||
return Info::unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((pkg_metadata_file_info = g_file_enumerator_next_file(pkg_metadata_enumerator, nullptr, nullptr)))
|
for (const auto& pkg_metadata_file_info : std::filesystem::directory_iterator{ pkg_metadata_dir })
|
||||||
{
|
{
|
||||||
const char *dir = g_file_info_get_name(pkg_metadata_file_info);
|
std::string filename = pkg_metadata_file_info.path().native();
|
||||||
|
const char *dir = filename.c_str();
|
||||||
dashes = 0;
|
dashes = 0;
|
||||||
|
|
||||||
if (strcmp(dir, pkg_fullname) == 0)
|
if (dir == pkg_fullname)
|
||||||
{
|
{
|
||||||
ret = Info::installed;
|
ret = Info::installed;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (it = dir + strlen(dir); it != dir; --it)
|
for (it = dir + filename.size(); it != dir; --it)
|
||||||
{
|
{
|
||||||
if (*it == '-')
|
if (*it == '-')
|
||||||
{
|
{
|
||||||
@@ -251,15 +237,11 @@ Info is_installed(const char *pkg_fullname)
|
|||||||
ret = Info::updating;
|
ret = Info::updating;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_object_unref(pkg_metadata_file_info);
|
|
||||||
|
|
||||||
if (ret != Info::installing) /* If installed */
|
if (ret != Info::installing) /* If installed */
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_object_unref(pkg_metadata_enumerator);
|
|
||||||
g_object_unref(pkg_metadata_dir);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user