15#include <rpm/rpmcli.h>
16#include <rpm/rpmlog.h>
32#include <zypp-core/base/StringV.h>
33#include <zypp/base/Logger.h>
34#include <zypp/base/String.h>
35#include <zypp/base/Gettext.h>
37#include <zypp-core/base/DtorReset>
40#include <zypp/Pathname.h>
41#include <zypp/PathInfo.h>
43#include <zypp-core/ui/ProgressData>
51#include <zypp/TmpPath.h>
56#include <zypp/base/IOTools.h>
61#define WARNINGMAILPATH "/var/log/YaST2/"
62#define FILEFORBACKUPFILES "YaSTBackupModifiedFiles"
63#define MAXRPMMESSAGELINES 10000
65#define WORKAROUNDRPMPWDBUG
67#undef ZYPP_BASE_LOGGER_LOGGROUP
68#define ZYPP_BASE_LOGGER_LOGGROUP "librpmDb"
72 namespace zypp_readonly_hack
80 static bool val = [](){
81 const char * env = getenv(
"ZYPP_RPM_DEBUG");
97const char* quoteInFilename_m =
"\'\"";
99const char* quoteInFilename_m =
" \t\'\"";
101inline std::string rpmQuoteFilename(
const Pathname & path_r )
103 std::string path( path_r.
asString() );
105 pos != std::string::npos;
106 pos = path.find_first_of( quoteInFilename_m, pos ) )
108 path.insert( pos,
"\\" );
121#if defined(WORKAROUNDRPMPWDBUG)
125 AutoDispose<char*> cwd( ::get_current_dir_name(), ::free );
128 WAR <<
"Can't get cwd!" << endl;
149 MIL <<
"trusted key added to zypp Keyring. Importing..." << endl;
155 MIL <<
"Trusted key removed from zypp Keyring. Removing..." << endl;
164unsigned diffFiles(
const std::string file1,
const std::string file2, std::string& out,
int maxlines)
185 if (maxlines<0?
true:count<maxlines)
211#define FAILIFNOTINITIALIZED if( ! initialized() ) { ZYPP_THROW(RpmDbNotOpenException()); }
222 : _backuppath (
"/var/adm/backup")
223 , _packagebackups(false)
230 setenv(
"RPM_IgnoreFailedSymlinks",
"1", 1 );
242 MIL <<
"~RpmDb()" << endl;
245 MIL <<
"~RpmDb() end" << endl;
271 bool quickinit( root_r.
empty() );
273 if ( root_r.
empty() )
281 if ( dbPath_r !=
"/var/lib/rpm" && !
PathInfo( root_r/
"/var/lib/rpm" ).isExist() )
283 WAR <<
"Inject missing /var/lib/rpm compat symlink to " << dbPath_r << endl;
297 if ( root_r ==
_root ) {
305 MIL <<
"Calling initDatabase: " <<
stringPath( root_r, dbPath_r )
306 << ( doRebuild_r ?
" (rebuilddb)" :
"" )
307 << ( quickinit ?
" (quickinit)" :
"" ) << endl;
316 MIL <<
"QUICK initDatabase (no systemRoot set)" << endl;
338 MIL <<
"Synchronizing keys with zypp keyring" << endl;
347 MIL <<
"InitDatabase: " << *
this << endl;
363 MIL <<
"Calling closeDatabase: " << *
this << endl;
375 MIL <<
"closeDatabase: " << *
this << endl;
405 MIL <<
"RpmDb::rebuildDatabase" << *
this << endl;
419 opts.push_back(
"--rebuilddb");
420 opts.push_back(
"-vv");
430 tics.
range( hdrTotal );
433 return report->progress( tics_r.
reportValue(), mydbpath );
441 static const std::string debugPrefix {
"D:" };
442 static const std::string progressPrefix {
"D: read h#" };
443 static const std::string ignoreSuffix {
"digest: OK" };
458 WAR <<
"User requested abort." << endl;
482 void computeKeyRingSync( std::set<Edition> & rpmKeys_r, std::list<PublicKeyData> & zyppKeys_r )
493 void updateIf(
const Edition & rpmKey_r )
495 std::string keyRelease( rpmKey_r.
release() );
496 int comp = _release.compare( keyRelease );
500 _release.swap( keyRelease );
501 _inRpmKeys = &rpmKey_r;
502 _inZyppKeys =
nullptr;
503 if ( !keyRelease.empty() )
504 DBG <<
"Old key in Z: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
506 else if ( comp == 0 )
510 _inRpmKeys = &rpmKey_r;
514 DBG <<
"Old key in R: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
517 void updateIf(
const PublicKeyData & zyppKey_r )
519 std::string keyRelease( zyppKey_r.gpgPubkeyRelease() );
520 int comp = _release.compare( keyRelease );
524 _release.swap( keyRelease );
525 _inRpmKeys =
nullptr;
526 _inZyppKeys = &zyppKey_r;
527 if ( !keyRelease.empty() )
528 DBG <<
"Old key in R: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() <<
"-" << keyRelease << endl;
530 else if ( comp == 0 )
534 _inZyppKeys = &zyppKey_r;
538 DBG <<
"Old key in Z: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() <<
"-" << keyRelease << endl;
541 std::string _release;
542 const Edition * _inRpmKeys;
543 const PublicKeyData * _inZyppKeys;
548 std::map<std::string,Key> _keymap;
550 for_( it, rpmKeys_r.begin(), rpmKeys_r.end() )
552 _keymap[(*it).version()].updateIf( *it );
555 for_( it, zyppKeys_r.begin(), zyppKeys_r.end() )
557 _keymap[(*it).gpgPubkeyVersion()].updateIf( *it );
561 std::set<Edition> rpmKeys;
562 std::list<PublicKeyData> zyppKeys;
563 for_( it, _keymap.begin(), _keymap.end() )
565 DBG <<
"gpg-pubkey-" << (*it).first <<
"-" << (*it).second._release <<
" "
566 << ( (*it).second._inRpmKeys ?
"R" :
"_" )
567 << ( (*it).second._inZyppKeys ?
"Z" :
"_" ) << endl;
568 if ( ! (*it).second._inRpmKeys )
570 zyppKeys.push_back( *(*it).second._inZyppKeys );
572 if ( ! (*it).second._inZyppKeys )
574 rpmKeys.insert( *(*it).second._inRpmKeys );
577 rpmKeys_r.swap( rpmKeys );
578 zyppKeys_r.swap( zyppKeys );
585 MIL <<
"Going to sync trusted keys..." << endl;
587 std::list<PublicKeyData> zyppKeys( getZYpp()->keyRing()->trustedPublicKeyData() );
599 MIL <<
"Removing excess keys in zypp trusted keyring" << std::endl;
605 if ( ! rpmKeys.count( keyData.gpgPubkeyEdition() ) )
607 DBG <<
"Excess key in Z to delete: gpg-pubkey-" << keyData.gpgPubkeyEdition() << endl;
608 getZYpp()->keyRing()->deleteKey( keyData.id(),
true );
609 if ( !dirty ) dirty =
true;
613 zyppKeys = getZYpp()->keyRing()->trustedPublicKeyData();
616 computeKeyRingSync( rpmKeys, zyppKeys );
617 MIL << (mode_r &
SYNC_TO_KEYRING ?
"" :
"(skip) ") <<
"Rpm keys to export into zypp trusted keyring: " << rpmKeys.size() << endl;
618 MIL << (mode_r &
SYNC_FROM_KEYRING ?
"" :
"(skip) ") <<
"Zypp trusted keys to import into rpm database: " << zyppKeys.size() << endl;
624 MIL <<
"Exporting rpm keyring into zypp trusted keyring" <<endl;
629 TmpFile tmpfile( getZYpp()->tmpPath() );
631 std::ofstream tmpos( tmpfile.
path().
c_str() );
632 for_( it, rpmKeys.begin(), rpmKeys.end() )
636 getData(
"gpg-pubkey", *it, result );
637 tmpos << result->tag_description() << endl;
642 getZYpp()->keyRing()->multiKeyImport( tmpfile.
path(),
true );
646 std::set<Edition> missingKeys;
647 for (
const Edition & key : rpmKeys )
649 if ( getZYpp()->keyRing()->isKeyTrusted( key.version() ) )
651 ERR <<
"Could not import key:" <<
str::Format(
"gpg-pubkey-%s") % key <<
" into zypp keyring (V3 key?)" << endl;
652 missingKeys.insert( key );
654 if ( ! missingKeys.empty() )
660 ERR <<
"Could not import keys into zypp keyring: " << endl;
668 MIL <<
"Importing zypp trusted keyring" << std::endl;
669 for_( it, zyppKeys.begin(), zyppKeys.end() )
673 importPubkey( getZYpp()->keyRing()->exportTrustedPublicKey( *it ) );
681 MIL <<
"Trusted keys synced." << endl;
703 WAR <<
"Key " << pubkey_r <<
" can not be imported. (READONLY MODE)" << endl;
710 bool hasOldkeys =
false;
712 for_( it, rpmKeys.begin(), rpmKeys.end() )
721 MIL <<
"Key " << pubkey_r <<
" is already in the rpm trusted keyring. (skip import)" << endl;
725 if ( keyEd.
version() != (*it).version() )
728 if ( keyEd.
release() < (*it).release() )
730 MIL <<
"Key " << pubkey_r <<
" is older than one in the rpm trusted keyring. (skip import)" << endl;
738 MIL <<
"Key " << pubkey_r <<
" will be imported into the rpm trusted keyring." << (hasOldkeys?
"(update)":
"(new)") << endl;
744 std::string keyName(
"gpg-pubkey-" + keyEd.
version() );
746 opts.push_back (
"-e" );
747 opts.push_back (
"--allmatches" );
748 opts.push_back (
"--" );
749 opts.push_back ( keyName.c_str() );
760 ERR <<
"Failed to remove key " << pubkey_r <<
" from RPM trusted keyring (ignored)" << endl;
764 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
770 opts.push_back (
"--import" );
771 opts.push_back (
"--" );
773 opts.push_back ( pubkeypath.c_str() );
777 std::vector<std::string> excplines;
783 excplines.push_back( std::move(line) );
799 MIL <<
"Key " << pubkey_r <<
" imported in rpm trusted keyring." << endl;
816 std::set<Edition>::const_iterator found_edition = rpm_keys.end();
819 for_( it, rpm_keys.begin(), rpm_keys.end() )
821 if ( (*it).version() == pubkeyVersion )
829 if (found_edition == rpm_keys.end())
831 WAR <<
"Key " << pubkey_r.
id() <<
" is not in rpm db" << endl;
835 std::string rpm_name(
"gpg-pubkey-" + found_edition->asString());
838 opts.push_back (
"-e" );
839 opts.push_back (
"--" );
840 opts.push_back ( rpm_name.c_str() );
844 std::vector<std::string> excplines;
850 excplines.push_back( std::move(line) );
866 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
878 std::list<PublicKey> ret;
881 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
883 Edition edition = it->tag_edition();
888 getData(
"gpg-pubkey", edition, result );
889 TmpFile file(getZYpp()->tmpPath());
895 os << result->tag_description();
904 catch ( std::exception & e )
906 ERR <<
"Could not dump key " << edition.
asString() <<
" in tmp file " << file.
path() << endl;
916 std::set<Edition> ret;
919 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
921 Edition edition = it->tag_edition();
923 ret.insert( edition );
940 std::list<FileInfo> result;
967bool RpmDb::hasFile(
const std::string & file_r,
const std::string & name_r )
const
977 res = (it->tag_name() == name_r);
998 return it->tag_name();
1112 struct RpmlogCapture :
public std::vector<std::string>
1116 rpmlogSetCallback( rpmLogCB,
this );
1117 _oldMask = rpmlogSetMask( RPMLOG_UPTO( RPMLOG_PRI(RPMLOG_INFO) ) );
1122 rpmlogSetCallback(
nullptr,
nullptr );
1126 static int rpmLogCB( rpmlogRec rec_r, rpmlogCallbackData data_r )
1127 {
return reinterpret_cast<RpmlogCapture*
>(data_r)->rpmLog( rec_r ); }
1129 int rpmLog( rpmlogRec rec_r )
1131 std::string l { ::rpmlogRecMessage( rec_r ) };
1133 push_back( std::move(l) );
1141 std::ostream &
operator<<( std::ostream &
str,
const RpmlogCapture & obj )
1144 for (
const auto & l : obj ) {
1145 if ( sep )
str << sep;
else sep =
'\n';
1154 bool requireGPGSig_r,
1155 RpmDb::CheckPackageDetail & detail_r )
1158 if ( ! file.isFile() )
1160 ERR <<
"Not a file: " << file << endl;
1164 FD_t fd = ::Fopen( file.asString().c_str(),
"r.ufdio" );
1165 if ( fd == 0 || ::Ferror(fd) )
1167 ERR <<
"Can't open file for reading: " << file <<
" (" << ::Fstrerror(fd) <<
")" << endl;
1172 rpmts ts = ::rpmtsCreate();
1173 ::rpmtsSetRootDir( ts, root_r.
c_str() );
1174 ::rpmtsSetVSFlags( ts, RPMVSF_DEFAULT );
1175#ifdef HAVE_RPM_VERIFY_TRANSACTION_STEP
1176 ::rpmtsSetVfyFlags( ts, RPMVSF_DEFAULT );
1179 RpmlogCapture vresult;
1180 LocaleGuard guard( LC_ALL,
"C" );
1181 static rpmQVKArguments_s qva = ([](){ rpmQVKArguments_s qva; memset( &qva, 0,
sizeof(rpmQVKArguments_s) );
return qva; })();
1182 int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.
basename().c_str() );
1191 typedef std::map<std::string_view,RpmDb::CheckPackageResult> ResultMap;
1192 static const ResultMap resultMap {
1200 auto getresult = [](
const ResultMap & resultMap, ResultMap::key_type key )->ResultMap::mapped_type {
1201 auto it = resultMap.find( key );
1206 unsigned count[7] = { 0, 0, 0, 0, 0, 0, 0 };
1211 SawHeaderSig = (1 << 0),
1212 SawHeaderDigest = (1 << 1),
1213 SawPayloadDigest = (1 << 2),
1215 SawDigest = (1 << 4),
1217 unsigned saw = SawNone;
1219 static const str::regex rx(
"^ *(Header|Payload)? .*(Signature, key|digest).*: ([A-Z]+)" );
1221 for (
const std::string & line : vresult )
1223 if ( line[0] !=
' ' )
1229 lineres = getresult( resultMap, what[3] );
1233 if ( what[1][0] ==
'H' ) {
1234 saw |= ( what[2][0] ==
'S' ? SawHeaderSig :SawHeaderDigest );
1236 else if ( what[1][0] ==
'P' ) {
1237 if ( what[2][0] ==
'd' ) saw |= SawPayloadDigest;
1240 saw |= ( what[2][0] ==
'S' ? SawSig : SawDigest );
1245 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( lineres, std::move(line) ) );
1267 bool isSigned = (saw & SawHeaderSig) && ( (saw & SawPayloadDigest) || (saw & SawSig) );
1268 if ( not isSigned ) {
1269 std::string message {
" " };
1270 if ( not (saw & SawHeaderSig) )
1271 message +=
_(
"Package header is not signed!");
1273 message +=
_(
"Package payload is not signed!");
1275 detail_r.push_back( RpmDb::CheckPackageDetail::value_type(
RpmDb::CHK_NOSIG, std::move(message) ) );
1276 if ( requireGPGSig_r )
1285 bool didReadHeader =
false;
1286 std::unordered_map< std::string, std::string> fprs;
1289 str::regex rxexpr(
"key ID ([a-fA-F0-9]{8}):" );
1290 for (
auto &detail : detail_r ) {
1291 auto &line = detail.second;
1295 if ( !didReadHeader ) {
1296 didReadHeader =
true;
1302 const auto &addFprs = [&](
auto tag ){
1303 const auto &list1 = keyMgr.readSignatureFingerprints( header->blob_val( tag ) );
1304 for (
const auto &
id : list1 ) {
1305 if (
id.size() <= 8 )
1309 fprs.insert( std::make_pair( lowerId.substr( lowerId.size() - 8 ), lowerId ) );
1313 addFprs( RPMTAG_SIGGPG );
1314 addFprs( RPMTAG_SIGPGP );
1315 addFprs( RPMTAG_RSAHEADER );
1316 addFprs( RPMTAG_DSAHEADER );
1319 ERR <<
"Failed to read package signatures." << std::endl;
1330 if (
const auto &i = fprs.find( keyId ); i != fprs.end() ) {
1337 WAR << path_r <<
" (" << requireGPGSig_r <<
" -> " << ret <<
")" << endl;
1338 WAR << vresult << endl;
1341 DBG << path_r <<
" [0-Signature is OK]" << endl;
1352{
return doCheckPackageSig( path_r,
root(),
false, detail_r ); }
1358{
return doCheckPackageSig( path_r,
root(),
true, detail_r ); }
1373 opts.push_back (
"-V");
1374 opts.push_back (
"--nodeps");
1375 opts.push_back (
"--noscripts");
1376 opts.push_back (
"--nomd5");
1377 opts.push_back (
"--");
1378 opts.push_back (packageName.c_str());
1399 if (line.length() > 12 &&
1400 (line[0] ==
'S' || line[0] ==
's' ||
1401 (line[0] ==
'.' && line[7] ==
'T')))
1404 std::string filename;
1406 filename.assign(line, 11, line.length() - 11);
1446#if defined(WORKAROUNDRPMPWDBUG)
1447 args.push_back(
"#/");
1449 args.push_back(
"rpm");
1450 args.push_back(
"--root");
1452 args.push_back(
"--dbpath");
1455 args.push_back(
"-vv");
1456 const char* argv[args.size() + opts.size() + 1];
1458 const char** p = argv;
1459 p =
copy (args.begin (), args.end (), p);
1460 p =
copy (opts.begin (), opts.end (), p);
1490 const auto &readResult =
io::receiveUpto( inputfile,
'\n', 5 * 1000,
false );
1491 switch ( readResult.first ) {
1497 line += readResult.second;
1502 line += readResult.second;
1503 if ( line.size() && line.back() ==
'\n')
1508 line += readResult.second;
1510 if ( line.size() && line.back() ==
'\n')
1514 L_DBG(
"RPM_DEBUG") << line << endl;
1558void RpmDb::processConfigFiles(
const std::string& line,
const std::string& name,
const char* typemsg,
const char* difffailmsg,
const char* diffgenmsg)
1560 std::string msg = line.substr(9);
1563 std::string file1s, file2s;
1567 pos1 = msg.find (typemsg);
1570 if ( pos1 == std::string::npos )
1573 pos2 = pos1 + strlen (typemsg);
1575 if (pos2 >= msg.length() )
1578 file1 = msg.substr (0, pos1);
1579 file2 = msg.substr (pos2);
1586 file1 =
_root + file1;
1587 file2 =
_root + file2;
1597 ERR <<
"Could not create " << file.
asString() << endl;
1601 std::ofstream notify(file.
asString().c_str(), std::ios::out|std::ios::app);
1604 ERR <<
"Could not open " << file << endl;
1610 notify <<
str::form(
_(
"Changed configuration files for %s:"), name.c_str()) << endl;
1613 ERR <<
"diff failed" << endl;
1615 file1s.c_str(), file2s.c_str()) << endl;
1620 file1s.c_str(), file2s.c_str()) << endl;
1625 if (out.substr(0,4) ==
"--- ")
1627 out.replace(4, file1.
asString().length(), file1s);
1630 if (pos != std::string::npos)
1632 out.replace(pos+5, file2.
asString().length(), file2s);
1635 notify << out << endl;
1638 notify.open(
"/var/lib/update-messages/yast2-packagemanager.rpmdb.configfiles");
1643 WAR <<
"rpm created " << file2 <<
" but it is not different from " << file2 << endl;
1659 report->start(filename);
1674 report->finish( excpt_r );
1690 MIL <<
"RpmDb::installPackage(" << filename <<
"," << flags <<
")" << endl;
1698 ERR <<
"backup of " << filename.
asString() <<
" failed" << endl;
1701 report->progress( 0 );
1707 opts.push_back(
"-i");
1709 opts.push_back(
"-U");
1711 opts.push_back(
"--percent");
1712 opts.push_back(
"--noglob");
1716 opts.push_back(
"--ignorearch");
1719 opts.push_back(
"--nodigest");
1721 opts.push_back(
"--nosignature");
1723 opts.push_back (
"--excludedocs");
1725 opts.push_back (
"--noscripts");
1727 opts.push_back (
"--force");
1729 opts.push_back (
"--nodeps");
1731 opts.push_back (
"--ignoresize");
1733 opts.push_back (
"--justdb");
1735 opts.push_back (
"--test");
1737 opts.push_back (
"--noposttrans");
1739 opts.push_back(
"--");
1742 std::string quotedFilename( rpmQuoteFilename( workaroundRpmPwdBug( filename ) ) );
1743 opts.push_back ( quotedFilename.c_str() );
1748 unsigned lineno = 0;
1751 cmdout.
set(
"line", std::cref(line) );
1752 cmdout.
set(
"lineno", lineno );
1756 std::vector<std::string> configwarnings;
1763 sscanf( line.c_str() + 2,
"%d", &percent );
1764 report->progress( percent );
1768 cmdout.
set(
"lineno", lineno );
1769 report->report( cmdout );
1772 if ( line.find(
" scriptlet failed, " ) == std::string::npos )
1776 rpmmsg += line+
'\n';
1779 configwarnings.push_back(line);
1782 rpmmsg +=
"[truncated]\n";
1787 for (std::vector<std::string>::iterator it = configwarnings.begin();
1788 it != configwarnings.end(); ++it)
1792 _(
"rpm saved %s as %s, but it was impossible to determine the difference"),
1794 _(
"rpm saved %s as %s.\nHere are the first 25 lines of difference:\n"));
1797 _(
"rpm created %s as %s, but it was impossible to determine the difference"),
1799 _(
"rpm created %s as %s.\nHere are the first 25 lines of difference:\n"));
1802 if ( rpm_status != 0 )
1807 std::ostringstream sstr;
1808 sstr <<
"rpm output:" << endl << rpmmsg << endl;
1809 historylog.
comment(sstr.str());
1812 if ( not rpmmsg.empty() )
1816 else if ( ! rpmmsg.empty() )
1821 std::ostringstream sstr;
1822 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
1823 historylog.
comment(sstr.str());
1827 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
1841 +
"-" + package->edition().version()
1842 +
"-" + package->edition().release()
1843 +
"." + package->arch().asString(), flags );
1856 report->start( name_r );
1871 report->finish( excpt_r );
1888 MIL <<
"RpmDb::doRemovePackage(" << name_r <<
"," << flags <<
")" << endl;
1897 ERR <<
"backup of " << name_r <<
" failed" << endl;
1899 report->progress( 0 );
1903 report->progress( 100 );
1908 opts.push_back(
"-e");
1909 opts.push_back(
"--allmatches");
1912 opts.push_back(
"--noscripts");
1914 opts.push_back(
"--nodeps");
1916 opts.push_back(
"--justdb");
1918 opts.push_back (
"--test");
1921 WAR <<
"IGNORE OPTION: 'rpm -e' does not support '--force'" << endl;
1924 opts.push_back(
"--");
1925 opts.push_back(name_r.c_str());
1930 unsigned lineno = 0;
1933 cmdout.
set(
"line", std::cref(line) );
1934 cmdout.
set(
"lineno", lineno );
1944 report->progress( 5 );
1948 cmdout.
set(
"lineno", lineno );
1949 report->report( cmdout );
1952 if ( line.find(
" scriptlet failed, " ) == std::string::npos )
1955 rpmmsg += line+
'\n';
1958 rpmmsg +=
"[truncated]\n";
1959 report->progress( 50 );
1962 if ( rpm_status != 0 )
1965 str::form(
"%s remove failed", name_r.c_str()),
true );
1966 std::ostringstream sstr;
1967 sstr <<
"rpm output:" << endl << rpmmsg << endl;
1968 historylog.
comment(sstr.str());
1971 if ( not rpmmsg.empty() )
1975 else if ( ! rpmmsg.empty() )
1978 str::form(
"%s removed ok", name_r.c_str()),
true );
1980 std::ostringstream sstr;
1981 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
1982 historylog.
comment(sstr.str());
1986 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2020 INT <<
"_backuppath empty" << endl;
2028 ERR <<
"Error while getting changed files for package " <<
2029 packageName << endl;
2035 DBG <<
"package " << packageName <<
" not changed -> no backup" << endl;
2047 struct tm *currentLocalTime = localtime(&
currentTime);
2049 int date = (currentLocalTime->tm_year + 1900) * 10000
2050 + (currentLocalTime->tm_mon + 1) * 100
2051 + currentLocalTime->tm_mday;
2057 +
str::form(
"%s-%d-%d.tar.gz",packageName.c_str(), date, num);
2060 while (
PathInfo(backupFilename).isExist() && num++ < 1000);
2065 ERR << filestobackupfile.
asString() <<
" already exists and is no file" << endl;
2069 std::ofstream fp ( filestobackupfile.
asString().c_str(), std::ios::out|std::ios::trunc );
2073 ERR <<
"could not open " << filestobackupfile.
asString() << endl;
2077 for (FileList::const_iterator cit =
fileList.begin();
2080 std::string name = *cit;
2081 if ( name[0] ==
'/' )
2084 name = name.substr( 1 );
2086 DBG <<
"saving file "<< name << endl;
2091 const char*
const argv[] =
2097 "--ignore-failed-read",
2101 filestobackupfile.
asString().c_str(),
2117 int ret = tar.
close();
2121 ERR <<
"tar failed: " << tarmsg << endl;
2126 MIL <<
"tar backup ok" << endl;
2147#define OUTS(E,S) case RpmDb::E: return str << "["<< (unsigned)obj << "-"<< S << "]"; break
2149 OUTS( CHK_OK,
_(
"Signature is OK") );
2151 OUTS( CHK_NOTFOUND,
_(
"Unknown type of signature") );
2153 OUTS( CHK_FAIL,
_(
"Signature does not verify") );
2155 OUTS( CHK_NOTTRUSTED,
_(
"Signature is OK, but key is not trusted") );
2157 OUTS( CHK_NOKEY,
_(
"Signatures public key is not available") );
2159 OUTS( CHK_ERROR,
_(
"File does not exist or signature can't be checked") );
2161 OUTS( CHK_NOSIG,
_(
"File is unsigned") );
2169 for (
const auto & el : obj )
2170 str << el.second << endl;
#define MAXRPMMESSAGELINES
#define FAILIFNOTINITIALIZED
#define FILEFORBACKUPFILES
Store and operate on date (time_t).
std::string form(const std::string &format_r) const
Return string representation according to format as localtime.
static Date now()
Return the current time.
Assign a vaiable a certain value when going out of scope.
Edition represents [epoch:]version[-release]
std::string version() const
Version.
std::string release() const
Release.
static const Edition noedition
Value representing noedition ("") This is in fact a valid Edition.
Base class for Exception.
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
void addHistory(const std::string &msg_r)
Add some message text to the history.
void moveToHistory(TContainer &&msgc_r)
addHistory from string container types (oldest first) moving
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
bool kill()
Kill the program.
const std::string & execError() const
Some detail telling why the execution failed, if it failed.
bool running()
Return whether program is running.
int close()
Wait for the progamm to complete.
Stderr_Disposition
Define symbols for different policies on the handling of stderr.
Writing the zypp history file.
void comment(const std::string &comment, bool timestamp=false)
Log a comment (even multiline).
std::string asString() const
static KeyManagerCtx createForOpenPGP()
Creates a new KeyManagerCtx for PGP using a volatile temp.
TraitsType::constPtrType constPtr
Maintain [min,max] and counter (value) for progress counting.
value_type reportValue() const
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
bool toMax()
Set counter value to current max value (unless no range).
bool incr(value_type val_r=1)
Increment counter value (default by 1).
bool toMin()
Set counter value to current min value.
void range(value_type max_r)
Set new [0,max].
Class representing one GPG Public Keys data.
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
Pathname path() const
File containing the ASCII armored key.
std::string gpgPubkeyRelease() const
std::string asString() const
std::string gpgPubkeyVersion() const
bool hasSubkeys() const
!<
static ZConfig & instance()
Singleton ctor.
Typesafe passing of user data via callbacks.
bool set(const std::string &key_r, AnyType val_r)
Set the value for key (nonconst version always returns true).
zypp::ContentType ContentType
void setBlocking(bool mode)
Set the blocking mode of the input stream.
FILE * inputFile() const
Return the input stream.
std::string receiveLine()
Read one line from the input stream.
Wrapper class for ::stat/::lstat.
bool isExist() const
Return whether valid stat info exists.
const char * c_str() const
String representation.
const std::string & asString() const
String representation.
std::string basename() const
Return the last component of this path.
bool empty() const
Test for an empty path.
bool relative() const
Test for a relative path.
Provide a new empty temporary file and delete it when no longer needed.
Interface to the rpm program.
void getData(const std::string &name_r, RpmHeader::constPtr &result_r) const
Get an installed packages data from rpmdb.
void doRebuildDatabase(callback::SendReport< RebuildDBReport > &report)
bool queryChangedFiles(FileList &fileList, const std::string &packageName)
determine which files of an installed package have been modified.
std::string error_message
Error message from running rpm as external program.
bool hasRequiredBy(const std::string &tag_r) const
Return true if at least one package requires a certain tag.
virtual std::ostream & dumpOn(std::ostream &str) const
Dump debug info.
std::string whoOwnsFile(const std::string &file_r) const
Return name of package owning file or empty string if no installed package owns file.
void exportTrustedKeysInZyppKeyRing()
insert all rpm trusted keys into zypp trusted keyring
void importPubkey(const PublicKey &pubkey_r)
Import ascii armored public key in file pubkey_r.
void installPackage(const Pathname &filename, RpmInstFlags flags=RPMINST_NONE)
install rpm package
Pathname _backuppath
/var/adm/backup
void run_rpm(const RpmArgVec &options, ExternalProgram::Stderr_Disposition stderr_disp=ExternalProgram::Stderr_To_Stdout)
Run rpm with the specified arguments and handle stderr.
void initDatabase(Pathname root_r=Pathname(), bool doRebuild_r=false)
Prepare access to the rpm database below root_r.
ExternalProgram * process
The connection to the rpm process.
SyncTrustedKeyBits
Sync mode for syncTrustedKeys.
@ SYNC_TO_KEYRING
export rpm trusted keys into zypp trusted keyring
@ SYNC_FROM_KEYRING
import zypp trusted keys into rpm database.
std::list< PublicKey > pubkeys() const
Return the long ids of all installed public keys.
std::set< Edition > pubkeyEditions() const
Return the edition of all installed public keys.
int systemStatus()
Return the exit status of the general rpm process, closing the connection if not already done.
CheckPackageResult checkPackageSignature(const Pathname &path_r, CheckPackageDetail &detail_r)
Check signature of rpm file on disk (strict check returning CHK_NOSIG if file is unsigned).
bool backupPackage(const std::string &packageName)
create tar.gz of all changed files in a Package
bool hasProvides(const std::string &tag_r) const
Return true if at least one package provides a certain tag.
void systemKill()
Forcably kill the system process.
const Pathname & root() const
void removePubkey(const PublicKey &pubkey_r)
Remove a public key from the rpm database.
void removePackage(const std::string &name_r, RpmInstFlags flags=RPMINST_NONE)
remove rpm package
void doInstallPackage(const Pathname &filename, RpmInstFlags flags, callback::SendReport< RpmInstallReport > &report)
std::list< FileInfo > fileList(const std::string &name_r, const Edition &edition_r) const
return complete file list for installed package name_r (in FileInfo.filename) if edition_r !...
const Pathname & dbPath() const
Pathname _dbPath
Directory that contains the rpmdb.
void closeDatabase()
Block further access to the rpm database and go back to uninitialized state.
void setBackupPath(const Pathname &path)
set path where package backups are stored
void doRemovePackage(const std::string &name_r, RpmInstFlags flags, callback::SendReport< RpmRemoveReport > &report)
bool _packagebackups
create package backups?
CheckPackageResult checkPackage(const Pathname &path_r, CheckPackageDetail &detail_r)
Check signature of rpm file on disk (legacy version returning CHK_OK if file is unsigned,...
void importZyppKeyRingTrustedKeys()
iterates through zypp keyring and import all non-existent keys into rpm keyring
Pathname _root
Root directory for all operations.
bool hasConflicts(const std::string &tag_r) const
Return true if at least one package conflicts with a certain tag.
std::vector< const char * > RpmArgVec
int exit_code
The exit code of the rpm process, or -1 if not yet known.
void syncTrustedKeys(SyncTrustedKeyBits mode_r=SYNC_BOTH)
Sync trusted keys stored in rpm database and zypp trusted keyring.
void processConfigFiles(const std::string &line, const std::string &name, const char *typemsg, const char *difffailmsg, const char *diffgenmsg)
handle rpm messages like "/etc/testrc saved as /etc/testrc.rpmorig"
CheckPackageResult
checkPackage result
bool hasPackage(const std::string &name_r) const
Return true if package is installed.
std::set< std::string > FileList
bool systemReadLine(std::string &line)
Read a line from the general rpm query.
void rebuildDatabase()
Rebuild the rpm database (rpm –rebuilddb).
bool hasFile(const std::string &file_r, const std::string &name_r="") const
Return true if at least one package owns a certain file (name_r empty) Return true if package name_r ...
Just inherits Exception to separate media exceptions.
Subclass to retrieve database content.
bool findByProvides(const std::string &tag_r)
Reset to iterate all packages that provide a certain tag.
bool findByName(const std::string &name_r)
Reset to iterate all packages with a certain name.
bool findByFile(const std::string &file_r)
Reset to iterate all packages that own a certain file.
bool findByRequiredBy(const std::string &tag_r)
Reset to iterate all packages that require a certain tag.
bool findPackage(const std::string &name_r)
Find package by name.
shared_ptr< RpmException > dbError() const
Return any database error.
bool findByConflicts(const std::string &tag_r)
Reset to iterate all packages that conflict with a certain tag.
static bool globalInit()
Initialize lib librpm (read configfiles etc.).
static std::string stringPath(const Pathname &root_r, const Pathname &sub_r)
static unsigned dbRelease(bool force_r=false)
If there are no outstanding references to the database (e.g.
static void dbAccess()
Access the database at the current default location.
static unsigned blockAccess()
Blocks further access to rpmdb.
static Pathname suggestedDbPath(const Pathname &root_r)
static void unblockAccess()
Allow access to rpmdb e.g.
String related utilities and Regular expression matching.
Types and functions for filesystem operations.
Pathname expandlink(const Pathname &path_r)
Recursively follows the symlink pointed to by path_r and returns the Pathname to the real file or dir...
int unlink(const Pathname &path)
Like 'unlink'.
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
int symlink(const Pathname &oldpath, const Pathname &newpath)
Like 'symlink'.
std::pair< ReceiveUpToResult, std::string > receiveUpto(FILE *file, char c, timeout_type timeout, bool failOnUnblockError)
std::ostream & copy(std::istream &from_r, std::ostream &to_r)
Copy istream to ostream.
std::string & replaceAll(std::string &str_r, const std::string &from_r, const std::string &to_r)
Replace all occurrences of from_r with to_r in str_r (inplace).
std::string numstring(char n, int w=0)
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
bool endsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasSuffix
bool regex_match(const std::string &s, smatch &matches, const regex ®ex)
\relates regex \ingroup ZYPP_STR_REGEX \relates regex \ingroup ZYPP_STR_REGEX
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
std::string toLower(const std::string &s)
Return lowercase version of s.
std::ostream & operator<<(std::ostream &str, const librpmDb::db_const_iterator &obj)
static shared_ptr< KeyRingSignalReceiver > sKeyRingReceiver
std::string stringPath(const Pathname &root_r, const Pathname &sub_r)
unsigned diffFiles(const std::string file1, const std::string file2, std::string &out, int maxlines)
Easy-to use interface to the ZYPP dependency resolver.
Temporarily connect a ReceiveReport then restore the previous one.
static const UserData::ContentType contentRpmout
"rpmout/installpkg": Additional rpm output (sent immediately).
virtual void trustedKeyRemoved(const PublicKey &key)
virtual void trustedKeyAdded(const PublicKey &key)
KeyRingSignalReceiver(RpmDb &rpmdb)
static const UserData::ContentType contentRpmout
"rpmout/removepkg": Additional rpm output (sent immediately).
Detailed rpm signature check log messages A single multiline message if CHK_OK.
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.