--- /dev/null
+/*
+ * Copyright (c) 2026 SUSE LLC
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, contact Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail, you may
+ * find current contact information at www.novell.com.
+ */
+
+
+#include <boost/algorithm/string.hpp>
+
+#include <snapper/AppUtil.h>
+#include <snapper/Exception.h>
+#include <snapper/LoggerImpl.h>
+#include <snapper/SystemCmd.h>
+
+#include "../utils/text.h"
+
+#include "CmdChecksum.h"
+
+
+namespace snapper
+{
+
+ CmdChecksum::CmdChecksum(const Shell& shell, const string& chksum_bin, const string& path)
+ : path(path)
+ {
+ SystemCmd::Args cmd_args = { chksum_bin, "--", path };
+ SystemCmd cmd(shellify(shell, cmd_args));
+
+ if (cmd.retcode() != 0)
+ {
+ y2err("command '" << cmd.cmd() << "' failed: " << cmd.retcode());
+ for (const string& tmp : cmd.get_stdout())
+ y2err(tmp);
+ for (const string& tmp : cmd.get_stderr())
+ y2err(tmp);
+
+ SN_THROW(Exception(_("Failed to compute checksum.")));
+ }
+
+ parse(cmd.get_stdout());
+
+ y2mil(*this);
+ }
+
+
+ void
+ CmdChecksum::parse(const vector<string>& lines)
+ {
+ if (lines.size() != 1)
+ SN_THROW(Exception(_("Invalid number of lines in checksum output.")));
+
+ vector<string> parts;
+ boost::split(parts, lines[0], boost::is_any_of(" "), boost::token_compress_on);
+ if (parts.size() != 2)
+ {
+ y2err("Invalid checksum line: " << lines[0]);
+ SN_THROW(Exception(_("Invalid checksum output format.")));
+ }
+
+ checksum = parts[0];
+ }
+
+
+ std::ostream&
+ operator<<(std::ostream& s, const CmdChecksum& cmd_checksum)
+ {
+ s << "path: " << cmd_checksum.path << " checksum: " << cmd_checksum.checksum << '\n';
+
+ return s;
+ }
+
+
+} // namespace snapper
*/
-#ifndef SNAPPER_CMD_FILE_HASH_H
-#define SNAPPER_CMD_FILE_HASH_H
+#ifndef SNAPPER_CMD_CHECKSUM_H
+#define SNAPPER_CMD_CHECKSUM_H
#include "Shell.h"
/**
- * Find the hash of the file at the given path.
- * If `allow_failure` is `true`, errors are ignored and the hash is set to an empty
- * string.
+ * Get the checksum (e.g. sha256sum) of the file at the given path.
*/
- class CmdFileHash
+ class CmdChecksum
{
public:
- CmdFileHash(const Shell& shell, const string& chksum_bin, const string& path,
- bool allow_failure);
+ CmdChecksum(const Shell& shell, const string& checksum_bin, const string& path);
- const string& get_hash() const;
+ const string& get_checksum() const { return checksum; }
- friend std::ostream& operator<<(std::ostream& s, const CmdFileHash& cmd_filehash);
+ friend std::ostream& operator<<(std::ostream& s, const CmdChecksum& cmd_checksum);
private:
+ void parse(const vector<string>& lines);
+
const string path;
- string hash;
+ string checksum;
+
};
+++ /dev/null
-/*
- * Copyright (c) 2026 SUSE LLC
- *
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, contact Novell, Inc.
- *
- * To contact Novell about this file by physical or electronic mail, you may
- * find current contact information at www.novell.com.
- */
-
-
-#include <boost/algorithm/string.hpp>
-
-#include <snapper/AppUtil.h>
-#include <snapper/Exception.h>
-#include <snapper/LoggerImpl.h>
-#include <snapper/SystemCmd.h>
-
-#include "../utils/text.h"
-
-#include "CmdFileHash.h"
-
-
-namespace snapper
-{
-
-
- CmdFileHash::CmdFileHash(const Shell& shell, const string& chksum_bin,
- const string& path, bool allow_failure)
- : path(path)
- {
- SystemCmd::Args cmd_args = { chksum_bin, "--", path };
- SystemCmd cmd(shellify(shell, cmd_args));
-
- try
- {
- if (cmd.retcode() != 0)
- {
- y2err("command '" << cmd.cmd() << "' failed: " << cmd.retcode());
- for (const string& tmp : cmd.get_stdout())
- y2err(tmp);
- for (const string& tmp : cmd.get_stderr())
- y2err(tmp);
-
- SN_THROW(Exception(_("Failed to compute file hash.")));
- }
- else
- {
- // Check if the hash utility returns 1 line exactly
- vector<string> cmd_outputs = cmd.get_stdout();
- if (cmd_outputs.size() != 1)
- {
- y2err(sformat("Expected 1 line, but %lu lines were received from %s.",
- cmd_outputs.size(), chksum_bin.c_str()));
- SN_THROW(Exception(_("Unexpected output from the hash utility.")));
- }
-
- // Parse the hash output
- vector<string> parts;
- const string& line = cmd_outputs[0];
- boost::split(parts, line, boost::is_any_of(" "),
- boost::token_compress_on);
- if (parts.size() != 2)
- {
- y2err("Invalid hash string: " << line);
- SN_THROW(Exception(_("Invalid hash output format.")));
- }
-
- hash = parts[0];
- }
- }
- catch (const Exception& e)
- {
- if (!allow_failure)
- {
- SN_THROW(e);
- }
- else
- {
- y2err(e);
- }
- }
-
- y2mil(*this);
- }
-
-
- const string& CmdFileHash::get_hash() const { return hash; }
-
- std::ostream& operator<<(std::ostream& s, const CmdFileHash& cmd_filehash)
- {
- s << "path: " << cmd_filehash.path << " hash: " << cmd_filehash.hash << '\n';
-
- return s;
- }
-
-
-} // namespace snapper
Shell.cc Shell.h \
CmdBtrfs.cc CmdBtrfs.h \
CmdLs.cc CmdLs.h \
- CmdFileHash.cc CmdFileHash.h \
+ CmdChecksum.cc CmdChecksum.h \
JsonFile.cc JsonFile.h \
utils.cc utils.h \
TreeView.cc TreeView.h
#include "CmdBtrfs.h"
#include "CmdLs.h"
-#include "CmdFileHash.h"
+#include "CmdChecksum.h"
#include "BackupConfig.h"
#include "TheBigThing.h"
the_big_thing.source_received_uuid = extra.get_received_uuid();
the_big_thing.source_creation_time = extra.get_creation_time();
- // Find the hash of info.xml
- CmdFileHash cmd_filehash(shell_source, SHA256SUM_BIN,
- source_snapshot_dir(snapper, num) + "/info.xml",
- false);
- the_big_thing.source_meta_hash = cmd_filehash.get_hash();
+ // Get the checksum of info.xml.
+ CmdChecksum cmd_checksum(shell_source, SHA256SUM_BIN,
+ source_snapshot_dir(snapper, num) + "/info.xml");
+ the_big_thing.source_meta_checksum = cmd_checksum.get_checksum();
the_big_things.push_back(the_big_thing);
}
it->target_received_uuid = extra.get_received_uuid();
it->target_creation_time = extra.get_creation_time();
- // Find the hash of info.xml
- CmdFileHash cmd_filehash(
- shell_target, backup_config.target_sha256sum_bin,
- target_snapshot_dir(backup_config, num) + "/info.xml", true);
- it->target_meta_hash = cmd_filehash.get_hash();
+ try
+ {
+ // Get the checksum of info.xml.
+ CmdChecksum cmd_checksum(shell_target, backup_config.target_sha256sum_bin,
+ target_snapshot_dir(backup_config, num) + "/info.xml");
+ it->target_meta_checksum = cmd_checksum.get_checksum();
+ }
+ catch (const Exception& e)
+ {
+ SN_CAUGHT(e);
+
+ // keep checksum empty
+ }
if (it->source_state == TheBigThing::SourceState::READ_ONLY &&
it->target_state == TheBigThing::TargetState::VALID &&
- it->source_meta_hash != it->target_meta_hash)
+ it->source_meta_checksum != it->target_meta_checksum)
{
it->target_state = TheBigThing::TargetState::LEGACY;
}
string source_parent_uuid;
string source_received_uuid;
string source_creation_time;
- string source_meta_hash;
+ string source_meta_checksum;
string target_uuid;
string target_parent_uuid;
string target_received_uuid;
string target_creation_time;
- string target_meta_hash;
+ string target_meta_checksum;
private: