1
0
mirror of https://github.com/openSUSE/snapper.git synced 2026-02-06 00:45:39 +01:00
Files
snapper/client/misc.cc
2025-07-25 10:07:39 +02:00

221 lines
4.7 KiB
C++

/*
* Copyright (c) [2011-2014] Novell, Inc.
* Copyright (c) [2020-2023] 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 "config.h"
#include <iostream>
#include <sstream>
#include <boost/algorithm/string.hpp>
#include <snapper/AppUtil.h>
#include <snapper/SystemCmd.h>
#include <snapper/SnapperDefines.h>
#include <snapper/Filesystem.h>
#include "utils/text.h"
#include "misc.h"
namespace snapper
{
unsigned int
read_num(const string& str)
{
istringstream s(str);
unsigned int num = 0;
s >> num;
if (s.fail() || !s.eof())
{
cerr << sformat(_("Invalid snapshot '%s'."), str.c_str()) << endl;
exit(EXIT_FAILURE);
}
return num;
}
map<string, string>
read_userdata(const string& s, const map<string, string>& old)
{
if (s.empty())
{
cerr << _("Empty userdata.") << endl;
exit(EXIT_FAILURE);
}
list<string> tmp;
boost::split(tmp, s, boost::is_any_of(","), boost::token_compress_on);
if (tmp.empty())
{
cerr << _("Empty userdata.") << endl;
exit(EXIT_FAILURE);
}
map<string, string> userdata = old;
for (list<string>::const_iterator it = tmp.begin(); it != tmp.end(); ++it)
{
string::size_type pos = it->find("=");
if (pos == string::npos)
{
cerr << sformat(_("Userdata '%s' does not include '=' sign."), it->c_str()) << endl;
exit(EXIT_FAILURE);
}
string key = boost::trim_copy(it->substr(0, pos));
string value = boost::trim_copy(it->substr(pos + 1));
if (key.empty())
{
cerr << sformat(_("Userdata '%s' has empty key."), it->c_str()) << endl;
exit(EXIT_FAILURE);
}
if (value.empty())
userdata.erase(key);
else
userdata[key] = value;
}
return userdata;
}
string
show_userdata(const map<string, string>& userdata)
{
string s;
for (map<string, string>::const_iterator it = userdata.begin(); it != userdata.end(); ++it)
{
if (!s.empty())
s += ", ";
s += it->first + "=" + it->second;
}
return s;
}
map<string, string>
read_configdata(const vector<string>& v, const map<string, string>& old)
{
if (v.empty())
{
cerr << _("Empty configdata.") << endl;
exit(EXIT_FAILURE);
}
map<string, string> configdata = old;
for (vector<string>::const_iterator it = v.begin(); it != v.end(); ++it)
{
string::size_type pos = it->find("=");
if (pos == string::npos)
{
cerr << sformat(_("Configdata '%s' does not include '=' sign."), it->c_str()) << endl;
exit(EXIT_FAILURE);
}
string key = boost::trim_copy(it->substr(0, pos));
string value = boost::trim_copy(it->substr(pos + 1));
if (key.empty())
{
cerr << sformat(_("Configdata '%s' has empty key."), it->c_str()) << endl;
exit(EXIT_FAILURE);
}
configdata[key] = value;
}
return configdata;
}
string
username(uid_t uid)
{
string username;
gid_t gid;
if (!get_uid_username_gid(uid, username, gid))
return sformat("unknown (%d)", uid);
return username;
}
unique_ptr<const Filesystem>
get_filesystem(const ProxyConfig& config, const string& target_root)
{
const map<string, string>& raw = config.getAllValues();
map<string, string>::const_iterator pos1 = raw.find(KEY_FSTYPE);
map<string, string>::const_iterator pos2 = raw.find(KEY_SUBVOLUME);
if (pos1 == raw.end() || pos2 == raw.end())
{
cerr << _("Failed to initialize filesystem handler.") << endl;
exit(EXIT_FAILURE);
}
try
{
return Filesystem::create(pos1->second, pos2->second, target_root);
}
catch (const InvalidConfigException& e)
{
SN_CAUGHT(e);
cerr << _("Failed to initialize filesystem handler.") << endl;
exit(EXIT_FAILURE);
}
}
Differ::Differ()
: command(DIFF_BIN " --new-file --unified")
{
}
void
Differ::run(const string& f1, const string& f2) const
{
string tmp = command;
if (!extensions.empty())
tmp += " " + extensions;
tmp += " " + quote(f1) + " " + quote(f2);
SystemCmd cmd({ SH_BIN, "-c", tmp });
for (const string& line : cmd.get_stdout())
cout << line << endl;
for (const string& line : cmd.get_stderr())
cerr << line << endl;
}
}