Go to the documentation of this file.
15 #include <rpm/rpmcli.h>
16 #include <rpm/rpmlog.h>
56 #define WARNINGMAILPATH "/var/log/YaST2/"
57 #define FILEFORBACKUPFILES "YaSTBackupModifiedFiles"
58 #define MAXRPMMESSAGELINES 10000
60 #define WORKAROUNDRPMPWDBUG
64 namespace zypp_readonly_hack
74 #if 1 // No more need to escape whitespace since rpm-4.4.2.3
75 const char* quoteInFilename_m =
"\'\"";
77 const char* quoteInFilename_m =
" \t\'\"";
79 inline std::string rpmQuoteFilename(
const Pathname & path_r )
81 std::string path( path_r.
asString() );
83 pos != std::string::npos;
84 pos = path.find_first_of( quoteInFilename_m, pos ) )
86 path.insert( pos,
"\\" );
99 #if defined(WORKAROUNDRPMPWDBUG)
103 AutoDispose<char*> cwd( ::get_current_dir_name(), ::free );
106 WAR <<
"Can't get cwd!" << endl;
127 MIL <<
"trusted key added to zypp Keyring. Importing..." << endl;
128 _rpmdb.importPubkey( key );
133 MIL <<
"Trusted key removed from zypp Keyring. Removing..." << endl;
134 _rpmdb.removePubkey( key );
142 unsigned diffFiles(
const std::string file1,
const std::string file2, std::string& out,
int maxlines)
163 if (maxlines<0?
true:count<maxlines)
191 if ( obj == RpmDb::DbSI_NO_INIT )
197 #define ENUM_OUT(B,C) str << ( obj & RpmDb::B ? C : '-' )
220 #define FAILIFNOTINITIALIZED if( ! initialized() ) { ZYPP_THROW(RpmDbNotOpenException()); }
231 : _dbStateInfo( DbSI_NO_INIT )
232 #warning Check for obsolete memebers
233 , _backuppath (
"/var/adm/backup")
234 , _packagebackups(false)
235 , _warndirexists(false)
242 setenv(
"RPM_IgnoreFailedSymlinks",
"1", 1 );
254 MIL <<
"~RpmDb()" << endl;
257 MIL <<
"~RpmDb() end" << endl;
267 db_path =
"/var/lib/rpm";
274 return rpmdb_info.
mtime();
294 #define ENUM_OUT(B,C) str << ( _dbStateInfo & B ? C : '-' )
320 bool quickinit( root_r.
empty() );
322 if ( root_r.
empty() )
325 if ( dbPath_r.
empty() )
326 dbPath_r =
"/var/lib/rpm";
330 ERR <<
"Illegal root or dbPath: " <<
stringPath( root_r, dbPath_r ) << endl;
334 MIL <<
"Calling initDatabase: " <<
stringPath( root_r, dbPath_r )
335 << ( doRebuild_r ?
" (rebuilddb)" :
"" )
336 << ( quickinit ?
" (quickinit)" :
"" ) << endl;
360 MIL <<
"QUICK initDatabase (no systemRoot set)" << endl;
373 ERR <<
"Cleanup on error: state " << info << endl;
388 MIL <<
"Cleanup: state " << info << endl;
397 MIL <<
"Update mode: Cleanup delayed until closeOldDatabase." << endl;
400 #warning CHECK: notify root about conversion backup.
415 MIL <<
"Synchronizing keys with zypp keyring" << endl;
424 MIL <<
"InitDatabase: " << *
this << endl;
450 ERR <<
"Bad database directory: " << dbInfo.
dbDir() << endl;
457 MIL <<
"Found rpm4 database in " << dbInfo.
dbDir() << endl;
461 MIL <<
"Creating new rpm4 database in " << dbInfo.
dbDir() << endl;
473 DBG <<
"Initial state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
492 DBG <<
"Access state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
501 bool dbEmpty = dbptr->empty();
504 MIL <<
"Empty rpm4 database " << dbInfo.
dbV4() << endl;
509 MIL <<
"Found rpm3 database " << dbInfo.
dbV3() << endl;
520 WAR <<
"Backup converted rpm3 database failed: error(" << res <<
")" << endl;
527 MIL <<
"Backup converted rpm3 database: " << dbInfo.
dbV3ToV4() << endl;
536 WAR <<
"Non empty rpm3 and rpm4 database found: using rpm4" << endl;
542 DBG <<
"Convert state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
548 MIL <<
"Rpm3 database backup: " << dbInfo.
dbV3ToV4() << endl;
560 const char * v3backup =
"packages.rpm3";
561 const char * master =
"Packages";
562 const char * index[] =
587 ERR <<
"Can't remove rpm4 database in non directory: " << dbdir_r << endl;
591 for (
const char ** f = index; *f; ++f )
600 pi( dbdir_r + master );
603 MIL <<
"Removing rpm4 database " << pi << endl;
609 pi( dbdir_r + v3backup );
612 MIL <<
"Removing converted rpm3 database backup " << pi << endl;
626 const char * master =
"packages.rpm";
627 const char * index[] =
629 "conflictsindex.rpm",
643 ERR <<
"Can't remove rpm3 database in non directory: " << dbdir_r << endl;
647 for (
const char ** f = index; *f; ++f )
656 #warning CHECK: compare vs existing v3 backup. notify root
657 pi( dbdir_r + master );
680 MIL <<
"(Re)moved rpm3 database to " << pi << endl;
720 MIL <<
"Calling closeDatabase: " << *
this << endl;
751 MIL <<
"closeDatabase: " << *
this << endl;
782 MIL <<
"RpmDb::rebuildDatabase" << *
this << endl;
790 opts.push_back(
"--rebuilddb");
791 opts.push_back(
"-vv");
813 WAR <<
"User requested abort." << endl;
819 if ( line.compare( 0, 2,
"D:" ) )
821 errmsg += line +
'\n';
829 if ( rpm_status != 0 )
847 void computeKeyRingSync( std::set<Edition> & rpmKeys_r, std::list<PublicKeyData> & zyppKeys_r )
858 void updateIf(
const Edition & rpmKey_r )
860 std::string keyRelease( rpmKey_r.
release() );
861 int comp = _release.compare( keyRelease );
865 _release.swap( keyRelease );
866 _inRpmKeys = &rpmKey_r;
867 _inZyppKeys =
nullptr;
868 if ( !keyRelease.empty() )
869 DBG <<
"Old key in Z: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
871 else if ( comp == 0 )
875 _inRpmKeys = &rpmKey_r;
879 DBG <<
"Old key in R: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
882 void updateIf(
const PublicKeyData & zyppKey_r )
884 std::string keyRelease( zyppKey_r.gpgPubkeyRelease() );
885 int comp = _release.compare( keyRelease );
889 _release.swap( keyRelease );
890 _inRpmKeys =
nullptr;
891 _inZyppKeys = &zyppKey_r;
892 if ( !keyRelease.empty() )
893 DBG <<
"Old key in R: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() <<
"-" << keyRelease << endl;
895 else if ( comp == 0 )
899 _inZyppKeys = &zyppKey_r;
903 DBG <<
"Old key in Z: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() <<
"-" << keyRelease << endl;
906 std::string _release;
907 const Edition * _inRpmKeys;
908 const PublicKeyData * _inZyppKeys;
913 std::map<std::string,Key> _keymap;
915 for_( it, rpmKeys_r.begin(), rpmKeys_r.end() )
917 _keymap[(*it).version()].updateIf( *it );
920 for_( it, zyppKeys_r.begin(), zyppKeys_r.end() )
922 _keymap[(*it).gpgPubkeyVersion()].updateIf( *it );
926 std::set<Edition> rpmKeys;
927 std::list<PublicKeyData> zyppKeys;
928 for_( it, _keymap.begin(), _keymap.end() )
930 DBG <<
"gpg-pubkey-" << (*it).first <<
"-" << (*it).second._release <<
" "
931 << ( (*it).second._inRpmKeys ?
"R" :
"_" )
932 << ( (*it).second._inZyppKeys ?
"Z" :
"_" ) << endl;
933 if ( ! (*it).second._inRpmKeys )
935 zyppKeys.push_back( *(*it).second._inZyppKeys );
937 if ( ! (*it).second._inZyppKeys )
939 rpmKeys.insert( *(*it).second._inRpmKeys );
942 rpmKeys_r.swap( rpmKeys );
943 zyppKeys_r.swap( zyppKeys );
950 MIL <<
"Going to sync trusted keys..." << endl;
952 std::list<PublicKeyData> zyppKeys( getZYpp()->keyRing()->trustedPublicKeyData() );
964 MIL <<
"Removing excess keys in zypp trusted keyring" << std::endl;
970 if ( ! rpmKeys.count( keyData.gpgPubkeyEdition() ) )
972 DBG <<
"Excess key in Z to delete: gpg-pubkey-" << keyData.gpgPubkeyEdition() << endl;
973 getZYpp()->keyRing()->deleteKey( keyData.id(),
true );
974 if ( !dirty ) dirty =
true;
978 zyppKeys = getZYpp()->keyRing()->trustedPublicKeyData();
981 computeKeyRingSync( rpmKeys, zyppKeys );
982 MIL << (mode_r &
SYNC_TO_KEYRING ?
"" :
"(skip) ") <<
"Rpm keys to export into zypp trusted keyring: " << rpmKeys.size() << endl;
983 MIL << (mode_r &
SYNC_FROM_KEYRING ?
"" :
"(skip) ") <<
"Zypp trusted keys to import into rpm database: " << zyppKeys.size() << endl;
989 MIL <<
"Exporting rpm keyring into zypp trusted keyring" <<endl;
994 TmpFile tmpfile( getZYpp()->tmpPath() );
996 std::ofstream tmpos( tmpfile.
path().
c_str() );
997 for_( it, rpmKeys.begin(), rpmKeys.end() )
1001 getData(
"gpg-pubkey", *it, result );
1002 tmpos << result->tag_description() << endl;
1007 getZYpp()->keyRing()->multiKeyImport( tmpfile.
path(),
true );
1011 std::set<Edition> missingKeys;
1012 for (
const Edition & key : rpmKeys )
1014 if ( getZYpp()->keyRing()->isKeyTrusted( key.version() ) )
1016 ERR <<
"Could not import key:" <<
str::Format(
"gpg-pubkey-%s") % key <<
" into zypp keyring (V3 key?)" << endl;
1017 missingKeys.insert( key );
1019 if ( ! missingKeys.empty() )
1024 ERR <<
"Could not import keys into zypp keyring" << endl;
1032 MIL <<
"Importing zypp trusted keyring" << std::endl;
1033 for_( it, zyppKeys.begin(), zyppKeys.end() )
1037 importPubkey( getZYpp()->keyRing()->exportTrustedPublicKey( *it ) );
1045 MIL <<
"Trusted keys synced." << endl;
1067 WAR <<
"Key " << pubkey_r <<
" can not be imported. (READONLY MODE)" << endl;
1074 bool hasOldkeys =
false;
1076 for_( it, rpmKeys.begin(), rpmKeys.end() )
1083 if ( keyEd == *it && !pubkey_r.
hasSubkeys() )
1085 MIL <<
"Key " << pubkey_r <<
" is already in the rpm trusted keyring. (skip import)" << endl;
1089 if ( keyEd.
version() != (*it).version() )
1092 if ( keyEd.
release() < (*it).release() )
1094 MIL <<
"Key " << pubkey_r <<
" is older than one in the rpm trusted keyring. (skip import)" << endl;
1102 MIL <<
"Key " << pubkey_r <<
" will be imported into the rpm trusted keyring." << (hasOldkeys?
"(update)":
"(new)") << endl;
1108 std::string keyName(
"gpg-pubkey-" + keyEd.
version() );
1110 opts.push_back (
"-e" );
1111 opts.push_back (
"--allmatches" );
1112 opts.push_back (
"--" );
1113 opts.push_back ( keyName.c_str() );
1126 ERR <<
"Failed to remove key " << pubkey_r <<
" from RPM trusted keyring (ignored)" << endl;
1130 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1136 opts.push_back (
"--import" );
1137 opts.push_back (
"--" );
1139 opts.push_back ( pubkeypath.c_str() );
1146 std::vector<std::string> excplines;
1151 WAR << line << endl;
1152 excplines.push_back( std::move(line) );
1155 DBG << line << endl;
1168 MIL <<
"Key " << pubkey_r <<
" imported in rpm trusted keyring." << endl;
1185 std::set<Edition>::const_iterator found_edition = rpm_keys.end();
1188 for_( it, rpm_keys.begin(), rpm_keys.end() )
1190 if ( (*it).version() == pubkeyVersion )
1198 if (found_edition == rpm_keys.end())
1200 WAR <<
"Key " << pubkey_r.
id() <<
" is not in rpm db" << endl;
1204 std::string rpm_name(
"gpg-pubkey-" + found_edition->asString());
1207 opts.push_back (
"-e" );
1208 opts.push_back (
"--" );
1209 opts.push_back ( rpm_name.c_str() );
1216 std::vector<std::string> excplines;
1221 WAR << line << endl;
1222 excplines.push_back( std::move(line) );
1225 DBG << line << endl;
1238 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1250 std::list<PublicKey> ret;
1253 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1255 Edition edition = it->tag_edition();
1260 getData(
"gpg-pubkey", edition, result );
1261 TmpFile file(getZYpp()->tmpPath());
1267 os << result->tag_description();
1276 catch ( std::exception & e )
1278 ERR <<
"Could not dump key " << edition.
asString() <<
" in tmp file " << file.
path() << endl;
1288 std::set<Edition> ret;
1291 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1293 Edition edition = it->tag_edition();
1295 ret.insert( edition );
1312 std::list<FileInfo> result;
1347 if (!name_r.empty())
1349 res = (it->tag_name() == name_r);
1370 return it->tag_name();
1484 struct RpmlogCapture :
public std::string
1487 { rpmlog()._cap =
this; }
1490 { rpmlog()._cap =
nullptr; }
1498 rpmlogSetCallback( rpmLogCB,
this );
1499 rpmSetVerbosity( RPMLOG_INFO );
1500 _f = ::fopen(
"/dev/null",
"w");
1501 rpmlogSetFile(
_f );
1505 {
if (
_f ) ::fclose(
_f ); }
1507 static int rpmLogCB( rpmlogRec rec_r, rpmlogCallbackData data_r )
1508 {
return reinterpret_cast<Rpmlog*
>(data_r)->rpmLog( rec_r ); }
1510 int rpmLog( rpmlogRec rec_r )
1512 if (
_cap ) (*_cap) += rpmlogRecMessage( rec_r );
1513 return RPMLOG_DEFAULT;
1520 static Rpmlog & rpmlog()
1521 {
static Rpmlog _rpmlog;
return _rpmlog; }
1526 bool requireGPGSig_r,
1527 RpmDb::CheckPackageDetail & detail_r )
1530 if ( ! file.isFile() )
1532 ERR <<
"Not a file: " << file << endl;
1536 FD_t fd = ::Fopen( file.asString().c_str(),
"r.ufdio" );
1537 if ( fd == 0 || ::Ferror(fd) )
1539 ERR <<
"Can't open file for reading: " << file <<
" (" << ::Fstrerror(fd) <<
")" << endl;
1544 rpmts ts = ::rpmtsCreate();
1545 ::rpmtsSetRootDir( ts, root_r.
c_str() );
1546 ::rpmtsSetVSFlags( ts, RPMVSF_DEFAULT );
1548 rpmQVKArguments_s qva;
1549 memset( &qva, 0,
sizeof(rpmQVKArguments_s) );
1550 qva.qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE);
1552 RpmlogCapture vresult;
1553 LocaleGuard guard( LC_ALL,
"C" );
1554 int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.
basename().c_str() );
1567 std::vector<std::string> lines;
1568 str::split( vresult, std::back_inserter(lines),
"\n" );
1569 unsigned count[7] = { 0, 0, 0, 0, 0, 0, 0 };
1571 for (
unsigned i = 1; i < lines.size(); ++i )
1573 std::string & line( lines[i] );
1575 if ( line.find(
": OK" ) != std::string::npos )
1578 if ( line.find(
"Signature, key ID" ) == std::string::npos )
1581 else if ( line.find(
": NOKEY" ) != std::string::npos )
1583 else if ( line.find(
": BAD" ) != std::string::npos )
1585 else if ( line.find(
": UNKNOWN" ) != std::string::npos )
1587 else if ( line.find(
": NOTRUSTED" ) != std::string::npos )
1591 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( lineres, std::move(line) ) );
1612 detail_r.push_back( RpmDb::CheckPackageDetail::value_type(
RpmDb::CHK_NOSIG, std::string(
" ")+
_(
"Package is not signed!") ) );
1613 if ( requireGPGSig_r )
1620 WAR << path_r <<
" (" << requireGPGSig_r <<
" -> " << ret <<
")" << endl;
1633 {
return doCheckPackageSig( path_r,
root(),
false, detail_r ); }
1639 {
return doCheckPackageSig( path_r,
root(),
true, detail_r ); }
1654 opts.push_back (
"-V");
1655 opts.push_back (
"--nodeps");
1656 opts.push_back (
"--noscripts");
1657 opts.push_back (
"--nomd5");
1658 opts.push_back (
"--");
1659 opts.push_back (packageName.c_str());
1680 if (line.length() > 12 &&
1681 (line[0] ==
'S' || line[0] ==
's' ||
1682 (line[0] ==
'.' && line[7] ==
'T')))
1685 std::string filename;
1687 filename.assign(line, 11, line.length() - 11);
1728 #if defined(WORKAROUNDRPMPWDBUG)
1729 args.push_back(
"#/");
1731 args.push_back(
"rpm");
1732 args.push_back(
"--root");
1734 args.push_back(
"--dbpath");
1737 const char* argv[args.size() + opts.size() + 1];
1739 const char** p = argv;
1740 p =
copy (args.begin (), args.end (), p);
1741 p =
copy (opts.begin (), opts.end (), p);
1767 int inputfileFd = ::fileno( inputfile );
1773 FD_SET( inputfileFd, &rfds );
1780 int retval = select( inputfileFd+1, &rfds, NULL, NULL, &tv );
1784 ERR <<
"select error: " <<
strerror(errno) << endl;
1785 if ( errno != EINTR )
1791 static size_t linebuffer_size = 0;
1792 static char * linebuffer = 0;
1793 ssize_t nread =
getline( &linebuffer, &linebuffer_size, inputfile );
1796 if ( ::feof( inputfile ) )
1803 if ( linebuffer[nread-1] ==
'\n' )
1805 line += std::string( linebuffer, nread );
1808 if ( ! ::ferror( inputfile ) || ::feof( inputfile ) )
1811 clearerr( inputfile );
1860 void RpmDb::processConfigFiles(
const std::string& line,
const std::string& name,
const char* typemsg,
const char* difffailmsg,
const char* diffgenmsg)
1862 std::string msg = line.substr(9);
1865 std::string file1s, file2s;
1869 pos1 = msg.find (typemsg);
1872 if ( pos1 == std::string::npos )
1875 pos2 = pos1 + strlen (typemsg);
1877 if (pos2 >= msg.length() )
1880 file1 = msg.substr (0, pos1);
1881 file2 = msg.substr (pos2);
1888 file1 =
_root + file1;
1889 file2 =
_root + file2;
1899 ERR <<
"Could not create " << file.
asString() << endl;
1903 std::ofstream notify(file.
asString().c_str(), std::ios::out|std::ios::app);
1906 ERR <<
"Could not open " << file << endl;
1912 notify <<
str::form(
_(
"Changed configuration files for %s:"), name.c_str()) << endl;
1915 ERR <<
"diff failed" << endl;
1917 file1s.c_str(), file2s.c_str()) << endl;
1922 file1s.c_str(), file2s.c_str()) << endl;
1927 if (out.substr(0,4) ==
"--- ")
1929 out.replace(4, file1.
asString().length(), file1s);
1932 if (pos != std::string::npos)
1934 out.replace(pos+5, file2.
asString().length(), file2s);
1937 notify << out << endl;
1940 notify.open(
"/var/lib/update-messages/yast2-packagemanager.rpmdb.configfiles");
1945 WAR <<
"rpm created " << file2 <<
" but it is not different from " << file2 << endl;
1976 report->finish( excpt_r );
1992 MIL <<
"RpmDb::installPackage(" << filename <<
"," << flags <<
")" << endl;
2001 ERR <<
"backup of " << filename.
asString() <<
" failed" << endl;
2010 opts.push_back(
"-i");
2012 opts.push_back(
"-U");
2014 opts.push_back(
"--percent");
2015 opts.push_back(
"--noglob");
2019 opts.push_back(
"--ignorearch");
2022 opts.push_back(
"--nodigest");
2024 opts.push_back(
"--nosignature");
2026 opts.push_back (
"--excludedocs");
2028 opts.push_back (
"--noscripts");
2030 opts.push_back (
"--force");
2032 opts.push_back (
"--nodeps");
2034 opts.push_back (
"--ignoresize");
2036 opts.push_back (
"--justdb");
2038 opts.push_back (
"--test");
2040 opts.push_back (
"--noposttrans");
2042 opts.push_back(
"--");
2045 std::string quotedFilename( rpmQuoteFilename( workaroundRpmPwdBug( filename ) ) );
2046 opts.push_back ( quotedFilename.c_str() );
2053 std::vector<std::string> configwarnings;
2055 unsigned linecnt = 0;
2061 sscanf( line.c_str() + 2,
"%d", &percent );
2062 report->progress( percent );
2068 else if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2071 rpmmsg += line+
'\n';
2074 configwarnings.push_back(line);
2077 rpmmsg +=
"[truncated]\n";
2082 for (std::vector<std::string>::iterator it = configwarnings.begin();
2083 it != configwarnings.end(); ++it)
2087 _(
"rpm saved %s as %s, but it was impossible to determine the difference"),
2089 _(
"rpm saved %s as %s.\nHere are the first 25 lines of difference:\n"));
2092 _(
"rpm created %s as %s, but it was impossible to determine the difference"),
2094 _(
"rpm created %s as %s.\nHere are the first 25 lines of difference:\n"));
2097 if ( rpm_status != 0 )
2102 std::ostringstream sstr;
2103 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2104 historylog.
comment(sstr.str());
2108 else if ( ! rpmmsg.empty() )
2113 std::ostringstream sstr;
2114 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2115 historylog.
comment(sstr.str());
2119 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2133 +
"-" + package->edition().version()
2134 +
"-" + package->edition().release()
2135 +
"." + package->arch().asString(), flags );
2163 report->finish( excpt_r );
2180 MIL <<
"RpmDb::doRemovePackage(" << name_r <<
"," << flags <<
")" << endl;
2189 ERR <<
"backup of " << name_r <<
" failed" << endl;
2200 opts.push_back(
"-e");
2201 opts.push_back(
"--allmatches");
2204 opts.push_back(
"--noscripts");
2206 opts.push_back(
"--nodeps");
2208 opts.push_back(
"--justdb");
2210 opts.push_back (
"--test");
2213 WAR <<
"IGNORE OPTION: 'rpm -e' does not support '--force'" << endl;
2216 opts.push_back(
"--");
2217 opts.push_back(name_r.c_str());
2230 unsigned linecnt = 0;
2235 else if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2237 rpmmsg += line+
'\n';
2240 rpmmsg +=
"[truncated]\n";
2244 if ( rpm_status != 0 )
2247 str::form(
"%s remove failed", name_r.c_str()),
true );
2248 std::ostringstream sstr;
2249 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2250 historylog.
comment(sstr.str());
2254 else if ( ! rpmmsg.empty() )
2257 str::form(
"%s removed ok", name_r.c_str()),
true );
2259 std::ostringstream sstr;
2260 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2261 historylog.
comment(sstr.str());
2265 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2299 INT <<
"_backuppath empty" << endl;
2307 ERR <<
"Error while getting changed files for package " <<
2308 packageName << endl;
2314 DBG <<
"package " << packageName <<
" not changed -> no backup" << endl;
2326 struct tm *currentLocalTime = localtime(&
currentTime);
2328 int date = (currentLocalTime->tm_year + 1900) * 10000
2329 + (currentLocalTime->tm_mon + 1) * 100
2330 + currentLocalTime->tm_mday;
2336 +
str::form(
"%s-%d-%d.tar.gz",packageName.c_str(), date, num);
2339 while (
PathInfo(backupFilename).isExist() && num++ < 1000);
2344 ERR << filestobackupfile.
asString() <<
" already exists and is no file" << endl;
2348 std::ofstream fp ( filestobackupfile.
asString().c_str(), std::ios::out|std::ios::trunc );
2352 ERR <<
"could not open " << filestobackupfile.
asString() << endl;
2356 for (FileList::const_iterator cit =
fileList.begin();
2359 std::string name = *cit;
2360 if ( name[0] ==
'/' )
2363 name = name.substr( 1 );
2365 DBG <<
"saving file "<< name << endl;
2370 const char*
const argv[] =
2376 "--ignore-failed-read",
2380 filestobackupfile.
asString().c_str(),
2396 int ret = tar.
close();
2400 ERR <<
"tar failed: " << tarmsg << endl;
2405 MIL <<
"tar backup ok" << endl;
2426 #define OUTS(E,S) case RpmDb::E: return str << "["<< (unsigned)obj << "-"<< S << "]"; break
2428 OUTS( CHK_OK,
_(
"Signature is OK") );
2430 OUTS( CHK_NOTFOUND,
_(
"Unknown type of signature") );
2432 OUTS( CHK_FAIL,
_(
"Signature does not verify") );
2434 OUTS( CHK_NOTTRUSTED,
_(
"Signature is OK, but key is not trusted") );
2436 OUTS( CHK_NOKEY,
_(
"Signatures public key is not available") );
2438 OUTS( CHK_ERROR,
_(
"File does not exist or signature can't be checked") );
2440 OUTS( CHK_NOSIG,
_(
"File is unsigned") );
2448 for (
const auto & el : obj )
2449 str << el.second << endl;
Date timestamp() const
timestamp of the rpm database (last modification)
bool usableArgs() const
Whether constructor arguments were llegal and dbDir either is a directory or may be created (path doe...
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
std::ostream & operator<<(std::ostream &str, const librpmDb::DbDirInfo &obj)
std::string stringPath(const Pathname &root_r, const Pathname &sub_r)
const Pathname & path() const
Return current Pathname.
void run_rpm(const RpmArgVec &options, ExternalProgram::Stderr_Disposition stderr_disp=ExternalProgram::Stderr_To_Stdout)
Run rpm with the specified arguments and handle stderr.
bool isExist() const
Return whether valid stat info exists.
bool hasDbV3ToV4() const
Whether dbV3ToV4 file exists.
void removePubkey(const PublicKey &pubkey_r)
Remove a public key from the rpm database.
void doRebuildDatabase(callback::SendReport< RebuildDBReport > &report)
virtual void trustedKeyAdded(const PublicKey &key)
Base class for Exception.
CheckPackageResult
checkPackage result
const PathInfo & dbV4() const
rpmV4 database (_dbDir/Packages)
bool absolute() const
Test for an absolute path.
bool findByRequiredBy(const std::string &tag_r)
Reset to iterate all packages that require a certain tag.
bool kill()
Kill the program.
void closeDatabase()
Block further access to the rpm database and go back to uninitialized state.
bool hasDbV3() const
Whether dbV3 file exists.
std::set< Edition > pubkeyEditions() const
Return the edition of all installed public keys.
Pathname _backuppath
/var/adm/backup
void internal_initDatabase(const Pathname &root_r, const Pathname &dbPath_r, DbStateInfoBits &info_r)
Internal helper for initDatabase.
bool hasDbV4() const
Whether dbV4 file exists.
void setBackupPath(const Pathname &path)
set path where package backups are stored
static bool globalInit()
Initialize lib librpm (read configfiles etc.).
bool hasConflicts(const std::string &tag_r) const
Return true if at least one package conflicts with a certain tag.
int rename(const Pathname &oldpath, const Pathname &newpath)
Like 'rename'.
Class representing one GPG Public Keys data. PublicKeyData are provided e.g. by a PublicKey or a KeyR...
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
Types and functions for filesystem operations.
Edition represents [epoch:]version[-release]
bool running()
Return whether program is running.
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"
void systemKill()
Forcably kill the system process.
bool hasSubkeys() const
!<
void importZyppKeyRingTrustedKeys()
iterates through zypp keyring and import all non existant keys into rpm keyring
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 exportTrustedKeysInZyppKeyRing()
insert all rpm trusted keys into zypp trusted keyring
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Pathname _root
Root directory for all operations.
void addHistory(const std::string &msg_r)
Add some message text to the history.
TraitsType::constPtrType constPtr
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
bool systemReadLine(std::string &line)
Read a line from the general rpm query.
static shared_ptr< KeyRingSignalReceiver > sKeyRingReceiver
std::string strerror(int errno_r)
Return string describing the error_r code.
void installPackage(const Pathname &filename, RpmInstFlags flags=RPMINST_NONE)
install rpm package
bool findByProvides(const std::string &tag_r)
Reset to iterate all packages that provide a certain tag.
static void removeV4(const Pathname &dbdir_r, bool v3backup_r)
Remove the rpm4 database in dbdir_r and optionally any backup created on conversion.
int unlink(const Pathname &path)
Like 'unlink'.
std::string release() const
Release.
const std::string & execError() const
Some detail telling why the execution failed, if it failed.
static void removeV3(const Pathname &dbdir_r, bool v3backup_r)
Remove the rpm3 database in dbdir_r.
std::string getline(std::istream &str)
Read one line from stream.
static unsigned blockAccess()
Blocks further access to rpmdb.
static void unblockAccess()
Allow access to rpmdb e.g.
void importPubkey(const PublicKey &pubkey_r)
Import ascii armored public key in file pubkey_r.
bool queryChangedFiles(FileList &fileList, const std::string &packageName)
determine which files of an installed package have been modified.
void moveToHistory(TContainer &&msgc_r)
addHistory from string container types (oldest first) moving
Wrapper class for ::stat/::lstat.
bool hasProvides(const std::string &tag_r) const
Return true if at least one package provides a certain tag.
Provide a new empty temporary file and delete it when no longer needed.
void getData(const std::string &name_r, RpmHeader::constPtr &result_r) const
Get an installed packages data from rpmdb.
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
ExternalProgram * process
The connection to the rpm process.
@ SYNC_TO_KEYRING
export rpm trusted keys into zypp trusted keyring
const char * c_str() const
String representation.
Writing the zypp history file.
std::string gpgPubkeyVersion() const
static std::ostream & dumpState(std::ostream &str)
Dump debug info.
bool hasPackage(const std::string &name_r) const
Return true if package is installed.
const PathInfo & dbV3() const
rpmV3 database (_dbDir/packages.rpm)
std::list< PublicKey > pubkeys() const
Return the long ids of all installed public keys.
static void dbAccess()
Access the database at the current default location.
void syncTrustedKeys(SyncTrustedKeyBits mode_r=SYNC_BOTH)
Sync trusted keys stored in rpm database and zypp trusted keyring.
Interface to the rpm program.
DbStateInfoBits _dbStateInfo
Internal state info.
void convertV3toV4(const Pathname &v3db_r, const librpmDb::constPtr &v4db_r)
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
#define MAXRPMMESSAGELINES
void restat()
Restat all paths.
Pathname _dbPath
Directory that contains the rpmdb.
static ZConfig & instance()
Singleton ctor.
Just inherits Exception to separate media exceptions.
Easy-to use interface to the ZYPP dependency resolver.
std::string numstring(char n, int w=0)
std::string version() const
Version.
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t")
Split line_r into words.
bool _packagebackups
create package backups?
std::string form(const std::string &format_r) const
Return string representation according to format as localtime.
Collect info about what kind of rpmdb seems to be present by looking at paths and filenames.
const PathInfo & dbV3ToV4() const
rpmV3 database backup created on conversion to rpmV4 (_dbDir/packages.rpm3)
void doInstallPackage(const Pathname &filename, RpmInstFlags flags, callback::SendReport< RpmInstallReport > &report)
void initDatabase(Pathname root_r=Pathname(), Pathname dbPath_r=Pathname(), bool doRebuild_r=false)
Prepare access to the rpm database.
bool findByConflicts(const std::string &tag_r)
Reset to iterate all packages that conflict with a certain tag.
SyncTrustedKeyBits
Sync mode for syncTrustedKeys.
Stderr_Disposition
Define symbols for different policies on the handling of stderr.
int close()
Wait for the progamm to complete.
const Pathname & root() const
int copy(const Pathname &file, const Pathname &dest)
Like 'cp file dest'.
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 ...
bool dbsi_has(const DbStateInfoBits &val_r, const unsigned &bits_r) const
std::string asString() const
void dbsi_set(DbStateInfoBits &val_r, const unsigned &bits_r) const
Subclass to retrieve database content.
bool findByName(const std::string &name_r)
Reset to iterate all packages with a certain name.
void removePackage(const std::string &name_r, RpmInstFlags flags=RPMINST_NONE)
remove rpm package
virtual void trustedKeyRemoved(const PublicKey &key)
bool findPackage(const std::string &name_r)
Find package by name.
std::string receiveLine()
Read one line from the input stream.
bool illegalArgs() const
Whether constructor arguments were illegal.
static const Edition noedition
Value representing noedition ("") This is in fact a valid Edition.
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
const Pathname & dbPath() const
void dbsi_clr(DbStateInfoBits &val_r, const unsigned &bits_r) const
Pathname dirname() const
Return all but the last component od this path.
const PathInfo & dbDir() const
database directory (unset on illegal constructor arguments)
bool hasRequiredBy(const std::string &tag_r) const
Return true if at least one package requires a certain tag.
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
std::string gpgPubkeyRelease() const
Store and operate on date (time_t).
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
Pathname path() const
File containig the ASCII armored key.
void doRemovePackage(const std::string &name_r, RpmInstFlags flags, callback::SendReport< RpmRemoveReport > &report)
std::ostream & operator<<(std::ostream &str, const Glob &obj)
void setBlocking(bool mode)
Set the blocking mode of the input stream.
intrusive_ptr< const librpmDb > constPtr
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 !...
std::ostream & copy(std::istream &from_r, std::ostream &to_r)
Copy istream to ostream.
bool empty() const
Test for an empty path.
@ SYNC_FROM_KEYRING
import zypp trusted keys into rpm database.
static Date now()
Return the current time.
void modifyDatabase()
Called before the database is modified by installPackage/removePackage.
Detailed rpm signature check log messages A single multiline message if CHK_OK.
Temporarily connect a ReceiveReport then restore the previous one.
unsigned diffFiles(const std::string file1, const std::string file2, std::string &out, int maxlines)
std::set< std::string > FileList
std::string asString() const
static unsigned dbRelease(bool force_r=false)
If there are no outstanding references to the database (e.g.
shared_ptr< RpmException > dbError() const
Return any database error.
std::string basename() const
Return the last component of this path.
bool findByFile(const std::string &file_r)
Reset to iterate all packages that own a certain file.
std::string error_message
Error message from running rpm as external program.
String related utilities and Regular expression matching.
#define FAILIFNOTINITIALIZED
int exit_code
The exit code of the rpm process, or -1 if not yet known.
#define FILEFORBACKUPFILES
KeyRingSignalReceiver(RpmDb &rpmdb)
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
const std::string & asString() const
String representation.
void comment(const std::string &comment, bool timestamp=false)
Log a comment (even multiline).
std::vector< const char * > RpmArgVec
std::string whoOwnsFile(const std::string &file_r) const
Return name of package owning file or empty string if no installed package owns file.
virtual std::ostream & dumpOn(std::ostream &str) const
Dump debug info.
int systemStatus()
Return the exit status of the general rpm process, closing the connection if not already done.
bool relative() const
Test for a relative path.
FILE * inputFile() const
Return the input stream.