15 #include <rpm/rpmcli.h> 16 #include <rpm/rpmlog.h> 55 #define WARNINGMAILPATH "/var/log/YaST2/" 56 #define FILEFORBACKUPFILES "YaSTBackupModifiedFiles" 57 #define MAXRPMMESSAGELINES 10000 59 #define WORKAROUNDRPMPWDBUG 63 namespace zypp_readonly_hack
73 #if 1 // No more need to escape whitespace since rpm-4.4.2.3 74 const char* quoteInFilename_m =
"\'\"";
76 const char* quoteInFilename_m =
" \t\'\"";
78 inline std::string rpmQuoteFilename(
const Pathname & path_r )
80 std::string path( path_r.asString() );
82 pos != std::string::npos;
83 pos = path.find_first_of( quoteInFilename_m, pos ) )
85 path.insert( pos,
"\\" );
96 inline Pathname workaroundRpmPwdBug( Pathname path_r )
98 #if defined(WORKAROUNDRPMPWDBUG) 99 if ( path_r.relative() )
104 return Pathname( cwd ) / path_r;
105 WAR <<
"Can't get cwd!" << endl;
126 MIL <<
"trusted key added to zypp Keyring. Importing..." << endl;
127 _rpmdb.importPubkey( key );
132 MIL <<
"Trusted key removed from zypp Keyring. Removing..." << endl;
133 _rpmdb.removePubkey( key );
141 unsigned diffFiles(
const std::string file1,
const std::string file2, std::string& out,
int maxlines)
162 if (maxlines<0?
true:count<maxlines)
177 inline std::string
stringPath(
const Pathname & root_r,
const Pathname & sub_r )
190 if ( obj == RpmDb::DbSI_NO_INIT )
196 #define ENUM_OUT(B,C) str << ( obj & RpmDb::B ? C : '-' ) 219 #define FAILIFNOTINITIALIZED if( ! initialized() ) { ZYPP_THROW(RpmDbNotOpenException()); } 230 : _dbStateInfo( DbSI_NO_INIT )
231 #warning Check for obsolete memebers
232 , _backuppath (
"/var/adm/backup")
233 , _packagebackups(false)
234 , _warndirexists(false)
241 setenv(
"RPM_IgnoreFailedSymlinks",
"1", 1 );
253 MIL <<
"~RpmDb()" << endl;
256 MIL <<
"~RpmDb() end" << endl;
257 sKeyRingReceiver.reset();
266 db_path =
"/var/lib/rpm";
270 PathInfo rpmdb_info(
root() + db_path +
"/Packages");
272 if ( rpmdb_info.isExist() )
273 return rpmdb_info.mtime();
293 #define ENUM_OUT(B,C) str << ( _dbStateInfo & B ? C : '-' ) 319 bool quickinit( root_r.empty() );
321 if ( root_r.empty() )
324 if ( dbPath_r.empty() )
325 dbPath_r =
"/var/lib/rpm";
327 if ( ! (root_r.absolute() && dbPath_r.absolute()) )
329 ERR <<
"Illegal root or dbPath: " <<
stringPath( root_r, dbPath_r ) << endl;
333 MIL <<
"Calling initDatabase: " <<
stringPath( root_r, dbPath_r )
334 << ( doRebuild_r ?
" (rebuilddb)" :
"" )
335 << ( quickinit ?
" (quickinit)" :
"" ) << endl;
359 MIL <<
"QUICK initDatabase (no systemRoot set)" << endl;
372 ERR <<
"Cleanup on error: state " << info << endl;
387 MIL <<
"Cleanup: state " << info << endl;
396 MIL <<
"Update mode: Cleanup delayed until closeOldDatabase." << endl;
399 #warning CHECK: notify root about conversion backup. 414 MIL <<
"Synchronizing keys with zypp keyring" << endl;
423 MIL <<
"InitDatabase: " << *
this << endl;
449 ERR <<
"Bad database directory: " << dbInfo.
dbDir() << endl;
456 MIL <<
"Found rpm4 database in " << dbInfo.
dbDir() << endl;
460 MIL <<
"Creating new rpm4 database in " << dbInfo.
dbDir() << endl;
472 DBG <<
"Initial state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
491 DBG <<
"Access state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
500 bool dbEmpty = dbptr->empty();
503 MIL <<
"Empty rpm4 database " << dbInfo.
dbV4() << endl;
508 MIL <<
"Found rpm3 database " << dbInfo.
dbV3() << endl;
519 WAR <<
"Backup converted rpm3 database failed: error(" << res <<
")" << endl;
526 MIL <<
"Backup converted rpm3 database: " << dbInfo.
dbV3ToV4() << endl;
535 WAR <<
"Non empty rpm3 and rpm4 database found: using rpm4" << endl;
541 DBG <<
"Convert state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
547 MIL <<
"Rpm3 database backup: " << dbInfo.
dbV3ToV4() << endl;
559 const char * v3backup =
"packages.rpm3";
560 const char * master =
"Packages";
561 const char * index[] =
583 PathInfo pi( dbdir_r );
586 ERR <<
"Can't remove rpm4 database in non directory: " << dbdir_r << endl;
590 for (
const char ** f = index; *f; ++f )
599 pi( dbdir_r + master );
602 MIL <<
"Removing rpm4 database " << pi << endl;
608 pi( dbdir_r + v3backup );
611 MIL <<
"Removing converted rpm3 database backup " << pi << endl;
625 const char * master =
"packages.rpm";
626 const char * index[] =
628 "conflictsindex.rpm",
639 PathInfo pi( dbdir_r );
642 ERR <<
"Can't remove rpm3 database in non directory: " << dbdir_r << endl;
646 for (
const char ** f = index; *f; ++f )
655 #warning CHECK: compare vs existing v3 backup. notify root 656 pi( dbdir_r + master );
659 Pathname m( pi.path() );
664 Pathname b( m.extend(
"3" ) );
669 Pathname b( m.extend(
".deleted" ) );
679 MIL <<
"(Re)moved rpm3 database to " << pi << endl;
719 MIL <<
"Calling closeDatabase: " << *
this << endl;
750 MIL <<
"closeDatabase: " << *
this << endl;
781 MIL <<
"RpmDb::rebuildDatabase" << *
this << endl;
784 PathInfo dbMaster(
root() +
dbPath() +
"Packages" );
785 PathInfo dbMasterBackup( dbMaster.path().extend(
".y2backup" ) );
789 opts.push_back(
"--rebuilddb");
790 opts.push_back(
"-vv");
797 PathInfo newMaster(
root()
810 if ( ! report->progress( (100 * newMaster.size()) / dbMaster.size(),
root() +
dbPath()) )
812 WAR <<
"User requested abort." << endl;
818 if ( line.compare( 0, 2,
"D:" ) )
820 errmsg += line +
'\n';
828 if ( rpm_status != 0 )
846 void computeKeyRingSync( std::set<Edition> & rpmKeys_r, std::list<PublicKeyData> & zyppKeys_r )
853 : _inRpmKeys(
nullptr )
854 , _inZyppKeys(
nullptr )
857 void updateIf(
const Edition & rpmKey_r )
859 std::string keyRelease( rpmKey_r.
release() );
860 int comp = _release.compare( keyRelease );
864 _release.swap( keyRelease );
865 _inRpmKeys = &rpmKey_r;
866 _inZyppKeys =
nullptr;
867 if ( !keyRelease.empty() )
868 DBG <<
"Old key in Z: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
870 else if ( comp == 0 )
874 _inRpmKeys = &rpmKey_r;
878 DBG <<
"Old key in R: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
884 int comp = _release.compare( keyRelease );
888 _release.swap( keyRelease );
889 _inRpmKeys =
nullptr;
890 _inZyppKeys = &zyppKey_r;
891 if ( !keyRelease.empty() )
892 DBG <<
"Old key in R: gpg-pubkey-" << zyppKey_r.
gpgPubkeyVersion() <<
"-" << keyRelease << endl;
894 else if ( comp == 0 )
898 _inZyppKeys = &zyppKey_r;
902 DBG <<
"Old key in Z: gpg-pubkey-" << zyppKey_r.
gpgPubkeyVersion() <<
"-" << keyRelease << endl;
905 std::string _release;
912 std::map<std::string,Key> _keymap;
914 for_( it, rpmKeys_r.begin(), rpmKeys_r.end() )
916 _keymap[(*it).version()].updateIf( *it );
919 for_( it, zyppKeys_r.begin(), zyppKeys_r.end() )
921 _keymap[(*it).gpgPubkeyVersion()].updateIf( *it );
925 std::set<Edition> rpmKeys;
926 std::list<PublicKeyData> zyppKeys;
927 for_( it, _keymap.begin(), _keymap.end() )
929 DBG <<
"gpg-pubkey-" << (*it).first <<
"-" << (*it).second._release <<
" " 930 << ( (*it).second._inRpmKeys ?
"R" :
"_" )
931 << ( (*it).second._inZyppKeys ?
"Z" :
"_" ) << endl;
932 if ( ! (*it).second._inRpmKeys )
934 zyppKeys.push_back( *(*it).second._inZyppKeys );
936 if ( ! (*it).second._inZyppKeys )
938 rpmKeys.insert( *(*it).second._inRpmKeys );
941 rpmKeys_r.swap( rpmKeys );
942 zyppKeys_r.swap( zyppKeys );
949 MIL <<
"Going to sync trusted keys..." << endl;
951 std::list<PublicKeyData> zyppKeys( getZYpp()->keyRing()->trustedPublicKeyData() );
952 computeKeyRingSync( rpmKeys, zyppKeys );
953 MIL << (mode_r &
SYNC_TO_KEYRING ?
"" :
"(skip) ") <<
"Rpm keys to export into zypp trusted keyring: " << rpmKeys.size() << endl;
954 MIL << (mode_r &
SYNC_FROM_KEYRING ?
"" :
"(skip) ") <<
"Zypp trusted keys to import into rpm database: " << zyppKeys.size() << endl;
960 MIL <<
"Exporting rpm keyring into zypp trusted keyring" <<endl;
965 TmpFile tmpfile( getZYpp()->tmpPath() );
967 std::ofstream tmpos( tmpfile.
path().
c_str() );
968 for_( it, rpmKeys.begin(), rpmKeys.end() )
972 getData(
"gpg-pubkey", *it, result );
973 tmpos << result->tag_description() << endl;
978 getZYpp()->keyRing()->multiKeyImport( tmpfile.
path(),
true );
982 ERR <<
"Could not import keys into in zypp keyring" << endl;
990 MIL <<
"Importing zypp trusted keyring" << std::endl;
991 for_( it, zyppKeys.begin(), zyppKeys.end() )
995 importPubkey( getZYpp()->keyRing()->exportTrustedPublicKey( *it ) );
1003 MIL <<
"Trusted keys synced." << endl;
1025 WAR <<
"Key " << pubkey_r <<
" can not be imported. (READONLY MODE)" << endl;
1032 bool hasOldkeys =
false;
1034 for_( it, rpmKeys.begin(), rpmKeys.end() )
1041 if ( keyEd == *it && !pubkey_r.
hasSubkeys() )
1043 MIL <<
"Key " << pubkey_r <<
" is already in the rpm trusted keyring. (skip import)" << endl;
1047 if ( keyEd.version() != (*it).version() )
1050 if ( keyEd.release() < (*it).release() )
1052 MIL <<
"Key " << pubkey_r <<
" is older than one in the rpm trusted keyring. (skip import)" << endl;
1060 MIL <<
"Key " << pubkey_r <<
" will be imported into the rpm trusted keyring." << (hasOldkeys?
"(update)":
"(new)") << endl;
1066 std::string keyName(
"gpg-pubkey-" + keyEd.version() );
1068 opts.push_back (
"-e" );
1069 opts.push_back (
"--allmatches" );
1070 opts.push_back (
"--" );
1071 opts.push_back ( keyName.c_str() );
1084 ERR <<
"Failed to remove key " << pubkey_r <<
" from RPM trusted keyring (ignored)" << endl;
1088 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1094 opts.push_back (
"--import" );
1095 opts.push_back (
"--" );
1096 std::string pubkeypath( pubkey_r.
path().asString() );
1097 opts.push_back ( pubkeypath.c_str() );
1104 std::vector<std::string> excplines;
1109 WAR << line << endl;
1110 excplines.push_back( std::move(line) );
1113 DBG << line << endl;
1126 MIL <<
"Key " << pubkey_r <<
" imported in rpm trusted keyring." << endl;
1143 std::set<Edition>::const_iterator found_edition = rpm_keys.end();
1146 for_( it, rpm_keys.begin(), rpm_keys.end() )
1148 if ( (*it).version() == pubkeyVersion )
1156 if (found_edition == rpm_keys.end())
1158 WAR <<
"Key " << pubkey_r.
id() <<
" is not in rpm db" << endl;
1162 std::string rpm_name(
"gpg-pubkey-" + found_edition->asString());
1165 opts.push_back (
"-e" );
1166 opts.push_back (
"--" );
1167 opts.push_back ( rpm_name.c_str() );
1174 std::vector<std::string> excplines;
1179 WAR << line << endl;
1180 excplines.push_back( std::move(line) );
1183 DBG << line << endl;
1196 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1208 std::list<PublicKey> ret;
1211 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1213 Edition edition = it->tag_edition();
1218 getData(
"gpg-pubkey", edition, result );
1219 TmpFile file(getZYpp()->tmpPath());
1225 os << result->tag_description();
1234 catch ( std::exception & e )
1236 ERR <<
"Could not dump key " << edition.
asString() <<
" in tmp file " << file.
path() << endl;
1246 std::set<Edition> ret;
1249 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1251 Edition edition = it->tag_edition();
1253 ret.insert( edition );
1270 std::list<FileInfo> result;
1305 if (!name_r.empty())
1307 res = (it->tag_name() == name_r);
1328 return it->tag_name();
1442 struct RpmlogCapture :
public std::string
1445 { rpmlog()._cap =
this; }
1448 { rpmlog()._cap =
nullptr; }
1456 rpmlogSetCallback( rpmLogCB,
this );
1457 rpmSetVerbosity( RPMLOG_INFO );
1458 _f = ::fopen(
"/dev/null",
"w");
1459 rpmlogSetFile(
_f );
1463 {
if (
_f ) ::fclose(
_f ); }
1465 static int rpmLogCB( rpmlogRec rec_r, rpmlogCallbackData data_r )
1466 {
return reinterpret_cast<Rpmlog*
>(data_r)->rpmLog( rec_r ); }
1468 int rpmLog( rpmlogRec rec_r )
1470 if (
_cap ) (*_cap) = rpmlogRecMessage( rec_r );
1471 return RPMLOG_DEFAULT;
1478 static Rpmlog & rpmlog()
1479 {
static Rpmlog _rpmlog;
return _rpmlog; }
1484 bool requireGPGSig_r,
1485 RpmDb::CheckPackageDetail & detail_r )
1490 ERR <<
"Not a file: " << file << endl;
1494 FD_t fd = ::Fopen( file.
asString().c_str(),
"r.ufdio" );
1495 if ( fd == 0 || ::Ferror(fd) )
1497 ERR <<
"Can't open file for reading: " << file <<
" (" << ::Fstrerror(fd) <<
")" << endl;
1502 rpmts ts = ::rpmtsCreate();
1503 ::rpmtsSetRootDir( ts, root_r.
c_str() );
1504 ::rpmtsSetVSFlags( ts, RPMVSF_DEFAULT );
1506 rpmQVKArguments_s qva;
1507 memset( &qva, 0,
sizeof(rpmQVKArguments_s) );
1508 qva.qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE);
1510 RpmlogCapture vresult;
1511 int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.
basename().c_str() );
1523 std::vector<std::string> lines;
1524 str::split( vresult, std::back_inserter(lines),
"\n" );
1525 unsigned count[7] = { 0, 0, 0, 0, 0, 0, 0 };
1527 for (
unsigned i = 1; i < lines.size(); ++i )
1529 std::string & line( lines[i] );
1531 if ( line.find(
": OK" ) != std::string::npos )
1534 if ( line.find(
"Signature, key ID" ) == std::string::npos )
1537 else if ( line.find(
": NOKEY" ) != std::string::npos )
1539 else if ( line.find(
": BAD" ) != std::string::npos )
1541 else if ( line.find(
": UNKNOWN" ) != std::string::npos )
1543 else if ( line.find(
": NOTRUSTED" ) != std::string::npos )
1547 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( lineres, std::move(line) ) );
1568 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( RpmDb::CHK_NOSIG, std::string(
" ")+
_(
"Package is not signed!") ) );
1569 if ( requireGPGSig_r )
1576 WAR << path_r <<
" (" << requireGPGSig_r <<
" -> " << ret <<
")" << endl;
1589 {
return doCheckPackageSig( path_r,
root(),
false, detail_r ); }
1595 {
return doCheckPackageSig( path_r,
root(),
true, detail_r ); }
1610 opts.push_back (
"-V");
1611 opts.push_back (
"--nodeps");
1612 opts.push_back (
"--noscripts");
1613 opts.push_back (
"--nomd5");
1614 opts.push_back (
"--");
1615 opts.push_back (packageName.c_str());
1636 if (line.length() > 12 &&
1637 (line[0] ==
'S' || line[0] ==
's' ||
1638 (line[0] ==
'.' && line[7] ==
'T')))
1641 std::string filename;
1643 filename.assign(line, 11, line.length() - 11);
1644 fileList.insert(filename);
1684 #if defined(WORKAROUNDRPMPWDBUG) 1685 args.push_back(
"#/");
1687 args.push_back(
"rpm");
1688 args.push_back(
"--root");
1689 args.push_back(
_root.asString().c_str());
1690 args.push_back(
"--dbpath");
1691 args.push_back(
_dbPath.asString().c_str());
1693 const char* argv[args.size() + opts.size() + 1];
1695 const char** p = argv;
1696 p =
copy (args.begin (), args.end (), p);
1697 p =
copy (opts.begin (), opts.end (), p);
1723 int inputfileFd = ::fileno( inputfile );
1729 FD_SET( inputfileFd, &rfds );
1736 int retval = select( inputfileFd+1, &rfds, NULL, NULL, &tv );
1740 ERR <<
"select error: " <<
strerror(errno) << endl;
1741 if ( errno != EINTR )
1747 static size_t linebuffer_size = 0;
1748 static char * linebuffer = 0;
1749 ssize_t nread =
getline( &linebuffer, &linebuffer_size, inputfile );
1752 if ( ::feof( inputfile ) )
1759 if ( linebuffer[nread-1] ==
'\n' )
1761 line += std::string( linebuffer, nread );
1764 if ( ! ::ferror( inputfile ) || ::feof( inputfile ) )
1767 clearerr( inputfile );
1816 void RpmDb::processConfigFiles(
const std::string& line,
const std::string& name,
const char* typemsg,
const char* difffailmsg,
const char* diffgenmsg)
1818 std::string msg = line.substr(9);
1821 std::string file1s, file2s;
1825 pos1 = msg.find (typemsg);
1828 if ( pos1 == std::string::npos )
1831 pos2 = pos1 + strlen (typemsg);
1833 if (pos2 >= msg.length() )
1836 file1 = msg.substr (0, pos1);
1837 file2 = msg.substr (pos2);
1839 file1s = file1.asString();
1840 file2s = file2.asString();
1844 file1 =
_root + file1;
1845 file2 =
_root + file2;
1849 int ret =
diffFiles (file1.asString(), file2.asString(), out, 25);
1855 ERR <<
"Could not create " << file.asString() << endl;
1859 std::ofstream notify(file.asString().c_str(), std::ios::out|std::ios::app);
1862 ERR <<
"Could not open " << file << endl;
1868 notify <<
str::form(
_(
"Changed configuration files for %s:"), name.c_str()) << endl;
1871 ERR <<
"diff failed" << endl;
1873 file1s.c_str(), file2s.c_str()) << endl;
1878 file1s.c_str(), file2s.c_str()) << endl;
1883 if (out.substr(0,4) ==
"--- ")
1885 out.replace(4, file1.asString().length(), file1s);
1888 if (pos != std::string::npos)
1890 out.replace(pos+5, file2.asString().length(), file2s);
1893 notify << out << endl;
1896 notify.open(
"/var/lib/update-messages/yast2-packagemanager.rpmdb.configfiles");
1901 WAR <<
"rpm created " << file2 <<
" but it is not different from " << file2 << endl;
1917 report->start(filename);
1932 report->finish( excpt_r );
1948 MIL <<
"RpmDb::installPackage(" << filename <<
"," << flags <<
")" << endl;
1957 ERR <<
"backup of " << filename.asString() <<
" failed" << endl;
1960 report->progress( 0 );
1966 opts.push_back(
"-i");
1968 opts.push_back(
"-U");
1970 opts.push_back(
"--percent");
1971 opts.push_back(
"--noglob");
1975 opts.push_back(
"--ignorearch");
1978 opts.push_back(
"--nodigest");
1980 opts.push_back(
"--nosignature");
1982 opts.push_back (
"--excludedocs");
1984 opts.push_back (
"--noscripts");
1986 opts.push_back (
"--force");
1988 opts.push_back (
"--nodeps");
1990 opts.push_back (
"--ignoresize");
1992 opts.push_back (
"--justdb");
1994 opts.push_back (
"--test");
1996 opts.push_back (
"--noposttrans");
1998 opts.push_back(
"--");
2001 std::string quotedFilename( rpmQuoteFilename( workaroundRpmPwdBug( filename ) ) );
2002 opts.push_back ( quotedFilename.c_str() );
2009 std::vector<std::string> configwarnings;
2011 unsigned linecnt = 0;
2017 sscanf( line.c_str() + 2,
"%d", &percent );
2018 report->progress( percent );
2024 else if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2027 rpmmsg += line+
'\n';
2030 configwarnings.push_back(line);
2033 rpmmsg +=
"[truncated]\n";
2038 for (std::vector<std::string>::iterator it = configwarnings.begin();
2039 it != configwarnings.end(); ++it)
2043 _(
"rpm saved %s as %s, but it was impossible to determine the difference"),
2045 _(
"rpm saved %s as %s.\nHere are the first 25 lines of difference:\n"));
2048 _(
"rpm created %s as %s, but it was impossible to determine the difference"),
2050 _(
"rpm created %s as %s.\nHere are the first 25 lines of difference:\n"));
2053 if ( rpm_status != 0 )
2056 str::form(
"%s install failed", Pathname::basename(filename).c_str()),
2058 std::ostringstream sstr;
2059 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2060 historylog.
comment(sstr.str());
2064 else if ( ! rpmmsg.empty() )
2067 str::form(
"%s installed ok", Pathname::basename(filename).c_str()),
2069 std::ostringstream sstr;
2070 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2071 historylog.
comment(sstr.str());
2075 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2089 +
"-" + package->edition().version()
2090 +
"-" + package->edition().release()
2091 +
"." + package->arch().asString(), flags );
2104 report->start( name_r );
2119 report->finish( excpt_r );
2136 MIL <<
"RpmDb::doRemovePackage(" << name_r <<
"," << flags <<
")" << endl;
2145 ERR <<
"backup of " << name_r <<
" failed" << endl;
2147 report->progress( 0 );
2151 report->progress( 100 );
2156 opts.push_back(
"-e");
2157 opts.push_back(
"--allmatches");
2160 opts.push_back(
"--noscripts");
2162 opts.push_back(
"--nodeps");
2164 opts.push_back(
"--justdb");
2166 opts.push_back (
"--test");
2169 WAR <<
"IGNORE OPTION: 'rpm -e' does not support '--force'" << endl;
2172 opts.push_back(
"--");
2173 opts.push_back(name_r.c_str());
2185 report->progress( 5 );
2186 unsigned linecnt = 0;
2191 else if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2193 rpmmsg += line+
'\n';
2196 rpmmsg +=
"[truncated]\n";
2197 report->progress( 50 );
2200 if ( rpm_status != 0 )
2203 str::form(
"%s remove failed", name_r.c_str()),
true );
2204 std::ostringstream sstr;
2205 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2206 historylog.
comment(sstr.str());
2210 else if ( ! rpmmsg.empty() )
2213 str::form(
"%s removed ok", name_r.c_str()),
true );
2215 std::ostringstream sstr;
2216 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2217 historylog.
comment(sstr.str());
2221 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2250 Pathname backupFilename;
2255 INT <<
"_backuppath empty" << endl;
2263 ERR <<
"Error while getting changed files for package " <<
2264 packageName << endl;
2268 if (fileList.size() <= 0)
2270 DBG <<
"package " << packageName <<
" not changed -> no backup" << endl;
2282 struct tm *currentLocalTime = localtime(¤tTime);
2284 int date = (currentLocalTime->tm_year + 1900) * 10000
2285 + (currentLocalTime->tm_mon + 1) * 100
2286 + currentLocalTime->tm_mday;
2292 +
str::form(
"%s-%d-%d.tar.gz",packageName.c_str(), date, num);
2295 while ( PathInfo(backupFilename).isExist() && num++ < 1000);
2297 PathInfo pi(filestobackupfile);
2298 if (pi.isExist() && !pi.isFile())
2300 ERR << filestobackupfile.asString() <<
" already exists and is no file" << endl;
2304 std::ofstream fp ( filestobackupfile.asString().c_str(), std::ios::out|std::ios::trunc );
2308 ERR <<
"could not open " << filestobackupfile.asString() << endl;
2312 for (FileList::const_iterator cit = fileList.begin();
2313 cit != fileList.end(); ++cit)
2315 std::string name = *cit;
2316 if ( name[0] ==
'/' )
2319 name = name.substr( 1 );
2321 DBG <<
"saving file "<< name << endl;
2326 const char*
const argv[] =
2331 _root.asString().c_str(),
2332 "--ignore-failed-read",
2334 backupFilename.asString().c_str(),
2336 filestobackupfile.asString().c_str(),
2352 int ret = tar.
close();
2356 ERR <<
"tar failed: " << tarmsg << endl;
2361 MIL <<
"tar backup ok" << endl;
2363 str::form(
_(
"created backup %s"), backupFilename.asString().c_str())
2382 #define OUTS(E,S) case RpmDb::E: return str << "["<< (unsigned)obj << "-"<< S << "]"; break 2394 OUTS(
CHK_ERROR,
_(
"File does not exist or signature can't be checked") );
2399 return str <<
"UnknowSignatureCheckError("+
str::numstring(obj)+
")";
2404 for (
const auto & el : obj )
2405 str << el.second << endl;
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).
std::string gpgPubkeyRelease() const
Gpg-pubkey release as computed by rpm (hexencoded created)
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
!<
Class representing one GPG Public Keys data.
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.
String related utilities and Regular expression matching.
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.
std::string gpgPubkeyVersion() const
Gpg-pubkey version as computed by rpm (trailing 8 byte id)
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Edition represents [epoch:]version[-release]
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 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
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.
const std::string & asString() const
Return current Pathname as String.
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
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
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.).
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
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
friend std::ostream & operator<<(std::ostream &str, const DbStateInfoBits &obj)
Easy-to use interface to the ZYPP dependency resolver.
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