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 );
670 Pathname b( m.extend(
".deleted" ) );
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);
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;
std::ostream & operator<<(std::ostream &str, const librpmDb::DbDirInfo &obj)
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Interface to the rpm program.
unsigned diffFiles(const std::string file1, const std::string file2, std::string &out, int maxlines)
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 hasRequiredBy(const std::string &tag_r) const
Return true if at least one package requires a certain tag.
static unsigned blockAccess()
Blocks further access to rpmdb.
static std::ostream & dumpState(std::ostream &str)
Dump debug info.
const Pathname & path() const
Return current Pathname.
void getData(const std::string &name_r, RpmHeader::constPtr &result_r) const
Get an installed packages data from rpmdb.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
virtual void trustedKeyAdded(const PublicKey &key)
bool kill()
Kill the program.
static ZConfig & instance()
Singleton ctor.
Pathname _root
Root directory for all operations.
bool findByProvides(const std::string &tag_r)
Reset to iterate all packages that provide a certain tag.
const PathInfo & dbV3ToV4() const
rpmV3 database backup created on conversion to rpmV4 (_dbDir/packages.rpm3)
Class representing one GPG Public Keys data.
Collect info about what kind of rpmdb seems to be present by looking at paths and filenames...
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
void exportTrustedKeysInZyppKeyRing()
insert all rpm trusted keys into zypp trusted keyring
static void dbAccess()
Access the database at the current default location.
void rebuildDatabase()
Rebuild the rpm database (rpm –rebuilddb).
void installPackage(const Pathname &filename, RpmInstFlags flags=RPMINST_NONE)
install rpm package
const char * c_str() const
String representation.
Date timestamp() const
timestamp of the rpm database (last modification)
void internal_initDatabase(const Pathname &root_r, const Pathname &dbPath_r, DbStateInfoBits &info_r)
Internal helper for initDatabase.
String related utilities and Regular expression matching.
bool hasDbV3() const
Whether dbV3 file exists.
bool findByRequiredBy(const std::string &tag_r)
Reset to iterate all packages that require a certain tag.
void modifyDatabase()
Called before the database is modified by installPackage/removePackage.
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \)
Split line_r into words.
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Edition represents [epoch:]version[-release]
bool running()
Return whether program is running.
bool usableArgs() const
Whether constructor arguments were llegal and dbDir either is a directory or may be created (path doe...
bool hasSubkeys() const
!<
std::string basename() const
Return the last component of this path.
Provide a new empty temporary file and delete it when no longer needed.
void importZyppKeyRingTrustedKeys()
iterates through zypp keyring and import all non existant keys into rpm keyring
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
bool backupPackage(const std::string &packageName)
create tar.gz of all changed files in a Package
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, like 'rpm -K')
#define FILEFORBACKUPFILES
Subclass to retrieve database content.
Temporarily connect a ReceiveReport then restore the previous one.
void importPubkey(const PublicKey &pubkey_r)
Import ascii armored public key in file pubkey_r.
bool hasDbV3ToV4() const
Whether dbV3ToV4 file exists.
bool hasPackage(const std::string &name_r) const
Return true if package is installed.
void systemKill()
Forcably kill the system process.
bool empty() const
Test for an empty path.
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
void moveToHistory(TContainer &&msgc_r)
addHistory from string container types (oldest first) moving
void syncTrustedKeys(SyncTrustedKeyBits mode_r=SYNC_BOTH)
Sync trusted keys stored in rpm database and zypp trusted keyring.
#define FAILIFNOTINITIALIZED
std::string getline(std::istream &str)
Read one line from stream.
Store and operate on date (time_t).
const std::string & execError() const
Some detail telling why the execution failed, if it failed.
Pathname _backuppath
/var/adm/backup
std::string version() const
Version.
shared_ptr< RpmException > dbError() const
Return any database error.
std::string form(const std::string &format_r) const
Return string representation according to format as localtime.
std::string asString() const
int exit_code
The exit code of the rpm process, or -1 if not yet known.
std::list< PublicKey > pubkeys() const
Return the long ids of all installed public keys.
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
void dbsi_set(DbStateInfoBits &val_r, const unsigned &bits_r) const
int unlink(const Pathname &path)
Like 'unlink'.
std::string gpgPubkeyVersion() const
SyncTrustedKeyBits
Sync mode for syncTrustedKeys.
bool systemReadLine(std::string &line)
Read a line from the general rpm query.
const std::string & asString() const
String representation.
int rename(const Pathname &oldpath, const Pathname &newpath)
Like 'rename'.
int systemStatus()
Return the exit status of the general rpm process, closing the connection if not already done...
std::set< Edition > pubkeyEditions() const
Return the edition of all installed public keys.
bool isExist() const
Return whether valid stat info exists.
bool findByName(const std::string &name_r)
Reset to iterate all packages with a certain name.
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
std::string release() const
Release.
Detailed rpm signature check log messages A single multiline message if CHK_OK.
virtual std::ostream & dumpOn(std::ostream &str) const
Dump debug info.
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
Types and functions for filesystem operations.
static unsigned dbRelease(bool force_r=false)
If there are no outstanding references to the database (e.g.
static shared_ptr< KeyRingSignalReceiver > sKeyRingReceiver
ExternalProgram * process
The connection to the rpm process.
Writing the zypp history fileReference counted signleton for writhing the zypp history file...
void doRebuildDatabase(callback::SendReport< RebuildDBReport > &report)
bool absolute() const
Test for an absolute path.
bool findByFile(const std::string &file_r)
Reset to iterate all packages that own a certain file.
std::string receiveLine()
Read one line from the input stream.
void closeDatabase()
Block further access to the rpm database and go back to uninitialized state.
Stderr_Disposition
Define symbols for different policies on the handling of stderr.
DbStateInfoBits _dbStateInfo
Internal state info.
bool hasProvides(const std::string &tag_r) const
Return true if at least one package provides a certain tag.
bool dbsi_has(const DbStateInfoBits &val_r, const unsigned &bits_r) const
Just inherits Exception to separate media exceptions.
std::string numstring(char n, int w=0)
import zypp trusted keys into rpm database.
virtual void trustedKeyRemoved(const PublicKey &key)
bool findPackage(const std::string &name_r)
Find package by name.
bool illegalArgs() const
Whether constructor arguments were illegal.
static void unblockAccess()
Allow access to rpmdb e.g.
std::ostream & copy(std::istream &from_r, std::ostream &to_r)
Copy istream to ostream.
void doInstallPackage(const Pathname &filename, RpmInstFlags flags, callback::SendReport< RpmInstallReport > &report)
int close()
Wait for the progamm to complete.
void removePubkey(const PublicKey &pubkey_r)
Remove a public key from the rpm database.
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"
int copy(const Pathname &file, const Pathname &dest)
Like 'cp file dest'.
bool _packagebackups
create package backups?
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
std::string gpgPubkeyRelease() const
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
const PathInfo & dbV3() const
rpmV3 database (_dbDir/packages.rpm)
void doRemovePackage(const std::string &name_r, RpmInstFlags flags, callback::SendReport< RpmRemoveReport > &report)
Base class for Exception.
bool hasDbV4() const
Whether dbV4 file exists.
void setBackupPath(const Pathname &path)
set path where package backups are stored
const Pathname & root() const
bool hasConflicts(const std::string &tag_r) const
Return true if at least one package conflicts with a certain tag.
Pathname path() const
File containig the ASCII armored key.
const Pathname & dbPath() const
const PathInfo & dbV4() const
rpmV4 database (_dbDir/Packages)
static Date now()
Return the current time.
void convertV3toV4(const Pathname &v3db_r, const librpmDb::constPtr &v4db_r)
void initDatabase(Pathname root_r=Pathname(), Pathname dbPath_r=Pathname(), bool doRebuild_r=false)
Prepare access to the rpm database.
std::string error_message
Error message from running rpm as external program.
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 removePackage(const std::string &name_r, RpmInstFlags flags=RPMINST_NONE)
remove rpm package
static bool globalInit()
Initialize lib librpm (read configfiles etc.).
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 != Edition...
std::string asString() const
bool relative() const
Test for a relative path.
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 ...
void comment(const std::string &comment, bool timestamp=false)
Log a comment (even multiline).
bool findByConflicts(const std::string &tag_r)
Reset to iterate all packages that conflict with a certain tag.
Wrapper class for ::stat/::lstat.
void setBlocking(bool mode)
Set the blocking mode of the input stream.
CheckPackageResult
checkPackage result
std::string stringPath(const Pathname &root_r, const Pathname &sub_r)
static void removeV3(const Pathname &dbdir_r, bool v3backup_r)
Remove the rpm3 database in dbdir_r.
bool queryChangedFiles(FileList &fileList, const std::string &packageName)
determine which files of an installed package have been modified.
static void removeV4(const Pathname &dbdir_r, bool v3backup_r)
Remove the rpm4 database in dbdir_r and optionally any backup created on conversion.
FILE * inputFile() const
Return the input stream.
std::string strerror(int errno_r)
Return string describing the error_r code.
std::ostream & operator<<(std::ostream &str, const Glob &obj)
intrusive_ptr< const librpmDb > constPtr
Easy-to use interface to the ZYPP dependency resolver.
void run_rpm(const RpmArgVec &options, ExternalProgram::Stderr_Disposition stderr_disp=ExternalProgram::Stderr_To_Stdout)
Run rpm with the specified arguments and handle stderr.
export rpm trusted keys into zypp trusted keyring
KeyRingSignalReceiver(RpmDb &rpmdb)
void dbsi_clr(DbStateInfoBits &val_r, const unsigned &bits_r) const
void restat()
Restat all paths.
TraitsType::constPtrType constPtr
#define MAXRPMMESSAGELINES
static const Edition noedition
Value representing noedition ("") This is in fact a valid Edition.
Pathname _dbPath
Directory that contains the rpmdb.
std::set< std::string > FileList
const PathInfo & dbDir() const
database directory (unset on illegal constructor arguments)
std::vector< const char * > RpmArgVec