diff --git a/bindings/swig/utils.i b/bindings/swig/utils.i index 60fabb02d6..df323e3755 100644 --- a/bindings/swig/utils.i +++ b/bindings/swig/utils.i @@ -44,4 +44,7 @@ namespace libdnf { namespace filesystem { void decompress(const char * inPath, const char * outPath, mode_t outMode, const char * compressType = nullptr); +bool checksum_check(const char * type, const char * inPath, const char * checksum_valid); +std::string checksum_value(const char * type, const char * inPath); + }} diff --git a/libdnf/utils/utils.cpp b/libdnf/utils/utils.cpp index 2bb1290d1b..1e37b924b4 100644 --- a/libdnf/utils/utils.cpp +++ b/libdnf/utils/utils.cpp @@ -1,6 +1,7 @@ #include "utils.hpp" #include "libdnf/dnf-sack-private.hpp" #include "libdnf/sack/advisorymodule.hpp" +#include #include @@ -311,6 +312,55 @@ void decompress(const char * inPath, const char * outPath, mode_t outMode, const fclose(inFile); } +void checksum(const char * type, const char * inPath, const char * checksum_valid, bool * valid_out, gchar ** calculated_out) +{ + GError * errP{nullptr}; + gboolean valid; + LrChecksumType lr_type = lr_checksum_type(type); + + if (lr_type == LR_CHECKSUM_UNKNOWN) + throw libdnf::Error(tfm::format("Unknown checksum type %s", type)); + + auto inFd = open(inPath, O_RDONLY); + + if (inFd == -1) + throw libdnf::Error(tfm::format("Error opening %s: %s", inPath, strerror(errno))); + + auto ret = lr_checksum_fd_compare(lr_type, + inFd, + /** + * If checksum_valid references a string, pass it in, else use + * an empty string + */ + checksum_valid ? checksum_valid : "", + TRUE, + &valid, + calculated_out, + &errP); + + close(inFd); + if (!ret) + throw libdnf::Error(tfm::format("Error calculating checksum %s: (%d, %s)", inPath, errP->code, errP->message)); + if (valid_out) + *valid_out = valid == TRUE; /* gboolean -> bool */ +} + + +bool checksum_check(const char * type, const char * inPath, const char * checksum_valid) +{ + bool valid; + checksum(type, inPath, checksum_valid, &valid, NULL); + return valid; +} + +std::string checksum_value(const char * type, const char * inPath) +{ + g_autofree gchar *calculated = NULL; + checksum(type, inPath, NULL, NULL, &calculated); + std::string out(calculated); + return out; +} + } namespace numeric { diff --git a/libdnf/utils/utils.hpp b/libdnf/utils/utils.hpp index d032dd42bb..fcb84fa3e3 100644 --- a/libdnf/utils/utils.hpp +++ b/libdnf/utils/utils.hpp @@ -66,6 +66,22 @@ std::vector getDirContent(const std::string &dirPath); * @param compressType Type of compression (".bz2", ".gz", ...), nullptr - detect from inPath filename. Defaults to nullptr. */ void decompress(const char * inPath, const char * outPath, mode_t outMode, const char * compressType = nullptr); + +/** +* @brief checksum file and return if matching. +* +* @param type Checksum type ("sha", "sha1", "sha256" etc). Raises libdnf::Error if invalid. +* @param inPath Path to input file +* @param valid_checksum hexadecimal encoded checksum string. +*/ +bool checksum_check(const char * type, const char * inPath, const char * valid_checksum); +/** +* @brief checksum file and return checksum. +* +* @param type Checksum type ("sha", "sha1", "sha256" etc). Raises libdnf::Error if invalid. +* @param inPath Path to input file +*/ +std::string checksum_value(const char * type, const char * inPath); } namespace numeric {