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 62 #undef ZYPP_BASE_LOGGER_LOGGROUP 63 #define ZYPP_BASE_LOGGER_LOGGROUP "librpmDb" 67 namespace zypp_readonly_hack
77 #if 1 // No more need to escape whitespace since rpm-4.4.2.3 78 const char* quoteInFilename_m =
"\'\"";
80 const char* quoteInFilename_m =
" \t\'\"";
82 inline std::string rpmQuoteFilename(
const Pathname & path_r )
84 std::string path( path_r.
asString() );
86 pos != std::string::npos;
87 pos = path.find_first_of( quoteInFilename_m, pos ) )
89 path.insert( pos,
"\\" );
102 #if defined(WORKAROUNDRPMPWDBUG) 106 AutoDispose<char*> cwd( ::get_current_dir_name(), ::free );
109 WAR <<
"Can't get cwd!" << endl;
130 MIL <<
"trusted key added to zypp Keyring. Importing..." << endl;
131 _rpmdb.importPubkey( key );
136 MIL <<
"Trusted key removed from zypp Keyring. Removing..." << endl;
137 _rpmdb.removePubkey( key );
145 unsigned diffFiles(
const std::string file1,
const std::string file2, std::string& out,
int maxlines)
166 if (maxlines<0?
true:count<maxlines)
194 if ( obj == RpmDb::DbSI_NO_INIT )
200 #define ENUM_OUT(B,C) str << ( obj & RpmDb::B ? C : '-' ) 223 #define FAILIFNOTINITIALIZED if( ! initialized() ) { ZYPP_THROW(RpmDbNotOpenException()); } 234 : _dbStateInfo( DbSI_NO_INIT )
235 #warning Check for obsolete memebers
236 , _backuppath (
"/var/adm/backup")
237 , _packagebackups(false)
238 , _warndirexists(false)
245 setenv(
"RPM_IgnoreFailedSymlinks",
"1", 1 );
257 MIL <<
"~RpmDb()" << endl;
260 MIL <<
"~RpmDb() end" << endl;
270 db_path =
"/var/lib/rpm";
277 return rpmdb_info.
mtime();
297 #define ENUM_OUT(B,C) str << ( _dbStateInfo & B ? C : '-' ) 323 bool quickinit( root_r.
empty() );
325 if ( root_r.
empty() )
328 if ( dbPath_r.
empty() )
329 dbPath_r =
"/var/lib/rpm";
333 ERR <<
"Illegal root or dbPath: " <<
stringPath( root_r, dbPath_r ) << endl;
337 if ( dbPath_r ==
"/var/lib/rpm" 338 && !
PathInfo( root_r/
"/var/lib/rpm" ).isExist()
339 &&
PathInfo( root_r/
"/usr/lib/sysimage/rpm" ).isDir() )
341 WAR <<
"Rpm package was deleted? Injecting missing rpmdb compat symlink." << endl;
345 MIL <<
"Calling initDatabase: " <<
stringPath( root_r, dbPath_r )
346 << ( doRebuild_r ?
" (rebuilddb)" :
"" )
347 << ( quickinit ?
" (quickinit)" :
"" ) << endl;
371 MIL <<
"QUICK initDatabase (no systemRoot set)" << endl;
384 ERR <<
"Cleanup on error: state " << info << endl;
399 MIL <<
"Cleanup: state " << info << endl;
408 MIL <<
"Update mode: Cleanup delayed until closeOldDatabase." << endl;
411 #warning CHECK: notify root about conversion backup. 426 MIL <<
"Synchronizing keys with zypp keyring" << endl;
435 MIL <<
"InitDatabase: " << *
this << endl;
461 ERR <<
"Bad database directory: " << dbInfo.
dbDir() << endl;
468 MIL <<
"Found rpm4 database in " << dbInfo.
dbDir() << endl;
472 MIL <<
"Creating new rpm4 database in " << dbInfo.
dbDir() << endl;
484 DBG <<
"Initial state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
503 DBG <<
"Access state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
512 bool dbEmpty = dbptr->empty();
515 MIL <<
"Empty rpm4 database " << dbInfo.
dbV4() << endl;
520 MIL <<
"Found rpm3 database " << dbInfo.
dbV3() << endl;
531 WAR <<
"Backup converted rpm3 database failed: error(" << res <<
")" << endl;
538 MIL <<
"Backup converted rpm3 database: " << dbInfo.
dbV3ToV4() << endl;
547 WAR <<
"Non empty rpm3 and rpm4 database found: using rpm4" << endl;
553 DBG <<
"Convert state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
559 MIL <<
"Rpm3 database backup: " << dbInfo.
dbV3ToV4() << endl;
571 const char * v3backup =
"packages.rpm3";
572 const char * master =
"Packages";
573 const char * index[] =
598 ERR <<
"Can't remove rpm4 database in non directory: " << dbdir_r << endl;
602 for (
const char ** f = index; *f; ++f )
611 pi( dbdir_r + master );
614 MIL <<
"Removing rpm4 database " << pi << endl;
620 pi( dbdir_r + v3backup );
623 MIL <<
"Removing converted rpm3 database backup " << pi << endl;
637 const char * master =
"packages.rpm";
638 const char * index[] =
640 "conflictsindex.rpm",
654 ERR <<
"Can't remove rpm3 database in non directory: " << dbdir_r << endl;
658 for (
const char ** f = index; *f; ++f )
667 #warning CHECK: compare vs existing v3 backup. notify root 668 pi( dbdir_r + master );
681 Pathname b( m.extend(
".deleted" ) );
691 MIL <<
"(Re)moved rpm3 database to " << pi << endl;
731 MIL <<
"Calling closeDatabase: " << *
this << endl;
762 MIL <<
"closeDatabase: " << *
this << endl;
793 MIL <<
"RpmDb::rebuildDatabase" << *
this << endl;
801 opts.push_back(
"--rebuilddb");
802 opts.push_back(
"-vv");
824 WAR <<
"User requested abort." << endl;
830 if ( line.compare( 0, 2,
"D:" ) )
832 errmsg += line +
'\n';
840 if ( rpm_status != 0 )
858 void computeKeyRingSync( std::set<Edition> & rpmKeys_r, std::list<PublicKeyData> & zyppKeys_r )
869 void updateIf(
const Edition & rpmKey_r )
871 std::string keyRelease( rpmKey_r.
release() );
872 int comp = _release.compare( keyRelease );
876 _release.swap( keyRelease );
877 _inRpmKeys = &rpmKey_r;
878 _inZyppKeys =
nullptr;
879 if ( !keyRelease.empty() )
880 DBG <<
"Old key in Z: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
882 else if ( comp == 0 )
886 _inRpmKeys = &rpmKey_r;
890 DBG <<
"Old key in R: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
893 void updateIf(
const PublicKeyData & zyppKey_r )
895 std::string keyRelease( zyppKey_r.gpgPubkeyRelease() );
896 int comp = _release.compare( keyRelease );
900 _release.swap( keyRelease );
901 _inRpmKeys =
nullptr;
902 _inZyppKeys = &zyppKey_r;
903 if ( !keyRelease.empty() )
904 DBG <<
"Old key in R: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() <<
"-" << keyRelease << endl;
906 else if ( comp == 0 )
910 _inZyppKeys = &zyppKey_r;
914 DBG <<
"Old key in Z: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() <<
"-" << keyRelease << endl;
917 std::string _release;
918 const Edition * _inRpmKeys;
919 const PublicKeyData * _inZyppKeys;
924 std::map<std::string,Key> _keymap;
926 for_( it, rpmKeys_r.begin(), rpmKeys_r.end() )
928 _keymap[(*it).version()].updateIf( *it );
931 for_( it, zyppKeys_r.begin(), zyppKeys_r.end() )
933 _keymap[(*it).gpgPubkeyVersion()].updateIf( *it );
937 std::set<Edition> rpmKeys;
938 std::list<PublicKeyData> zyppKeys;
939 for_( it, _keymap.begin(), _keymap.end() )
941 DBG <<
"gpg-pubkey-" << (*it).first <<
"-" << (*it).second._release <<
" " 942 << ( (*it).second._inRpmKeys ?
"R" :
"_" )
943 << ( (*it).second._inZyppKeys ?
"Z" :
"_" ) << endl;
944 if ( ! (*it).second._inRpmKeys )
946 zyppKeys.push_back( *(*it).second._inZyppKeys );
948 if ( ! (*it).second._inZyppKeys )
950 rpmKeys.insert( *(*it).second._inRpmKeys );
953 rpmKeys_r.swap( rpmKeys );
954 zyppKeys_r.swap( zyppKeys );
961 MIL <<
"Going to sync trusted keys..." << endl;
963 std::list<PublicKeyData> zyppKeys( getZYpp()->keyRing()->trustedPublicKeyData() );
975 MIL <<
"Removing excess keys in zypp trusted keyring" << std::endl;
981 if ( ! rpmKeys.count( keyData.gpgPubkeyEdition() ) )
983 DBG <<
"Excess key in Z to delete: gpg-pubkey-" << keyData.gpgPubkeyEdition() << endl;
984 getZYpp()->keyRing()->deleteKey( keyData.id(), true );
985 if ( !dirty ) dirty =
true;
989 zyppKeys = getZYpp()->keyRing()->trustedPublicKeyData();
992 computeKeyRingSync( rpmKeys, zyppKeys );
993 MIL << (mode_r &
SYNC_TO_KEYRING ?
"" :
"(skip) ") <<
"Rpm keys to export into zypp trusted keyring: " << rpmKeys.size() << endl;
994 MIL << (mode_r &
SYNC_FROM_KEYRING ?
"" :
"(skip) ") <<
"Zypp trusted keys to import into rpm database: " << zyppKeys.size() << endl;
1000 MIL <<
"Exporting rpm keyring into zypp trusted keyring" <<endl;
1005 TmpFile tmpfile( getZYpp()->tmpPath() );
1007 std::ofstream tmpos( tmpfile.
path().
c_str() );
1008 for_( it, rpmKeys.begin(), rpmKeys.end() )
1012 getData(
"gpg-pubkey", *it, result );
1013 tmpos << result->tag_description() << endl;
1018 getZYpp()->keyRing()->multiKeyImport( tmpfile.
path(),
true );
1022 std::set<Edition> missingKeys;
1023 for (
const Edition & key : rpmKeys )
1025 if ( getZYpp()->keyRing()->isKeyTrusted( key.version() ) )
1027 ERR <<
"Could not import key:" <<
str::Format(
"gpg-pubkey-%s") % key <<
" into zypp keyring (V3 key?)" << endl;
1028 missingKeys.insert( key );
1030 if ( ! missingKeys.empty() )
1036 ERR <<
"Could not import keys into zypp keyring: " << endl;
1044 MIL <<
"Importing zypp trusted keyring" << std::endl;
1045 for_( it, zyppKeys.begin(), zyppKeys.end() )
1049 importPubkey( getZYpp()->keyRing()->exportTrustedPublicKey( *it ) );
1057 MIL <<
"Trusted keys synced." << endl;
1079 WAR <<
"Key " << pubkey_r <<
" can not be imported. (READONLY MODE)" << endl;
1086 bool hasOldkeys =
false;
1088 for_( it, rpmKeys.begin(), rpmKeys.end() )
1095 if ( keyEd == *it && !pubkey_r.
hasSubkeys() )
1097 MIL <<
"Key " << pubkey_r <<
" is already in the rpm trusted keyring. (skip import)" << endl;
1101 if ( keyEd.version() != (*it).version() )
1104 if ( keyEd.release() < (*it).release() )
1106 MIL <<
"Key " << pubkey_r <<
" is older than one in the rpm trusted keyring. (skip import)" << endl;
1114 MIL <<
"Key " << pubkey_r <<
" will be imported into the rpm trusted keyring." << (hasOldkeys?
"(update)":
"(new)") << endl;
1120 std::string keyName(
"gpg-pubkey-" + keyEd.version() );
1122 opts.push_back (
"-e" );
1123 opts.push_back (
"--allmatches" );
1124 opts.push_back (
"--" );
1125 opts.push_back ( keyName.c_str() );
1138 ERR <<
"Failed to remove key " << pubkey_r <<
" from RPM trusted keyring (ignored)" << endl;
1142 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1148 opts.push_back (
"--import" );
1149 opts.push_back (
"--" );
1151 opts.push_back ( pubkeypath.c_str() );
1158 std::vector<std::string> excplines;
1163 WAR << line << endl;
1164 excplines.push_back( std::move(line) );
1167 DBG << line << endl;
1180 MIL <<
"Key " << pubkey_r <<
" imported in rpm trusted keyring." << endl;
1197 std::set<Edition>::const_iterator found_edition = rpm_keys.end();
1200 for_( it, rpm_keys.begin(), rpm_keys.end() )
1202 if ( (*it).version() == pubkeyVersion )
1210 if (found_edition == rpm_keys.end())
1212 WAR <<
"Key " << pubkey_r.
id() <<
" is not in rpm db" << endl;
1216 std::string rpm_name(
"gpg-pubkey-" + found_edition->asString());
1219 opts.push_back (
"-e" );
1220 opts.push_back (
"--" );
1221 opts.push_back ( rpm_name.c_str() );
1228 std::vector<std::string> excplines;
1233 WAR << line << endl;
1234 excplines.push_back( std::move(line) );
1237 DBG << line << endl;
1250 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1262 std::list<PublicKey> ret;
1265 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1267 Edition edition = it->tag_edition();
1272 getData(
"gpg-pubkey", edition, result );
1273 TmpFile file(getZYpp()->tmpPath());
1279 os << result->tag_description();
1288 catch ( std::exception & e )
1290 ERR <<
"Could not dump key " << edition.
asString() <<
" in tmp file " << file.
path() << endl;
1300 std::set<Edition> ret;
1303 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1305 Edition edition = it->tag_edition();
1307 ret.insert( edition );
1324 std::list<FileInfo> result;
1359 if (!name_r.empty())
1361 res = (it->tag_name() == name_r);
1382 return it->tag_name();
1496 struct RpmlogCapture :
public std::string
1499 { rpmlog()._cap =
this; }
1502 { rpmlog()._cap =
nullptr; }
1510 rpmlogSetCallback( rpmLogCB,
this );
1511 rpmSetVerbosity( RPMLOG_INFO );
1512 _f = ::fopen(
"/dev/null",
"w");
1513 rpmlogSetFile(
_f );
1517 {
if (
_f ) ::fclose(
_f ); }
1519 static int rpmLogCB( rpmlogRec rec_r, rpmlogCallbackData data_r )
1520 {
return reinterpret_cast<Rpmlog*
>(data_r)->rpmLog( rec_r ); }
1522 int rpmLog( rpmlogRec rec_r )
1524 if (
_cap ) (*_cap) += rpmlogRecMessage( rec_r );
1525 return RPMLOG_DEFAULT;
1532 static Rpmlog & rpmlog()
1533 {
static Rpmlog _rpmlog;
return _rpmlog; }
1538 bool requireGPGSig_r,
1539 RpmDb::CheckPackageDetail & detail_r )
1542 if ( ! file.isFile() )
1544 ERR <<
"Not a file: " << file << endl;
1548 FD_t fd = ::Fopen( file.asString().c_str(),
"r.ufdio" );
1549 if ( fd == 0 || ::Ferror(fd) )
1551 ERR <<
"Can't open file for reading: " << file <<
" (" << ::Fstrerror(fd) <<
")" << endl;
1556 rpmts ts = ::rpmtsCreate();
1557 ::rpmtsSetRootDir( ts, root_r.
c_str() );
1558 ::rpmtsSetVSFlags( ts, RPMVSF_DEFAULT );
1560 rpmQVKArguments_s qva;
1561 memset( &qva, 0,
sizeof(rpmQVKArguments_s) );
1562 #ifdef HAVE_NO_RPMTSSETVFYFLAGS 1565 qva.qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE);
1567 ::rpmtsSetVfyFlags( ts, RPMVSF_DEFAULT );
1569 RpmlogCapture vresult;
1570 LocaleGuard guard( LC_ALL,
"C" );
1571 int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.
basename().c_str() );
1584 std::vector<std::string> lines;
1585 str::split( vresult, std::back_inserter(lines),
"\n" );
1586 unsigned count[7] = { 0, 0, 0, 0, 0, 0, 0 };
1588 for (
unsigned i = 1; i < lines.size(); ++i )
1590 std::string & line( lines[i] );
1592 if ( line.find(
": OK" ) != std::string::npos )
1595 if ( line.find(
"Signature, key ID" ) == std::string::npos )
1598 else if ( line.find(
": NOKEY" ) != std::string::npos )
1600 else if ( line.find(
": BAD" ) != std::string::npos )
1602 else if ( line.find(
": UNKNOWN" ) != std::string::npos )
1604 else if ( line.find(
": NOTRUSTED" ) != std::string::npos )
1608 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( lineres, std::move(line) ) );
1629 detail_r.push_back( RpmDb::CheckPackageDetail::value_type(
RpmDb::CHK_NOSIG, std::string(
" ")+
_(
"Package is not signed!") ) );
1630 if ( requireGPGSig_r )
1637 WAR << path_r <<
" (" << requireGPGSig_r <<
" -> " << ret <<
")" << endl;
1650 {
return doCheckPackageSig( path_r,
root(),
false, detail_r ); }
1656 {
return doCheckPackageSig( path_r,
root(),
true, detail_r ); }
1671 opts.push_back (
"-V");
1672 opts.push_back (
"--nodeps");
1673 opts.push_back (
"--noscripts");
1674 opts.push_back (
"--nomd5");
1675 opts.push_back (
"--");
1676 opts.push_back (packageName.c_str());
1697 if (line.length() > 12 &&
1698 (line[0] ==
'S' || line[0] ==
's' ||
1699 (line[0] ==
'.' && line[7] ==
'T')))
1702 std::string filename;
1704 filename.assign(line, 11, line.length() - 11);
1745 #if defined(WORKAROUNDRPMPWDBUG) 1746 args.push_back(
"#/");
1748 args.push_back(
"rpm");
1749 args.push_back(
"--root");
1751 args.push_back(
"--dbpath");
1754 const char* argv[args.size() + opts.size() + 1];
1756 const char** p = argv;
1757 p =
copy (args.begin (), args.end (), p);
1758 p =
copy (opts.begin (), opts.end (), p);
1784 int inputfileFd = ::fileno( inputfile );
1790 FD_SET( inputfileFd, &rfds );
1797 int retval = select( inputfileFd+1, &rfds, NULL, NULL, &tv );
1801 ERR <<
"select error: " <<
strerror(errno) << endl;
1802 if ( errno != EINTR )
1808 static size_t linebuffer_size = 0;
1809 static char * linebuffer = 0;
1810 ssize_t nread =
getline( &linebuffer, &linebuffer_size, inputfile );
1813 if ( ::feof( inputfile ) )
1820 if ( linebuffer[nread-1] ==
'\n' )
1822 line += std::string( linebuffer, nread );
1825 if ( ! ::ferror( inputfile ) || ::feof( inputfile ) )
1828 clearerr( inputfile );
1877 void RpmDb::processConfigFiles(
const std::string& line,
const std::string& name,
const char* typemsg,
const char* difffailmsg,
const char* diffgenmsg)
1879 std::string msg = line.substr(9);
1882 std::string file1s, file2s;
1886 pos1 = msg.find (typemsg);
1889 if ( pos1 == std::string::npos )
1892 pos2 = pos1 + strlen (typemsg);
1894 if (pos2 >= msg.length() )
1897 file1 = msg.substr (0, pos1);
1898 file2 = msg.substr (pos2);
1905 file1 =
_root + file1;
1906 file2 =
_root + file2;
1916 ERR <<
"Could not create " << file.
asString() << endl;
1920 std::ofstream notify(file.
asString().c_str(), std::ios::out|std::ios::app);
1923 ERR <<
"Could not open " << file << endl;
1929 notify <<
str::form(
_(
"Changed configuration files for %s:"), name.c_str()) << endl;
1932 ERR <<
"diff failed" << endl;
1934 file1s.c_str(), file2s.c_str()) << endl;
1939 file1s.c_str(), file2s.c_str()) << endl;
1944 if (out.substr(0,4) ==
"--- ")
1946 out.replace(4, file1.
asString().length(), file1s);
1949 if (pos != std::string::npos)
1951 out.replace(pos+5, file2.
asString().length(), file2s);
1954 notify << out << endl;
1957 notify.open(
"/var/lib/update-messages/yast2-packagemanager.rpmdb.configfiles");
1962 WAR <<
"rpm created " << file2 <<
" but it is not different from " << file2 << endl;
1993 report->finish( excpt_r );
2009 MIL <<
"RpmDb::installPackage(" << filename <<
"," << flags <<
")" << endl;
2018 ERR <<
"backup of " << filename.
asString() <<
" failed" << endl;
2027 opts.push_back(
"-i");
2029 opts.push_back(
"-U");
2031 opts.push_back(
"--percent");
2032 opts.push_back(
"--noglob");
2036 opts.push_back(
"--ignorearch");
2039 opts.push_back(
"--nodigest");
2041 opts.push_back(
"--nosignature");
2043 opts.push_back (
"--excludedocs");
2045 opts.push_back (
"--noscripts");
2047 opts.push_back (
"--force");
2049 opts.push_back (
"--nodeps");
2051 opts.push_back (
"--ignoresize");
2053 opts.push_back (
"--justdb");
2055 opts.push_back (
"--test");
2057 opts.push_back (
"--noposttrans");
2059 opts.push_back(
"--");
2062 std::string quotedFilename( rpmQuoteFilename( workaroundRpmPwdBug( filename ) ) );
2063 opts.push_back ( quotedFilename.c_str() );
2070 std::vector<std::string> configwarnings;
2072 unsigned linecnt = 0;
2078 sscanf( line.c_str() + 2,
"%d", &percent );
2079 report->progress( percent );
2085 else if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2088 rpmmsg += line+
'\n';
2091 configwarnings.push_back(line);
2094 rpmmsg +=
"[truncated]\n";
2099 for (std::vector<std::string>::iterator it = configwarnings.begin();
2100 it != configwarnings.end(); ++it)
2104 _(
"rpm saved %s as %s, but it was impossible to determine the difference"),
2106 _(
"rpm saved %s as %s.\nHere are the first 25 lines of difference:\n"));
2109 _(
"rpm created %s as %s, but it was impossible to determine the difference"),
2111 _(
"rpm created %s as %s.\nHere are the first 25 lines of difference:\n"));
2114 if ( rpm_status != 0 )
2119 std::ostringstream sstr;
2120 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2121 historylog.
comment(sstr.str());
2125 else if ( ! rpmmsg.empty() )
2130 std::ostringstream sstr;
2131 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2132 historylog.
comment(sstr.str());
2136 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2150 +
"-" + package->edition().version()
2151 +
"-" + package->edition().release()
2152 +
"." + package->arch().asString(), flags );
2180 report->finish( excpt_r );
2197 MIL <<
"RpmDb::doRemovePackage(" << name_r <<
"," << flags <<
")" << endl;
2206 ERR <<
"backup of " << name_r <<
" failed" << endl;
2217 opts.push_back(
"-e");
2218 opts.push_back(
"--allmatches");
2221 opts.push_back(
"--noscripts");
2223 opts.push_back(
"--nodeps");
2225 opts.push_back(
"--justdb");
2227 opts.push_back (
"--test");
2230 WAR <<
"IGNORE OPTION: 'rpm -e' does not support '--force'" << endl;
2233 opts.push_back(
"--");
2234 opts.push_back(name_r.c_str());
2247 unsigned linecnt = 0;
2252 else if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2254 rpmmsg += line+
'\n';
2257 rpmmsg +=
"[truncated]\n";
2261 if ( rpm_status != 0 )
2264 str::form(
"%s remove failed", name_r.c_str()),
true );
2265 std::ostringstream sstr;
2266 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2267 historylog.
comment(sstr.str());
2271 else if ( ! rpmmsg.empty() )
2274 str::form(
"%s removed ok", name_r.c_str()),
true );
2276 std::ostringstream sstr;
2277 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2278 historylog.
comment(sstr.str());
2282 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2316 INT <<
"_backuppath empty" << endl;
2324 ERR <<
"Error while getting changed files for package " <<
2325 packageName << endl;
2331 DBG <<
"package " << packageName <<
" not changed -> no backup" << endl;
2343 struct tm *currentLocalTime = localtime(&
currentTime);
2345 int date = (currentLocalTime->tm_year + 1900) * 10000
2346 + (currentLocalTime->tm_mon + 1) * 100
2347 + currentLocalTime->tm_mday;
2353 +
str::form(
"%s-%d-%d.tar.gz",packageName.c_str(), date, num);
2361 ERR << filestobackupfile.
asString() <<
" already exists and is no file" << endl;
2365 std::ofstream fp ( filestobackupfile.
asString().c_str(), std::ios::out|std::ios::trunc );
2369 ERR <<
"could not open " << filestobackupfile.
asString() << endl;
2373 for (FileList::const_iterator cit =
fileList.begin();
2376 std::string name = *cit;
2377 if ( name[0] ==
'/' )
2380 name = name.substr( 1 );
2382 DBG <<
"saving file "<< name << endl;
2387 const char*
const argv[] =
2393 "--ignore-failed-read",
2397 filestobackupfile.
asString().c_str(),
2413 int ret = tar.
close();
2417 ERR <<
"tar failed: " << tarmsg << endl;
2422 MIL <<
"tar backup ok" << endl;
2443 #define OUTS(E,S) case RpmDb::E: return str << "["<< (unsigned)obj << "-"<< S << "]"; break 2445 OUTS( CHK_OK,
_(
"Signature is OK") );
2447 OUTS( CHK_NOTFOUND,
_(
"Unknown type of signature") );
2449 OUTS( CHK_FAIL,
_(
"Signature does not verify") );
2451 OUTS( CHK_NOTTRUSTED,
_(
"Signature is OK, but key is not trusted") );
2453 OUTS( CHK_NOKEY,
_(
"Signatures public key is not available") );
2455 OUTS( CHK_ERROR,
_(
"File does not exist or signature can't be checked") );
2457 OUTS( CHK_NOSIG,
_(
"File is unsigned") );
2465 for (
const auto & el : obj )
2466 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.
int symlink(const Pathname &oldpath, const Pathname &newpath)
Like 'symlink'.
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