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 qva.qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE);
1564 RpmlogCapture vresult;
1565 LocaleGuard guard( LC_ALL,
"C" );
1566 int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.
basename().c_str() );
1579 std::vector<std::string> lines;
1580 str::split( vresult, std::back_inserter(lines),
"\n" );
1581 unsigned count[7] = { 0, 0, 0, 0, 0, 0, 0 };
1583 for (
unsigned i = 1; i < lines.size(); ++i )
1585 std::string & line( lines[i] );
1587 if ( line.find(
": OK" ) != std::string::npos )
1590 if ( line.find(
"Signature, key ID" ) == std::string::npos )
1593 else if ( line.find(
": NOKEY" ) != std::string::npos )
1595 else if ( line.find(
": BAD" ) != std::string::npos )
1597 else if ( line.find(
": UNKNOWN" ) != std::string::npos )
1599 else if ( line.find(
": NOTRUSTED" ) != std::string::npos )
1603 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( lineres, std::move(line) ) );
1624 detail_r.push_back( RpmDb::CheckPackageDetail::value_type(
RpmDb::CHK_NOSIG, std::string(
" ")+
_(
"Package is not signed!") ) );
1625 if ( requireGPGSig_r )
1632 WAR << path_r <<
" (" << requireGPGSig_r <<
" -> " << ret <<
")" << endl;
1645 {
return doCheckPackageSig( path_r,
root(),
false, detail_r ); }
1651 {
return doCheckPackageSig( path_r,
root(),
true, detail_r ); }
1666 opts.push_back (
"-V");
1667 opts.push_back (
"--nodeps");
1668 opts.push_back (
"--noscripts");
1669 opts.push_back (
"--nomd5");
1670 opts.push_back (
"--");
1671 opts.push_back (packageName.c_str());
1692 if (line.length() > 12 &&
1693 (line[0] ==
'S' || line[0] ==
's' ||
1694 (line[0] ==
'.' && line[7] ==
'T')))
1697 std::string filename;
1699 filename.assign(line, 11, line.length() - 11);
1740 #if defined(WORKAROUNDRPMPWDBUG) 1741 args.push_back(
"#/");
1743 args.push_back(
"rpm");
1744 args.push_back(
"--root");
1746 args.push_back(
"--dbpath");
1749 const char* argv[args.size() + opts.size() + 1];
1751 const char** p = argv;
1752 p =
copy (args.begin (), args.end (), p);
1753 p =
copy (opts.begin (), opts.end (), p);
1779 int inputfileFd = ::fileno( inputfile );
1785 FD_SET( inputfileFd, &rfds );
1792 int retval = select( inputfileFd+1, &rfds, NULL, NULL, &tv );
1796 ERR <<
"select error: " <<
strerror(errno) << endl;
1797 if ( errno != EINTR )
1803 static size_t linebuffer_size = 0;
1804 static char * linebuffer = 0;
1805 ssize_t nread =
getline( &linebuffer, &linebuffer_size, inputfile );
1808 if ( ::feof( inputfile ) )
1815 if ( linebuffer[nread-1] ==
'\n' )
1817 line += std::string( linebuffer, nread );
1820 if ( ! ::ferror( inputfile ) || ::feof( inputfile ) )
1823 clearerr( inputfile );
1872 void RpmDb::processConfigFiles(
const std::string& line,
const std::string& name,
const char* typemsg,
const char* difffailmsg,
const char* diffgenmsg)
1874 std::string msg = line.substr(9);
1877 std::string file1s, file2s;
1881 pos1 = msg.find (typemsg);
1884 if ( pos1 == std::string::npos )
1887 pos2 = pos1 + strlen (typemsg);
1889 if (pos2 >= msg.length() )
1892 file1 = msg.substr (0, pos1);
1893 file2 = msg.substr (pos2);
1900 file1 =
_root + file1;
1901 file2 =
_root + file2;
1911 ERR <<
"Could not create " << file.
asString() << endl;
1915 std::ofstream notify(file.
asString().c_str(), std::ios::out|std::ios::app);
1918 ERR <<
"Could not open " << file << endl;
1924 notify <<
str::form(
_(
"Changed configuration files for %s:"), name.c_str()) << endl;
1927 ERR <<
"diff failed" << endl;
1929 file1s.c_str(), file2s.c_str()) << endl;
1934 file1s.c_str(), file2s.c_str()) << endl;
1939 if (out.substr(0,4) ==
"--- ")
1941 out.replace(4, file1.
asString().length(), file1s);
1944 if (pos != std::string::npos)
1946 out.replace(pos+5, file2.
asString().length(), file2s);
1949 notify << out << endl;
1952 notify.open(
"/var/lib/update-messages/yast2-packagemanager.rpmdb.configfiles");
1957 WAR <<
"rpm created " << file2 <<
" but it is not different from " << file2 << endl;
1988 report->finish( excpt_r );
2004 MIL <<
"RpmDb::installPackage(" << filename <<
"," << flags <<
")" << endl;
2013 ERR <<
"backup of " << filename.
asString() <<
" failed" << endl;
2022 opts.push_back(
"-i");
2024 opts.push_back(
"-U");
2026 opts.push_back(
"--percent");
2027 opts.push_back(
"--noglob");
2031 opts.push_back(
"--ignorearch");
2034 opts.push_back(
"--nodigest");
2036 opts.push_back(
"--nosignature");
2038 opts.push_back (
"--excludedocs");
2040 opts.push_back (
"--noscripts");
2042 opts.push_back (
"--force");
2044 opts.push_back (
"--nodeps");
2046 opts.push_back (
"--ignoresize");
2048 opts.push_back (
"--justdb");
2050 opts.push_back (
"--test");
2052 opts.push_back (
"--noposttrans");
2054 opts.push_back(
"--");
2057 std::string quotedFilename( rpmQuoteFilename( workaroundRpmPwdBug( filename ) ) );
2058 opts.push_back ( quotedFilename.c_str() );
2065 std::vector<std::string> configwarnings;
2067 unsigned linecnt = 0;
2073 sscanf( line.c_str() + 2,
"%d", &percent );
2074 report->progress( percent );
2080 else if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2083 rpmmsg += line+
'\n';
2086 configwarnings.push_back(line);
2089 rpmmsg +=
"[truncated]\n";
2094 for (std::vector<std::string>::iterator it = configwarnings.begin();
2095 it != configwarnings.end(); ++it)
2099 _(
"rpm saved %s as %s, but it was impossible to determine the difference"),
2101 _(
"rpm saved %s as %s.\nHere are the first 25 lines of difference:\n"));
2104 _(
"rpm created %s as %s, but it was impossible to determine the difference"),
2106 _(
"rpm created %s as %s.\nHere are the first 25 lines of difference:\n"));
2109 if ( rpm_status != 0 )
2114 std::ostringstream sstr;
2115 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2116 historylog.
comment(sstr.str());
2120 else if ( ! rpmmsg.empty() )
2125 std::ostringstream sstr;
2126 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2127 historylog.
comment(sstr.str());
2131 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2145 +
"-" + package->edition().version()
2146 +
"-" + package->edition().release()
2147 +
"." + package->arch().asString(), flags );
2175 report->finish( excpt_r );
2192 MIL <<
"RpmDb::doRemovePackage(" << name_r <<
"," << flags <<
")" << endl;
2201 ERR <<
"backup of " << name_r <<
" failed" << endl;
2212 opts.push_back(
"-e");
2213 opts.push_back(
"--allmatches");
2216 opts.push_back(
"--noscripts");
2218 opts.push_back(
"--nodeps");
2220 opts.push_back(
"--justdb");
2222 opts.push_back (
"--test");
2225 WAR <<
"IGNORE OPTION: 'rpm -e' does not support '--force'" << endl;
2228 opts.push_back(
"--");
2229 opts.push_back(name_r.c_str());
2242 unsigned linecnt = 0;
2247 else if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2249 rpmmsg += line+
'\n';
2252 rpmmsg +=
"[truncated]\n";
2256 if ( rpm_status != 0 )
2259 str::form(
"%s remove failed", name_r.c_str()),
true );
2260 std::ostringstream sstr;
2261 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2262 historylog.
comment(sstr.str());
2266 else if ( ! rpmmsg.empty() )
2269 str::form(
"%s removed ok", name_r.c_str()),
true );
2271 std::ostringstream sstr;
2272 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2273 historylog.
comment(sstr.str());
2277 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2311 INT <<
"_backuppath empty" << endl;
2319 ERR <<
"Error while getting changed files for package " <<
2320 packageName << endl;
2326 DBG <<
"package " << packageName <<
" not changed -> no backup" << endl;
2338 struct tm *currentLocalTime = localtime(&
currentTime);
2340 int date = (currentLocalTime->tm_year + 1900) * 10000
2341 + (currentLocalTime->tm_mon + 1) * 100
2342 + currentLocalTime->tm_mday;
2348 +
str::form(
"%s-%d-%d.tar.gz",packageName.c_str(), date, num);
2356 ERR << filestobackupfile.
asString() <<
" already exists and is no file" << endl;
2360 std::ofstream fp ( filestobackupfile.
asString().c_str(), std::ios::out|std::ios::trunc );
2364 ERR <<
"could not open " << filestobackupfile.
asString() << endl;
2368 for (FileList::const_iterator cit =
fileList.begin();
2371 std::string name = *cit;
2372 if ( name[0] ==
'/' )
2375 name = name.substr( 1 );
2377 DBG <<
"saving file "<< name << endl;
2382 const char*
const argv[] =
2388 "--ignore-failed-read",
2392 filestobackupfile.
asString().c_str(),
2408 int ret = tar.
close();
2412 ERR <<
"tar failed: " << tarmsg << endl;
2417 MIL <<
"tar backup ok" << endl;
2438 #define OUTS(E,S) case RpmDb::E: return str << "["<< (unsigned)obj << "-"<< S << "]"; break 2440 OUTS( CHK_OK,
_(
"Signature is OK") );
2442 OUTS( CHK_NOTFOUND,
_(
"Unknown type of signature") );
2444 OUTS( CHK_FAIL,
_(
"Signature does not verify") );
2446 OUTS( CHK_NOTTRUSTED,
_(
"Signature is OK, but key is not trusted") );
2448 OUTS( CHK_NOKEY,
_(
"Signatures public key is not available") );
2450 OUTS( CHK_ERROR,
_(
"File does not exist or signature can't be checked") );
2452 OUTS( CHK_NOSIG,
_(
"File is unsigned") );
2460 for (
const auto & el : obj )
2461 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