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>
40#include <zypp/Pathname.h>
41#include <zypp/PathInfo.h>
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::string
1114 RpmlogCapture() :
_cap(this)
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 if (
_cap ) (*_cap) += rpmlogRecMessage( rec_r );
1142 bool requireGPGSig_r,
1143 RpmDb::CheckPackageDetail & detail_r )
1148 ERR <<
"Not a file: " << file << endl;
1152 FD_t fd = ::Fopen( file.
asString().c_str(),
"r.ufdio" );
1153 if ( fd == 0 || ::Ferror(fd) )
1155 ERR <<
"Can't open file for reading: " << file <<
" (" << ::Fstrerror(fd) <<
")" << endl;
1160 rpmts ts = ::rpmtsCreate();
1161 ::rpmtsSetRootDir( ts, root_r.
c_str() );
1162 ::rpmtsSetVSFlags( ts, RPMVSF_DEFAULT );
1164 rpmQVKArguments_s qva;
1165 memset( &qva, 0,
sizeof(rpmQVKArguments_s) );
1166#ifndef HAVE_RPM_VERIFY_TRANSACTION_STEP
1169 qva.qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE);
1171 ::rpmtsSetVfyFlags( ts, RPMVSF_DEFAULT );
1173 RpmlogCapture vresult;
1174 LocaleGuard guard( LC_ALL,
"C" );
1175 int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.
basename().c_str() );
1187 std::vector<std::string> lines;
1188 str::split( vresult, std::back_inserter(lines),
"\n" );
1189 unsigned count[7] = { 0, 0, 0, 0, 0, 0, 0 };
1191 for (
unsigned i = 1; i < lines.size(); ++i )
1193 std::string &line( lines[i] );
1196 if ( line.find(
": OK" ) != std::string::npos )
1199 if ( line.find(
"Signature, key ID" ) == std::string::npos )
1202 else if ( line.find(
": NOKEY" ) != std::string::npos )
1204 else if ( line.find(
": BAD" ) != std::string::npos )
1206 else if ( line.find(
": UNKNOWN" ) != std::string::npos )
1208 else if ( line.find(
": NOTRUSTED" ) != std::string::npos )
1210 else if ( line.find(
": NOTFOUND" ) != std::string::npos )
1214 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( lineres, std::move(line) ) );
1235 detail_r.push_back( RpmDb::CheckPackageDetail::value_type(
RpmDb::CHK_NOSIG, std::string(
" ")+
_(
"Package is not signed!") ) );
1236 if ( requireGPGSig_r )
1244 bool didReadHeader =
false;
1245 std::unordered_map< std::string, std::string> fprs;
1248 str::regex rxexpr(
"key ID ([a-fA-F0-9]{8}):" );
1249 for (
auto &detail : detail_r ) {
1250 auto &line = detail.second;
1254 if ( !didReadHeader ) {
1255 didReadHeader =
true;
1261 const auto &addFprs = [&](
auto tag ){
1262 const auto &list1 = keyMgr.readSignatureFingerprints( header->blob_val( tag ) );
1263 for (
const auto &
id : list1 ) {
1264 if (
id.size() <= 8 )
1268 fprs.insert( std::make_pair( lowerId.substr( lowerId.size() - 8 ), lowerId ) );
1272 addFprs( RPMTAG_SIGGPG );
1273 addFprs( RPMTAG_SIGPGP );
1274 addFprs( RPMTAG_RSAHEADER );
1275 addFprs( RPMTAG_DSAHEADER );
1278 ERR <<
"Failed to read package signatures." << std::endl;
1289 if (
const auto &i = fprs.find( keyId ); i != fprs.end() ) {
1296 WAR << path_r <<
" (" << requireGPGSig_r <<
" -> " << ret <<
")" << endl;
1300 DBG << path_r <<
" [0-Signature is OK]" << endl;
1311{
return doCheckPackageSig( path_r,
root(),
false, detail_r ); }
1317{
return doCheckPackageSig( path_r,
root(),
true, detail_r ); }
1332 opts.push_back (
"-V");
1333 opts.push_back (
"--nodeps");
1334 opts.push_back (
"--noscripts");
1335 opts.push_back (
"--nomd5");
1336 opts.push_back (
"--");
1337 opts.push_back (packageName.c_str());
1358 if (line.length() > 12 &&
1359 (line[0] ==
'S' || line[0] ==
's' ||
1360 (line[0] ==
'.' && line[7] ==
'T')))
1363 std::string filename;
1365 filename.assign(line, 11, line.length() - 11);
1405#if defined(WORKAROUNDRPMPWDBUG)
1406 args.push_back(
"#/");
1408 args.push_back(
"rpm");
1409 args.push_back(
"--root");
1411 args.push_back(
"--dbpath");
1414 args.push_back(
"-vv");
1415 const char* argv[args.size() + opts.size() + 1];
1417 const char** p = argv;
1418 p =
copy (args.begin (), args.end (), p);
1419 p =
copy (opts.begin (), opts.end (), p);
1449 const auto &readResult =
io::receiveUpto( inputfile,
'\n', 5 * 1000,
false );
1450 switch ( readResult.first ) {
1456 line += readResult.second;
1460 line += readResult.second;
1461 if ( line.size() && line.back() ==
'\n')
1466 line += readResult.second;
1468 if ( line.size() && line.back() ==
'\n')
1472 L_DBG(
"RPM_DEBUG") << line << endl;
1516void RpmDb::processConfigFiles(
const std::string& line,
const std::string& name,
const char* typemsg,
const char* difffailmsg,
const char* diffgenmsg)
1518 std::string msg = line.substr(9);
1521 std::string file1s, file2s;
1525 pos1 = msg.find (typemsg);
1528 if ( pos1 == std::string::npos )
1531 pos2 = pos1 + strlen (typemsg);
1533 if (pos2 >= msg.length() )
1536 file1 = msg.substr (0, pos1);
1537 file2 = msg.substr (pos2);
1544 file1 =
_root + file1;
1545 file2 =
_root + file2;
1555 ERR <<
"Could not create " << file.
asString() << endl;
1559 std::ofstream notify(file.
asString().c_str(), std::ios::out|std::ios::app);
1562 ERR <<
"Could not open " << file << endl;
1568 notify <<
str::form(
_(
"Changed configuration files for %s:"), name.c_str()) << endl;
1571 ERR <<
"diff failed" << endl;
1573 file1s.c_str(), file2s.c_str()) << endl;
1578 file1s.c_str(), file2s.c_str()) << endl;
1583 if (out.substr(0,4) ==
"--- ")
1585 out.replace(4, file1.
asString().length(), file1s);
1588 if (pos != std::string::npos)
1590 out.replace(pos+5, file2.
asString().length(), file2s);
1593 notify << out << endl;
1596 notify.open(
"/var/lib/update-messages/yast2-packagemanager.rpmdb.configfiles");
1601 WAR <<
"rpm created " << file2 <<
" but it is not different from " << file2 << endl;
1617 report->start(filename);
1632 report->finish( excpt_r );
1648 MIL <<
"RpmDb::installPackage(" << filename <<
"," << flags <<
")" << endl;
1656 ERR <<
"backup of " << filename.
asString() <<
" failed" << endl;
1659 report->progress( 0 );
1665 opts.push_back(
"-i");
1667 opts.push_back(
"-U");
1669 opts.push_back(
"--percent");
1670 opts.push_back(
"--noglob");
1674 opts.push_back(
"--ignorearch");
1677 opts.push_back(
"--nodigest");
1679 opts.push_back(
"--nosignature");
1681 opts.push_back (
"--excludedocs");
1683 opts.push_back (
"--noscripts");
1685 opts.push_back (
"--force");
1687 opts.push_back (
"--nodeps");
1689 opts.push_back (
"--ignoresize");
1691 opts.push_back (
"--justdb");
1693 opts.push_back (
"--test");
1695 opts.push_back (
"--noposttrans");
1697 opts.push_back(
"--");
1700 std::string quotedFilename( rpmQuoteFilename( workaroundRpmPwdBug( filename ) ) );
1701 opts.push_back ( quotedFilename.c_str() );
1706 unsigned lineno = 0;
1709 cmdout.
set(
"line", std::cref(line) );
1710 cmdout.
set(
"lineno", lineno );
1714 std::vector<std::string> configwarnings;
1721 sscanf( line.c_str() + 2,
"%d", &percent );
1722 report->progress( percent );
1726 cmdout.
set(
"lineno", lineno );
1727 report->report( cmdout );
1730 if ( line.find(
" scriptlet failed, " ) == std::string::npos )
1734 rpmmsg += line+
'\n';
1737 configwarnings.push_back(line);
1740 rpmmsg +=
"[truncated]\n";
1745 for (std::vector<std::string>::iterator it = configwarnings.begin();
1746 it != configwarnings.end(); ++it)
1750 _(
"rpm saved %s as %s, but it was impossible to determine the difference"),
1752 _(
"rpm saved %s as %s.\nHere are the first 25 lines of difference:\n"));
1755 _(
"rpm created %s as %s, but it was impossible to determine the difference"),
1757 _(
"rpm created %s as %s.\nHere are the first 25 lines of difference:\n"));
1760 if ( rpm_status != 0 )
1765 std::ostringstream sstr;
1766 sstr <<
"rpm output:" << endl << rpmmsg << endl;
1767 historylog.
comment(sstr.str());
1771 else if ( ! rpmmsg.empty() )
1776 std::ostringstream sstr;
1777 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
1778 historylog.
comment(sstr.str());
1782 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
1796 +
"-" + package->edition().version()
1797 +
"-" + package->edition().release()
1798 +
"." + package->arch().asString(), flags );
1811 report->start( name_r );
1826 report->finish( excpt_r );
1843 MIL <<
"RpmDb::doRemovePackage(" << name_r <<
"," << flags <<
")" << endl;
1852 ERR <<
"backup of " << name_r <<
" failed" << endl;
1854 report->progress( 0 );
1858 report->progress( 100 );
1863 opts.push_back(
"-e");
1864 opts.push_back(
"--allmatches");
1867 opts.push_back(
"--noscripts");
1869 opts.push_back(
"--nodeps");
1871 opts.push_back(
"--justdb");
1873 opts.push_back (
"--test");
1876 WAR <<
"IGNORE OPTION: 'rpm -e' does not support '--force'" << endl;
1879 opts.push_back(
"--");
1880 opts.push_back(name_r.c_str());
1885 unsigned lineno = 0;
1888 cmdout.
set(
"line", std::cref(line) );
1889 cmdout.
set(
"lineno", lineno );
1899 report->progress( 5 );
1903 cmdout.
set(
"lineno", lineno );
1904 report->report( cmdout );
1907 if ( line.find(
" scriptlet failed, " ) == std::string::npos )
1910 rpmmsg += line+
'\n';
1913 rpmmsg +=
"[truncated]\n";
1914 report->progress( 50 );
1917 if ( rpm_status != 0 )
1920 str::form(
"%s remove failed", name_r.c_str()),
true );
1921 std::ostringstream sstr;
1922 sstr <<
"rpm output:" << endl << rpmmsg << endl;
1923 historylog.
comment(sstr.str());
1927 else if ( ! rpmmsg.empty() )
1930 str::form(
"%s removed ok", name_r.c_str()),
true );
1932 std::ostringstream sstr;
1933 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
1934 historylog.
comment(sstr.str());
1938 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
1972 INT <<
"_backuppath empty" << endl;
1980 ERR <<
"Error while getting changed files for package " <<
1981 packageName << endl;
1987 DBG <<
"package " << packageName <<
" not changed -> no backup" << endl;
1999 struct tm *currentLocalTime = localtime(&
currentTime);
2001 int date = (currentLocalTime->tm_year + 1900) * 10000
2002 + (currentLocalTime->tm_mon + 1) * 100
2003 + currentLocalTime->tm_mday;
2009 +
str::form(
"%s-%d-%d.tar.gz",packageName.c_str(), date, num);
2012 while (
PathInfo(backupFilename).isExist() && num++ < 1000);
2017 ERR << filestobackupfile.
asString() <<
" already exists and is no file" << endl;
2021 std::ofstream fp ( filestobackupfile.
asString().c_str(), std::ios::out|std::ios::trunc );
2025 ERR <<
"could not open " << filestobackupfile.
asString() << endl;
2029 for (FileList::const_iterator cit =
fileList.begin();
2032 std::string name = *cit;
2033 if ( name[0] ==
'/' )
2036 name = name.substr( 1 );
2038 DBG <<
"saving file "<< name << endl;
2043 const char*
const argv[] =
2049 "--ignore-failed-read",
2053 filestobackupfile.
asString().c_str(),
2069 int ret = tar.
close();
2073 ERR <<
"tar failed: " << tarmsg << endl;
2078 MIL <<
"tar backup ok" << endl;
2099#define OUTS(E,S) case RpmDb::E: return str << "["<< (unsigned)obj << "-"<< S << "]"; break
2101 OUTS( CHK_OK,
_(
"Signature is OK") );
2103 OUTS( CHK_NOTFOUND,
_(
"Unknown type of signature") );
2105 OUTS( CHK_FAIL,
_(
"Signature does not verify") );
2107 OUTS( CHK_NOTTRUSTED,
_(
"Signature is OK, but key is not trusted") );
2109 OUTS( CHK_NOKEY,
_(
"Signatures public key is not available") );
2111 OUTS( CHK_ERROR,
_(
"File does not exist or signature can't be checked") );
2113 OUTS( CHK_NOSIG,
_(
"File is unsigned") );
2121 for (
const auto & el : obj )
2122 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 std::string & asString() const
Return current Pathname as String.
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 existant 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.
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", const Trim trim_r=NO_TRIM)
Split line_r into words.
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.