15 #include <rpm/rpmcli.h>
16 #include <rpm/rpmlog.h>
54 using namespace zypp::filesystem;
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;
131 _rpmdb.importPubkey( key );
135 ERR <<
"Could not import key " << key.
id() <<
" (" << key.
name() <<
" from " << key.
path() <<
" in rpm database" << endl;
141 MIL <<
"Trusted key removed from zypp Keyring. Removing..." << endl;
146 _rpmdb.removePubkey( key );
150 ERR <<
"Could not remove key " << key.
id() <<
" (" << key.
name() <<
") from rpm database" << endl;
159 unsigned diffFiles(
const std::string file1,
const std::string file2, std::string& out,
int maxlines)
180 if (maxlines<0?
true:count<maxlines)
195 inline std::string
stringPath(
const Pathname & root_r,
const Pathname & sub_r )
208 if ( obj == RpmDb::DbSI_NO_INIT )
214 #define ENUM_OUT(B,C) str << ( obj & RpmDb::B ? C : '-' )
237 #define FAILIFNOTINITIALIZED if( ! initialized() ) { ZYPP_THROW(RpmDbNotOpenException()); }
248 : _dbStateInfo( DbSI_NO_INIT )
249 #warning Check for obsolete memebers
250 , _backuppath (
"/var/adm/backup")
251 , _packagebackups(false)
252 , _warndirexists(false)
259 setenv(
"RPM_IgnoreFailedSymlinks",
"1", 1 );
271 MIL <<
"~RpmDb()" << endl;
274 MIL <<
"~RpmDb() end" << endl;
284 db_path =
"/var/lib/rpm";
288 PathInfo rpmdb_info(
root() + db_path +
"/Packages");
290 if ( rpmdb_info.isExist() )
291 return rpmdb_info.mtime();
311 #define ENUM_OUT(B,C) str << ( _dbStateInfo & B ? C : '-' )
337 bool quickinit( root_r.empty() );
339 if ( root_r.empty() )
342 if ( dbPath_r.empty() )
343 dbPath_r =
"/var/lib/rpm";
345 if ( ! (root_r.absolute() && dbPath_r.absolute()) )
347 ERR <<
"Illegal root or dbPath: " <<
stringPath( root_r, dbPath_r ) << endl;
351 MIL <<
"Calling initDatabase: " <<
stringPath( root_r, dbPath_r )
352 << ( doRebuild_r ?
" (rebuilddb)" :
"" )
353 << ( quickinit ?
" (quickinit)" :
"" ) << endl;
377 MIL <<
"QUICK initDatabase (no systemRoot set)" << endl;
390 ERR <<
"Cleanup on error: state " << info << endl;
405 MIL <<
"Cleanup: state " << info << endl;
414 MIL <<
"Update mode: Cleanup delayed until closeOldDatabase." << endl;
417 #warning CHECK: notify root about conversion backup.
432 MIL <<
"Synchronizing keys with zypp keyring" << endl;
441 MIL <<
"InitDatabase: " << *
this << endl;
467 ERR <<
"Bad database directory: " << dbInfo.
dbDir() << endl;
474 MIL <<
"Found rpm4 database in " << dbInfo.
dbDir() << endl;
478 MIL <<
"Creating new rpm4 database in " << dbInfo.
dbDir() << endl;
490 DBG <<
"Initial state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
509 DBG <<
"Access state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
518 bool dbEmpty = dbptr->empty();
521 MIL <<
"Empty rpm4 database " << dbInfo.
dbV4() << endl;
526 MIL <<
"Found rpm3 database " << dbInfo.
dbV3() << endl;
537 WAR <<
"Backup converted rpm3 database failed: error(" << res <<
")" << endl;
544 MIL <<
"Backup converted rpm3 database: " << dbInfo.
dbV3ToV4() << endl;
553 WAR <<
"Non empty rpm3 and rpm4 database found: using rpm4" << endl;
559 DBG <<
"Convert state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
565 MIL <<
"Rpm3 database backup: " << dbInfo.
dbV3ToV4() << endl;
577 const char * v3backup =
"packages.rpm3";
578 const char * master =
"Packages";
579 const char * index[] =
601 PathInfo pi( dbdir_r );
604 ERR <<
"Can't remove rpm4 database in non directory: " << dbdir_r << endl;
608 for (
const char ** f = index; *f; ++f )
617 pi( dbdir_r + master );
620 MIL <<
"Removing rpm4 database " << pi << endl;
626 pi( dbdir_r + v3backup );
629 MIL <<
"Removing converted rpm3 database backup " << pi << endl;
643 const char * master =
"packages.rpm";
644 const char * index[] =
646 "conflictsindex.rpm",
657 PathInfo pi( dbdir_r );
660 ERR <<
"Can't remove rpm3 database in non directory: " << dbdir_r << endl;
664 for (
const char ** f = index; *f; ++f )
673 #warning CHECK: compare vs existing v3 backup. notify root
674 pi( dbdir_r + master );
677 Pathname m( pi.path() );
682 Pathname b( m.extend(
"3" ) );
687 Pathname b( m.extend(
".deleted" ) );
697 MIL <<
"(Re)moved rpm3 database to " << pi << endl;
737 MIL <<
"Calling closeDatabase: " << *
this << endl;
768 MIL <<
"closeDatabase: " << *
this << endl;
799 MIL <<
"RpmDb::rebuildDatabase" << *
this << endl;
802 PathInfo dbMaster(
root() +
dbPath() +
"Packages" );
803 PathInfo dbMasterBackup( dbMaster.path().extend(
".y2backup" ) );
807 opts.push_back(
"--rebuilddb");
808 opts.push_back(
"-vv");
815 PathInfo newMaster(
root()
828 if ( ! report->progress( (100 * newMaster.size()) / dbMaster.size(),
root() +
dbPath()) )
830 WAR <<
"User requested abort." << endl;
836 if ( line.compare( 0, 2,
"D:" ) )
838 errmsg += line +
'\n';
846 if ( rpm_status != 0 )
864 void computeKeyRingSync( std::set<Edition> & rpmKeys_r, std::list<PublicKeyData> & zyppKeys_r )
875 void updateIf(
const Edition & rpmKey_r )
877 std::string keyRelease( rpmKey_r.
release() );
878 int comp = _release.compare( keyRelease );
882 _release.swap( keyRelease );
883 _inRpmKeys = &rpmKey_r;
884 _inZyppKeys =
nullptr;
885 if ( !keyRelease.empty() )
886 DBG <<
"Old key in Z: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
888 else if ( comp == 0 )
892 _inRpmKeys = &rpmKey_r;
896 DBG <<
"Old key in R: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
899 void updateIf(
const PublicKeyData & zyppKey_r )
901 std::string keyRelease( zyppKey_r.gpgPubkeyRelease() );
902 int comp = _release.compare( keyRelease );
906 _release.swap( keyRelease );
907 _inRpmKeys =
nullptr;
908 _inZyppKeys = &zyppKey_r;
909 if ( !keyRelease.empty() )
910 DBG <<
"Old key in R: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() <<
"-" << keyRelease << endl;
912 else if ( comp == 0 )
916 _inZyppKeys = &zyppKey_r;
920 DBG <<
"Old key in Z: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() <<
"-" << keyRelease << endl;
923 std::string _release;
924 const Edition * _inRpmKeys;
925 const PublicKeyData * _inZyppKeys;
930 std::map<std::string,Key> _keymap;
932 for_( it, rpmKeys_r.begin(), rpmKeys_r.end() )
934 _keymap[(*it).version()].updateIf( *it );
937 for_( it, zyppKeys_r.begin(), zyppKeys_r.end() )
939 _keymap[(*it).gpgPubkeyVersion()].updateIf( *it );
943 std::set<Edition> rpmKeys;
944 std::list<PublicKeyData> zyppKeys;
945 for_( it, _keymap.begin(), _keymap.end() )
947 DBG <<
"gpg-pubkey-" << (*it).first <<
"-" << (*it).second._release <<
" "
948 << ( (*it).second._inRpmKeys ?
"R" :
"_" )
949 << ( (*it).second._inZyppKeys ?
"Z" :
"_" ) << endl;
950 if ( ! (*it).second._inRpmKeys )
952 zyppKeys.push_back( *(*it).second._inZyppKeys );
954 if ( ! (*it).second._inZyppKeys )
956 rpmKeys.insert( *(*it).second._inRpmKeys );
959 rpmKeys_r.swap( rpmKeys );
960 zyppKeys_r.swap( zyppKeys );
967 MIL <<
"Going to sync trusted keys..." << endl;
969 std::list<PublicKeyData> zyppKeys( getZYpp()->keyRing()->trustedPublicKeyData() );
970 computeKeyRingSync( rpmKeys, zyppKeys );
971 MIL << (mode_r &
SYNC_TO_KEYRING ?
"" :
"(skip) ") <<
"Rpm keys to export into zypp trusted keyring: " << rpmKeys.size() << endl;
972 MIL << (mode_r &
SYNC_FROM_KEYRING ?
"" :
"(skip) ") <<
"Zypp trusted keys to import into rpm database: " << zyppKeys.size() << endl;
978 MIL <<
"Exporting rpm keyring into zypp trusted keyring" <<endl;
983 TmpFile tmpfile( getZYpp()->tmpPath() );
985 std::ofstream tmpos( tmpfile.
path().
c_str() );
986 for_( it, rpmKeys.begin(), rpmKeys.end() )
990 getData(
"gpg-pubkey", *it, result );
991 tmpos << result->tag_description() << endl;
996 getZYpp()->keyRing()->multiKeyImport( tmpfile.
path(),
true );
1000 ERR <<
"Could not import keys into in zypp keyring" << endl;
1008 MIL <<
"Importing zypp trusted keyring" << std::endl;
1009 for_( it, zyppKeys.begin(), zyppKeys.end() )
1013 importPubkey( getZYpp()->keyRing()->exportTrustedPublicKey( *it ) );
1021 MIL <<
"Trusted keys synced." << endl;
1043 WAR <<
"Key " << pubkey_r <<
" can not be imported. (READONLY MODE)" << endl;
1050 bool hasOldkeys =
false;
1052 for_( it, rpmKeys.begin(), rpmKeys.end() )
1059 if ( keyEd == *it && !pubkey_r.
hasSubkeys() )
1061 MIL <<
"Key " << pubkey_r <<
" is already in the rpm trusted keyring. (skip import)" << endl;
1065 if ( keyEd.version() != (*it).version() )
1068 if ( keyEd.release() < (*it).release() )
1070 MIL <<
"Key " << pubkey_r <<
" is older than one in the rpm trusted keyring. (skip import)" << endl;
1078 MIL <<
"Key " << pubkey_r <<
" will be imported into the rpm trusted keyring." << (hasOldkeys?
"(update)":
"(new)") << endl;
1084 std::string keyName(
"gpg-pubkey-" + keyEd.version() );
1086 opts.push_back (
"-e" );
1087 opts.push_back (
"--allmatches" );
1088 opts.push_back (
"--" );
1089 opts.push_back ( keyName.c_str() );
1102 ERR <<
"Failed to remove key " << pubkey_r <<
" from RPM trusted keyring (ignored)" << endl;
1106 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1112 opts.push_back (
"--import" );
1113 opts.push_back (
"--" );
1114 std::string pubkeypath( pubkey_r.
path().asString() );
1115 opts.push_back ( pubkeypath.c_str() );
1136 MIL <<
"Key " << pubkey_r <<
" imported in rpm trusted keyring." << endl;
1153 std::set<Edition>::const_iterator found_edition = rpm_keys.end();
1156 for_( it, rpm_keys.begin(), rpm_keys.end() )
1158 if ( (*it).version() == pubkeyVersion )
1166 if (found_edition == rpm_keys.end())
1168 WAR <<
"Key " << pubkey_r.
id() <<
" is not in rpm db" << endl;
1172 std::string rpm_name(
"gpg-pubkey-" + found_edition->asString());
1175 opts.push_back (
"-e" );
1176 opts.push_back (
"--" );
1177 opts.push_back ( rpm_name.c_str() );
1186 if ( line.substr( 0, 6 ) ==
"error:" )
1188 WAR << line << endl;
1192 DBG << line << endl;
1198 if ( rpm_status != 0 )
1207 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1219 std::list<PublicKey> ret;
1222 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1224 Edition edition = it->tag_edition();
1229 getData(
"gpg-pubkey", edition, result );
1230 TmpFile file(getZYpp()->tmpPath());
1236 os << result->tag_description();
1245 catch ( std::exception & e )
1247 ERR <<
"Could not dump key " << edition.
asString() <<
" in tmp file " << file.
path() << endl;
1257 std::set<Edition> ret;
1260 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1262 Edition edition = it->tag_edition();
1264 ret.insert( edition );
1281 std::list<FileInfo> result;
1316 if (!name_r.empty())
1318 res = (it->tag_name() == name_r);
1339 return it->tag_name();
1453 struct RpmlogCapture :
public std::string
1456 { rpmlog()._cap =
this; }
1459 { rpmlog()._cap =
nullptr; }
1467 rpmlogSetCallback( rpmLogCB,
this );
1468 rpmSetVerbosity( RPMLOG_INFO );
1469 _f = ::fopen(
"/dev/null",
"w");
1470 rpmlogSetFile(
_f );
1474 {
if (
_f ) ::fclose(
_f ); }
1476 static int rpmLogCB( rpmlogRec rec_r, rpmlogCallbackData data_r )
1477 {
return reinterpret_cast<Rpmlog*
>(data_r)->rpmLog( rec_r ); }
1479 int rpmLog( rpmlogRec rec_r )
1481 if (
_cap ) (*_cap) = rpmlogRecMessage( rec_r );
1482 return RPMLOG_DEFAULT;
1489 static Rpmlog & rpmlog()
1490 {
static Rpmlog _rpmlog;
return _rpmlog; }
1495 bool requireGPGSig_r,
1496 RpmDb::CheckPackageDetail & detail_r )
1499 if ( ! file.isFile() )
1501 ERR <<
"Not a file: " << file << endl;
1505 FD_t fd = ::Fopen( file.asString().c_str(),
"r.ufdio" );
1506 if ( fd == 0 || ::Ferror(fd) )
1508 ERR <<
"Can't open file for reading: " << file <<
" (" << ::Fstrerror(fd) <<
")" << endl;
1513 rpmts ts = ::rpmtsCreate();
1514 ::rpmtsSetRootDir( ts, root_r.
c_str() );
1515 ::rpmtsSetVSFlags( ts, RPMVSF_DEFAULT );
1517 rpmQVKArguments_s qva;
1518 memset( &qva, 0,
sizeof(rpmQVKArguments_s) );
1519 qva.qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE);
1521 RpmlogCapture vresult;
1522 LocaleGuard guard( LC_ALL,
"C" );
1523 int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.
basename().c_str() );
1536 std::vector<std::string> lines;
1537 str::split( vresult, std::back_inserter(lines),
"\n" );
1538 unsigned count[7] = { 0, 0, 0, 0, 0, 0, 0 };
1540 for (
unsigned i = 1; i < lines.size(); ++i )
1542 std::string & line( lines[i] );
1544 if ( line.find(
": OK" ) != std::string::npos )
1547 if ( line.find(
"Signature, key ID" ) == std::string::npos )
1550 else if ( line.find(
": NOKEY" ) != std::string::npos )
1552 else if ( line.find(
": BAD" ) != std::string::npos )
1554 else if ( line.find(
": UNKNOWN" ) != std::string::npos )
1556 else if ( line.find(
": NOTRUSTED" ) != std::string::npos )
1560 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( lineres, std::move(line) ) );
1581 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( RpmDb::CHK_NOSIG, std::string(
" ")+
_(
"Package is not signed!") ) );
1582 if ( requireGPGSig_r )
1589 WAR << path_r <<
" (" << requireGPGSig_r <<
" -> " << ret <<
")" << endl;
1602 {
return doCheckPackageSig( path_r,
root(),
false, detail_r ); }
1608 {
return doCheckPackageSig( path_r,
root(),
true, detail_r ); }
1623 opts.push_back (
"-V");
1624 opts.push_back (
"--nodeps");
1625 opts.push_back (
"--noscripts");
1626 opts.push_back (
"--nomd5");
1627 opts.push_back (
"--");
1628 opts.push_back (packageName.c_str());
1649 if (line.length() > 12 &&
1650 (line[0] ==
'S' || line[0] ==
's' ||
1651 (line[0] ==
'.' && line[7] ==
'T')))
1654 std::string filename;
1656 filename.assign(line, 11, line.length() - 11);
1657 fileList.insert(filename);
1697 #if defined(WORKAROUNDRPMPWDBUG)
1698 args.push_back(
"#/");
1700 args.push_back(
"rpm");
1701 args.push_back(
"--root");
1702 args.push_back(
_root.asString().c_str());
1703 args.push_back(
"--dbpath");
1704 args.push_back(
_dbPath.asString().c_str());
1706 const char* argv[args.size() + opts.size() + 1];
1708 const char** p = argv;
1709 p =
copy (args.begin (), args.end (), p);
1710 p =
copy (opts.begin (), opts.end (), p);
1736 int inputfileFd = ::fileno( inputfile );
1742 FD_SET( inputfileFd, &rfds );
1749 int retval = select( inputfileFd+1, &rfds, NULL, NULL, &tv );
1753 ERR <<
"select error: " <<
strerror(errno) << endl;
1754 if ( errno != EINTR )
1760 static size_t linebuffer_size = 0;
1761 static char * linebuffer = 0;
1762 ssize_t nread =
getline( &linebuffer, &linebuffer_size, inputfile );
1765 if ( ::feof( inputfile ) )
1772 if ( linebuffer[nread-1] ==
'\n' )
1774 line += std::string( linebuffer, nread );
1777 if ( ! ::ferror( inputfile ) || ::feof( inputfile ) )
1780 clearerr( inputfile );
1829 void RpmDb::processConfigFiles(
const std::string& line,
const std::string& name,
const char* typemsg,
const char* difffailmsg,
const char* diffgenmsg)
1831 std::string msg = line.substr(9);
1834 std::string file1s, file2s;
1838 pos1 = msg.find (typemsg);
1841 if ( pos1 == std::string::npos )
1844 pos2 = pos1 + strlen (typemsg);
1846 if (pos2 >= msg.length() )
1849 file1 = msg.substr (0, pos1);
1850 file2 = msg.substr (pos2);
1852 file1s = file1.asString();
1853 file2s = file2.asString();
1857 file1 =
_root + file1;
1858 file2 =
_root + file2;
1862 int ret =
diffFiles (file1.asString(), file2.asString(), out, 25);
1868 ERR <<
"Could not create " << file.asString() << endl;
1872 std::ofstream notify(file.asString().c_str(), std::ios::out|std::ios::app);
1875 ERR <<
"Could not open " << file << endl;
1881 notify <<
str::form(
_(
"Changed configuration files for %s:"), name.c_str()) << endl;
1884 ERR <<
"diff failed" << endl;
1886 file1s.c_str(), file2s.c_str()) << endl;
1891 file1s.c_str(), file2s.c_str()) << endl;
1896 if (out.substr(0,4) ==
"--- ")
1898 out.replace(4, file1.asString().length(), file1s);
1901 if (pos != std::string::npos)
1903 out.replace(pos+5, file2.asString().length(), file2s);
1906 notify << out << endl;
1909 notify.open(
"/var/lib/update-messages/yast2-packagemanager.rpmdb.configfiles");
1914 WAR <<
"rpm created " << file2 <<
" but it is not different from " << file2 << endl;
1930 report->start(filename);
1945 report->finish( excpt_r );
1961 MIL <<
"RpmDb::installPackage(" << filename <<
"," << flags <<
")" << endl;
1970 ERR <<
"backup of " << filename.asString() <<
" failed" << endl;
1973 report->progress( 0 );
1979 opts.push_back(
"-i");
1981 opts.push_back(
"-U");
1983 opts.push_back(
"--percent");
1984 opts.push_back(
"--noglob");
1988 opts.push_back(
"--ignorearch");
1991 opts.push_back(
"--nodigest");
1993 opts.push_back(
"--nosignature");
1995 opts.push_back (
"--excludedocs");
1997 opts.push_back (
"--noscripts");
1999 opts.push_back (
"--force");
2001 opts.push_back (
"--nodeps");
2003 opts.push_back (
"--ignoresize");
2005 opts.push_back (
"--justdb");
2007 opts.push_back (
"--test");
2009 opts.push_back (
"--noposttrans");
2011 opts.push_back(
"--");
2014 std::string quotedFilename( rpmQuoteFilename( workaroundRpmPwdBug( filename ) ) );
2015 opts.push_back ( quotedFilename.c_str() );
2022 std::vector<std::string> configwarnings;
2024 unsigned linecnt = 0;
2032 if (line.substr(0,2)==
"%%")
2035 sscanf (line.c_str () + 2,
"%d", &percent);
2036 report->progress( percent );
2039 rpmmsg += line+
'\n';
2041 if ( line.substr(0,8) ==
"warning:" )
2043 configwarnings.push_back(line);
2047 rpmmsg +=
"[truncated]\n";
2052 for (std::vector<std::string>::iterator it = configwarnings.begin();
2053 it != configwarnings.end(); ++it)
2057 _(
"rpm saved %s as %s, but it was impossible to determine the difference"),
2059 _(
"rpm saved %s as %s.\nHere are the first 25 lines of difference:\n"));
2062 _(
"rpm created %s as %s, but it was impossible to determine the difference"),
2064 _(
"rpm created %s as %s.\nHere are the first 25 lines of difference:\n"));
2067 if ( rpm_status != 0 )
2070 str::form(
"%s install failed", Pathname::basename(filename).c_str()),
2072 std::ostringstream sstr;
2073 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2074 historylog.
comment(sstr.str());
2078 else if ( ! rpmmsg.empty() )
2081 str::form(
"%s installed ok", Pathname::basename(filename).c_str()),
2083 std::ostringstream sstr;
2084 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2085 historylog.
comment(sstr.str());
2089 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2103 +
"-" + package->edition().version()
2104 +
"-" + package->edition().release()
2105 +
"." + package->arch().asString(), flags );
2118 report->start( name_r );
2133 report->finish( excpt_r );
2150 MIL <<
"RpmDb::doRemovePackage(" << name_r <<
"," << flags <<
")" << endl;
2159 ERR <<
"backup of " << name_r <<
" failed" << endl;
2161 report->progress( 0 );
2165 report->progress( 100 );
2170 opts.push_back(
"-e");
2171 opts.push_back(
"--allmatches");
2174 opts.push_back(
"--noscripts");
2176 opts.push_back(
"--nodeps");
2178 opts.push_back(
"--justdb");
2180 opts.push_back (
"--test");
2183 WAR <<
"IGNORE OPTION: 'rpm -e' does not support '--force'" << endl;
2186 opts.push_back(
"--");
2187 opts.push_back(name_r.c_str());
2199 report->progress( 5 );
2200 unsigned linecnt = 0;
2207 rpmmsg += line+
'\n';
2210 rpmmsg +=
"[truncated]\n";
2211 report->progress( 50 );
2214 if ( rpm_status != 0 )
2217 str::form(
"%s remove failed", name_r.c_str()),
true );
2218 std::ostringstream sstr;
2219 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2220 historylog.
comment(sstr.str());
2224 else if ( ! rpmmsg.empty() )
2227 str::form(
"%s removed ok", name_r.c_str()),
true );
2229 std::ostringstream sstr;
2230 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2231 historylog.
comment(sstr.str());
2235 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2264 Pathname backupFilename;
2269 INT <<
"_backuppath empty" << endl;
2277 ERR <<
"Error while getting changed files for package " <<
2278 packageName << endl;
2282 if (fileList.size() <= 0)
2284 DBG <<
"package " << packageName <<
" not changed -> no backup" << endl;
2296 struct tm *currentLocalTime = localtime(¤tTime);
2298 int date = (currentLocalTime->tm_year + 1900) * 10000
2299 + (currentLocalTime->tm_mon + 1) * 100
2300 + currentLocalTime->tm_mday;
2306 +
str::form(
"%s-%d-%d.tar.gz",packageName.c_str(), date, num);
2309 while ( PathInfo(backupFilename).isExist() && num++ < 1000);
2311 PathInfo pi(filestobackupfile);
2312 if (pi.isExist() && !pi.isFile())
2314 ERR << filestobackupfile.asString() <<
" already exists and is no file" << endl;
2318 std::ofstream fp ( filestobackupfile.asString().c_str(), std::ios::out|std::ios::trunc );
2322 ERR <<
"could not open " << filestobackupfile.asString() << endl;
2326 for (FileList::const_iterator cit = fileList.begin();
2327 cit != fileList.end(); ++cit)
2329 std::string name = *cit;
2330 if ( name[0] ==
'/' )
2333 name = name.substr( 1 );
2335 DBG <<
"saving file "<< name << endl;
2340 const char*
const argv[] =
2345 _root.asString().c_str(),
2346 "--ignore-failed-read",
2348 backupFilename.asString().c_str(),
2350 filestobackupfile.asString().c_str(),
2366 int ret = tar.
close();
2370 ERR <<
"tar failed: " << tarmsg << endl;
2375 MIL <<
"tar backup ok" << endl;
2377 str::form(
_(
"created backup %s"), backupFilename.asString().c_str())
2396 #define OUTS(E,S) case RpmDb::E: return str << "["<< (unsigned)obj << "-"<< S << "]"; break
2398 OUTS( CHK_OK,
_(
"Signature is OK") );
2400 OUTS( CHK_NOTFOUND,
_(
"Unknown type of signature") );
2402 OUTS( CHK_FAIL,
_(
"Signature does not verify") );
2404 OUTS( CHK_NOTTRUSTED,
_(
"Signature is OK, but key is not trusted") );
2406 OUTS( CHK_NOKEY,
_(
"Signatures public key is not available") );
2408 OUTS( CHK_ERROR,
_(
"File does not exist or signature can't be checked") );
2410 OUTS( CHK_NOSIG,
_(
"File is unsigned") );
2413 return str <<
"UnknowSignatureCheckError("+
str::numstring(obj)+
")";
2418 for (
const auto & el : obj )
2419 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)
bool hasDbV3ToV4() const
Whether dbV3ToV4 file exists.
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 hasPackage(const std::string &name_r) const
Return true if package is installed.
static unsigned blockAccess()
Blocks further access to rpmdb.
std::string basename() const
Return the last component of this path.
static std::ostream & dumpState(std::ostream &str)
Dump debug info.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
bool hasProvides(const std::string &tag_r) const
Return true if at least one package provides a certain tag.
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.
std::string release() const
Release.
void getData(const std::string &name_r, RpmHeader::constPtr &result_r) const
Get an installed packages data from rpmdb.
bool hasSubkeys() const
!<
const std::string & asString() const
String representation.
const std::string & execError() const
Some detail telling why the execution failed, if it failed.
Collect info about what kind of rpmdb seems to be present by looking at paths and filenames...
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
std::string asString() const
void internal_initDatabase(const Pathname &root_r, const Pathname &dbPath_r, DbStateInfoBits &info_r)
Internal helper for initDatabase.
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.
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Edition represents [epoch:]version[-release]
bool relative() const
Test for a relative path.
bool running()
Return whether program is running.
bool illegalArgs() const
Whether constructor arguments were illegal.
bool hasConflicts(const std::string &tag_r) const
Return true if at least one package conflicts with a certain tag.
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')
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...
#define FILEFORBACKUPFILES
Subclass to retrieve database content.
Temporarily connect a ReceiveReport then restore the previous one.
std::string gpgPubkeyVersion() const
bool hasDbV4() const
Whether dbV4 file exists.
void importPubkey(const PublicKey &pubkey_r)
Import ascii armored public key in file pubkey_r.
void systemKill()
Forcably kill the system process.
bool dbsi_has(const DbStateInfoBits &val_r, const unsigned &bits_r) const
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
void syncTrustedKeys(SyncTrustedKeyBits mode_r=SYNC_BOTH)
Sync trusted keys stored in rpm database and zypp trusted keyring.
#define FAILIFNOTINITIALIZED
Pathname path() const
File containig the ASCII armored key.
std::string getline(std::istream &str)
Read one line from stream.
virtual std::ostream & dumpOn(std::ostream &str) const
Dump debug info.
Store and operate on date (time_t).
Pathname _backuppath
/var/adm/backup
const PathInfo & dbV3ToV4() const
rpmV3 database backup created on conversion to rpmV4 (_dbDir/packages.rpm3)
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t")
Split line_r into words.
int exit_code
The exit code of the rpm process, or -1 if not yet known.
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
int unlink(const Pathname &path)
Like 'unlink'.
std::string asString() const
shared_ptr< RpmException > dbError() const
Return any database error.
SyncTrustedKeyBits
Sync mode for syncTrustedKeys.
bool systemReadLine(std::string &line)
Read a line from the general rpm query.
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...
bool findByName(const std::string &name_r)
Reset to iterate all packages with a certain name.
const char * c_str() const
String representation.
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
Detailed rpm signature check log messages A single multiline message if CHK_OK.
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
static unsigned dbRelease(bool force_r=false)
If there are no outstanding references to the database (e.g.
static shared_ptr< KeyRingSignalReceiver > sKeyRingReceiver
bool hasDbV3() const
Whether dbV3 file exists.
std::string version() const
Version.
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)
std::set< Edition > pubkeyEditions() const
Return the edition of all installed public keys.
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.
const Pathname & root() const
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.
Just inherits Exception to separate media exceptions.
FILE * inputFile() const
Return the input stream.
std::string numstring(char n, int w=0)
export rpm trusted keys into zypp trusted keyring
virtual void trustedKeyRemoved(const PublicKey &key)
bool findPackage(const std::string &name_r)
Find package by name.
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'.
const PathInfo & dbV4() const
rpmV4 database (_dbDir/Packages)
bool _packagebackups
create package backups?
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
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).
void doRemovePackage(const std::string &name_r, RpmInstFlags flags, callback::SendReport< RpmRemoveReport > &report)
Base class for Exception.
std::string form(const std::string &format_r) const
Return string representation according to format as localtime.
void setBackupPath(const Pathname &path)
set path where package backups are stored
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.
void removePackage(const std::string &name_r, RpmInstFlags flags=RPMINST_NONE)
remove rpm package
static bool globalInit()
Initialize lib librpm (read configfiles etc.).
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).
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
Date timestamp() const
timestamp of the rpm database (last modification)
const Pathname & dbPath() const
bool findByConflicts(const std::string &tag_r)
Reset to iterate all packages that conflict with a certain tag.
Wrapper class for ::stat/::lstat.
const PathInfo & dbDir() const
database directory (unset on illegal constructor arguments)
void setBlocking(bool mode)
Set the blocking mode of the input stream.
CheckPackageResult
checkPackage result
std::list< PublicKey > pubkeys() const
Return the long ids of all installed public keys.
void dbsi_set(DbStateInfoBits &val_r, const unsigned &bits_r) const
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.
void dbsi_clr(DbStateInfoBits &val_r, const unsigned &bits_r) const
static void removeV4(const Pathname &dbdir_r, bool v3backup_r)
Remove the rpm4 database in dbdir_r and optionally any backup created on conversion.
std::string strerror(int errno_r)
Return string describing the error_r code.
std::ostream & operator<<(std::ostream &str, const Glob &obj)
bool usableArgs() const
Whether constructor arguments were llegal and dbDir either is a directory or may be created (path doe...
const PathInfo & dbV3() const
rpmV3 database (_dbDir/packages.rpm)
intrusive_ptr< const librpmDb > constPtr
std::string gpgPubkeyRelease() const
void run_rpm(const RpmArgVec &options, ExternalProgram::Stderr_Disposition stderr_disp=ExternalProgram::Stderr_To_Stdout)
Run rpm with the specified arguments and handle stderr.
KeyRingSignalReceiver(RpmDb &rpmdb)
void restat()
Restat all paths.
TraitsType::constPtrType constPtr
#define MAXRPMMESSAGELINES
std::string whoOwnsFile(const std::string &file_r) const
Return name of package owning file or empty string if no installed package owns file.
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
std::vector< const char * > RpmArgVec