|
|
fe1899 |
From 8987652fe1f1dca674a0726e6d967c60ed79e8b6 Mon Sep 17 00:00:00 2001
|
|
|
fe1899 |
From: Matthew Almond <malmond@fb.com>
|
|
|
fe1899 |
Date: Mon, 8 Mar 2021 12:57:53 -0800
|
|
|
fe1899 |
Subject: [PATCH 1/2] Expose librepo's checksum functions via SWIG
|
|
|
fe1899 |
|
|
|
fe1899 |
DNF has been carrying around yum's old checksum function. These
|
|
|
fe1899 |
functions duplicate code in librepo. They are slower because librepo can
|
|
|
fe1899 |
employ caching of digests. Lastly, these functions in Python do not know
|
|
|
fe1899 |
about changes in checksum logic like
|
|
|
fe1899 |
https://github.com/rpm-software-management/librepo/pull/222
|
|
|
fe1899 |
|
|
|
fe1899 |
The choices here are:
|
|
|
fe1899 |
|
|
|
fe1899 |
1. Replicate `lr_checksum_cow_fd()` and caching logic in Python
|
|
|
fe1899 |
2. Just use librepo from dnf.
|
|
|
fe1899 |
|
|
|
fe1899 |
This is 2. Note there was bug in librepo that forces no caching
|
|
|
fe1899 |
for `checksum_value()`
|
|
|
fe1899 |
(https://github.com/rpm-software-management/librepo/issues/233). This is
|
|
|
fe1899 |
now fixed, so we depend on librepo-1.13.1 to ensure this fix is present.
|
|
|
fe1899 |
|
|
|
fe1899 |
This change goes hand in hand with a change to `dnf` itself to make use
|
|
|
fe1899 |
of the new functions and eliminate the old ones. This is
|
|
|
fe1899 |
https://github.com/rpm-software-management/dnf/pull/1743. We bump the
|
|
|
fe1899 |
version of this library in the next commit to ensure this dependency is
|
|
|
fe1899 |
expressed properly.
|
|
|
fe1899 |
|
|
|
fe1899 |
On errors, these functions raise libdnf.error.Error which can be easily
|
|
|
fe1899 |
mapped into MiscError in dnf
|
|
|
fe1899 |
---
|
|
|
fe1899 |
bindings/swig/utils.i | 3 +++
|
|
|
fe1899 |
libdnf/utils/utils.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++
|
|
|
fe1899 |
libdnf/utils/utils.hpp | 16 ++++++++++++++
|
|
|
fe1899 |
3 files changed, 69 insertions(+)
|
|
|
fe1899 |
|
|
|
fe1899 |
diff --git a/bindings/swig/utils.i b/bindings/swig/utils.i
|
|
|
fe1899 |
index 60fabb02d..df323e375 100644
|
|
|
fe1899 |
--- a/bindings/swig/utils.i
|
|
|
fe1899 |
+++ b/bindings/swig/utils.i
|
|
|
fe1899 |
@@ -44,4 +44,7 @@ namespace libdnf { namespace filesystem {
|
|
|
fe1899 |
|
|
|
fe1899 |
void decompress(const char * inPath, const char * outPath, mode_t outMode, const char * compressType = nullptr);
|
|
|
fe1899 |
|
|
|
fe1899 |
+bool checksum_check(const char * type, const char * inPath, const char * checksum_valid);
|
|
|
fe1899 |
+std::string checksum_value(const char * type, const char * inPath);
|
|
|
fe1899 |
+
|
|
|
fe1899 |
}}
|
|
|
fe1899 |
diff --git a/libdnf/utils/utils.cpp b/libdnf/utils/utils.cpp
|
|
|
fe1899 |
index 1a83bfbd2..450718d37 100644
|
|
|
fe1899 |
--- a/libdnf/utils/utils.cpp
|
|
|
fe1899 |
+++ b/libdnf/utils/utils.cpp
|
|
|
fe1899 |
@@ -1,6 +1,7 @@
|
|
|
fe1899 |
#include "utils.hpp"
|
|
|
fe1899 |
#include "libdnf/dnf-sack-private.hpp"
|
|
|
fe1899 |
#include "libdnf/sack/advisorymodule.hpp"
|
|
|
fe1899 |
+#include <librepo/librepo.h>
|
|
|
fe1899 |
|
|
|
fe1899 |
#include <tinyformat/tinyformat.hpp>
|
|
|
fe1899 |
|
|
|
fe1899 |
@@ -300,6 +301,55 @@ void decompress(const char * inPath, const char * outPath, mode_t outMode, const
|
|
|
fe1899 |
fclose(inFile);
|
|
|
fe1899 |
}
|
|
|
fe1899 |
|
|
|
fe1899 |
+void checksum(const char * type, const char * inPath, const char * checksum_valid, bool * valid_out, gchar ** calculated_out)
|
|
|
fe1899 |
+{
|
|
|
fe1899 |
+ GError * errP{nullptr};
|
|
|
fe1899 |
+ gboolean valid;
|
|
|
fe1899 |
+ LrChecksumType lr_type = lr_checksum_type(type);
|
|
|
fe1899 |
+
|
|
|
fe1899 |
+ if (lr_type == LR_CHECKSUM_UNKNOWN)
|
|
|
fe1899 |
+ throw libdnf::Error(tfm::format("Unknown checksum type %s", type));
|
|
|
fe1899 |
+
|
|
|
fe1899 |
+ auto inFd = open(inPath, O_RDONLY);
|
|
|
fe1899 |
+
|
|
|
fe1899 |
+ if (inFd == -1)
|
|
|
fe1899 |
+ throw libdnf::Error(tfm::format("Error opening %s: %s", inPath, strerror(errno)));
|
|
|
fe1899 |
+
|
|
|
fe1899 |
+ auto ret = lr_checksum_fd_compare(lr_type,
|
|
|
fe1899 |
+ inFd,
|
|
|
fe1899 |
+ /**
|
|
|
fe1899 |
+ * If checksum_valid references a string, pass it in, else use
|
|
|
fe1899 |
+ * an empty string
|
|
|
fe1899 |
+ */
|
|
|
fe1899 |
+ checksum_valid ? checksum_valid : "",
|
|
|
fe1899 |
+ TRUE,
|
|
|
fe1899 |
+ &valid,
|
|
|
fe1899 |
+ calculated_out,
|
|
|
fe1899 |
+ &errP);
|
|
|
fe1899 |
+
|
|
|
fe1899 |
+ close(inFd);
|
|
|
fe1899 |
+ if (!ret)
|
|
|
fe1899 |
+ throw libdnf::Error(tfm::format("Error calculating checksum %s: (%d, %s)", inPath, errP->code, errP->message));
|
|
|
fe1899 |
+ if (valid_out)
|
|
|
fe1899 |
+ *valid_out = valid == TRUE; /* gboolean -> bool */
|
|
|
fe1899 |
+}
|
|
|
fe1899 |
+
|
|
|
fe1899 |
+
|
|
|
fe1899 |
+bool checksum_check(const char * type, const char * inPath, const char * checksum_valid)
|
|
|
fe1899 |
+{
|
|
|
fe1899 |
+ bool valid;
|
|
|
fe1899 |
+ checksum(type, inPath, checksum_valid, &valid, NULL);
|
|
|
fe1899 |
+ return valid;
|
|
|
fe1899 |
+}
|
|
|
fe1899 |
+
|
|
|
fe1899 |
+std::string checksum_value(const char * type, const char * inPath)
|
|
|
fe1899 |
+{
|
|
|
fe1899 |
+ g_autofree gchar *calculated = NULL;
|
|
|
fe1899 |
+ checksum(type, inPath, NULL, NULL, &calculated);
|
|
|
fe1899 |
+ std::string out(calculated);
|
|
|
fe1899 |
+ return out;
|
|
|
fe1899 |
+}
|
|
|
fe1899 |
+
|
|
|
fe1899 |
}
|
|
|
fe1899 |
|
|
|
fe1899 |
namespace numeric {
|
|
|
fe1899 |
diff --git a/libdnf/utils/utils.hpp b/libdnf/utils/utils.hpp
|
|
|
fe1899 |
index 5d755e017..43ca9ff34 100644
|
|
|
fe1899 |
--- a/libdnf/utils/utils.hpp
|
|
|
fe1899 |
+++ b/libdnf/utils/utils.hpp
|
|
|
fe1899 |
@@ -68,6 +68,22 @@ std::vector<std::string> getDirContent(const std::string &dirPath);
|
|
|
fe1899 |
* @param compressType Type of compression (".bz2", ".gz", ...), nullptr - detect from inPath filename. Defaults to nullptr.
|
|
|
fe1899 |
*/
|
|
|
fe1899 |
void decompress(const char * inPath, const char * outPath, mode_t outMode, const char * compressType = nullptr);
|
|
|
fe1899 |
+
|
|
|
fe1899 |
+/**
|
|
|
fe1899 |
+* @brief checksum file and return if matching.
|
|
|
fe1899 |
+*
|
|
|
fe1899 |
+* @param type Checksum type ("sha", "sha1", "sha256" etc). Raises libdnf::Error if invalid.
|
|
|
fe1899 |
+* @param inPath Path to input file
|
|
|
fe1899 |
+* @param valid_checksum hexadecimal encoded checksum string.
|
|
|
fe1899 |
+*/
|
|
|
fe1899 |
+bool checksum_check(const char * type, const char * inPath, const char * valid_checksum);
|
|
|
fe1899 |
+/**
|
|
|
fe1899 |
+* @brief checksum file and return checksum.
|
|
|
fe1899 |
+*
|
|
|
fe1899 |
+* @param type Checksum type ("sha", "sha1", "sha256" etc). Raises libdnf::Error if invalid.
|
|
|
fe1899 |
+* @param inPath Path to input file
|
|
|
fe1899 |
+*/
|
|
|
fe1899 |
+std::string checksum_value(const char * type, const char * inPath);
|
|
|
fe1899 |
}
|
|
|
fe1899 |
|
|
|
fe1899 |
namespace numeric {
|
|
|
fe1899 |
|