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;
130 _rpmdb.importPubkey( key );
134 ERR <<
"Could not import key " << key.
id() <<
" (" << key.
name() <<
" from " << key.
path() <<
" in rpm database" << endl;
140 MIL <<
"Trusted key removed from zypp Keyring. Removing..." << endl;
145 _rpmdb.removePubkey( key );
149 ERR <<
"Could not remove key " << key.
id() <<
" (" << key.
name() <<
") from rpm database" << endl;
158 unsigned diffFiles(
const std::string file1,
const std::string file2, std::string& out,
int maxlines)
179 if (maxlines<0?
true:count<maxlines)
194 inline std::string
stringPath(
const Pathname & root_r,
const Pathname & sub_r )
207 if ( obj == RpmDb::DbSI_NO_INIT )
213 #define ENUM_OUT(B,C) str << ( obj & RpmDb::B ? C : '-' ) 236 #define FAILIFNOTINITIALIZED if( ! initialized() ) { ZYPP_THROW(RpmDbNotOpenException()); } 247 : _dbStateInfo( DbSI_NO_INIT )
248 #warning Check for obsolete memebers
249 , _backuppath (
"/var/adm/backup")
250 , _packagebackups(false)
251 , _warndirexists(false)
258 setenv(
"RPM_IgnoreFailedSymlinks",
"1", 1 );
270 MIL <<
"~RpmDb()" << endl;
273 MIL <<
"~RpmDb() end" << endl;
274 sKeyRingReceiver.reset();
283 db_path =
"/var/lib/rpm";
287 PathInfo rpmdb_info(
root() + db_path +
"/Packages");
289 if ( rpmdb_info.isExist() )
290 return rpmdb_info.mtime();
310 #define ENUM_OUT(B,C) str << ( _dbStateInfo & B ? C : '-' ) 336 bool quickinit( root_r.empty() );
338 if ( root_r.empty() )
341 if ( dbPath_r.empty() )
342 dbPath_r =
"/var/lib/rpm";
344 if ( ! (root_r.absolute() && dbPath_r.absolute()) )
346 ERR <<
"Illegal root or dbPath: " <<
stringPath( root_r, dbPath_r ) << endl;
350 MIL <<
"Calling initDatabase: " <<
stringPath( root_r, dbPath_r )
351 << ( doRebuild_r ?
" (rebuilddb)" :
"" )
352 << ( quickinit ?
" (quickinit)" :
"" ) << endl;
376 MIL <<
"QUICK initDatabase (no systemRoot set)" << endl;
389 ERR <<
"Cleanup on error: state " << info << endl;
404 MIL <<
"Cleanup: state " << info << endl;
413 MIL <<
"Update mode: Cleanup delayed until closeOldDatabase." << endl;
416 #warning CHECK: notify root about conversion backup. 431 MIL <<
"Synchronizing keys with zypp keyring" << endl;
440 MIL <<
"InitDatabase: " << *
this << endl;
466 ERR <<
"Bad database directory: " << dbInfo.
dbDir() << endl;
473 MIL <<
"Found rpm4 database in " << dbInfo.
dbDir() << endl;
477 MIL <<
"Creating new rpm4 database in " << dbInfo.
dbDir() << endl;
489 DBG <<
"Initial state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
508 DBG <<
"Access state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
517 bool dbEmpty = dbptr->empty();
520 MIL <<
"Empty rpm4 database " << dbInfo.
dbV4() << endl;
525 MIL <<
"Found rpm3 database " << dbInfo.
dbV3() << endl;
536 WAR <<
"Backup converted rpm3 database failed: error(" << res <<
")" << endl;
543 MIL <<
"Backup converted rpm3 database: " << dbInfo.
dbV3ToV4() << endl;
552 WAR <<
"Non empty rpm3 and rpm4 database found: using rpm4" << endl;
558 DBG <<
"Convert state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
564 MIL <<
"Rpm3 database backup: " << dbInfo.
dbV3ToV4() << endl;
576 const char * v3backup =
"packages.rpm3";
577 const char * master =
"Packages";
578 const char * index[] =
600 PathInfo pi( dbdir_r );
603 ERR <<
"Can't remove rpm4 database in non directory: " << dbdir_r << endl;
607 for (
const char ** f = index; *f; ++f )
616 pi( dbdir_r + master );
619 MIL <<
"Removing rpm4 database " << pi << endl;
625 pi( dbdir_r + v3backup );
628 MIL <<
"Removing converted rpm3 database backup " << pi << endl;
642 const char * master =
"packages.rpm";
643 const char * index[] =
645 "conflictsindex.rpm",
656 PathInfo pi( dbdir_r );
659 ERR <<
"Can't remove rpm3 database in non directory: " << dbdir_r << endl;
663 for (
const char ** f = index; *f; ++f )
672 #warning CHECK: compare vs existing v3 backup. notify root 673 pi( dbdir_r + master );
676 Pathname m( pi.path() );
681 Pathname b( m.extend(
"3" ) );
686 Pathname b( m.extend(
".deleted" ) );
696 MIL <<
"(Re)moved rpm3 database to " << pi << endl;
736 MIL <<
"Calling closeDatabase: " << *
this << endl;
767 MIL <<
"closeDatabase: " << *
this << endl;
798 MIL <<
"RpmDb::rebuildDatabase" << *
this << endl;
801 PathInfo dbMaster(
root() +
dbPath() +
"Packages" );
802 PathInfo dbMasterBackup( dbMaster.path().extend(
".y2backup" ) );
806 opts.push_back(
"--rebuilddb");
807 opts.push_back(
"-vv");
814 PathInfo newMaster(
root()
827 if ( ! report->progress( (100 * newMaster.size()) / dbMaster.size(),
root() +
dbPath()) )
829 WAR <<
"User requested abort." << endl;
835 if ( line.compare( 0, 2,
"D:" ) )
837 errmsg += line +
'\n';
845 if ( rpm_status != 0 )
863 void computeKeyRingSync( std::set<Edition> & rpmKeys_r, std::list<PublicKeyData> & zyppKeys_r )
870 : _inRpmKeys(
nullptr )
871 , _inZyppKeys(
nullptr )
874 void updateIf(
const Edition & rpmKey_r )
876 std::string keyRelease( rpmKey_r.
release() );
877 int comp = _release.compare( keyRelease );
881 _release.swap( keyRelease );
882 _inRpmKeys = &rpmKey_r;
883 _inZyppKeys =
nullptr;
884 if ( !keyRelease.empty() )
885 DBG <<
"Old key in R: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
887 else if ( comp == 0 )
891 _inRpmKeys = &rpmKey_r;
895 DBG <<
"Old key in R: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
901 int comp = _release.compare( keyRelease );
905 _release.swap( keyRelease );
906 _inRpmKeys =
nullptr;
907 _inZyppKeys = &zyppKey_r;
908 if ( !keyRelease.empty() )
909 DBG <<
"Old key in Z: gpg-pubkey-" << zyppKey_r.
gpgPubkeyVersion() <<
"-" << keyRelease << endl;
911 else if ( comp == 0 )
915 _inZyppKeys = &zyppKey_r;
919 DBG <<
"Old key in Z: gpg-pubkey-" << zyppKey_r.
gpgPubkeyVersion() <<
"-" << keyRelease << endl;
922 std::string _release;
929 std::map<std::string,Key> _keymap;
931 for_( it, rpmKeys_r.begin(), rpmKeys_r.end() )
933 _keymap[(*it).version()].updateIf( *it );
936 for_( it, zyppKeys_r.begin(), zyppKeys_r.end() )
938 _keymap[(*it).gpgPubkeyVersion()].updateIf( *it );
942 std::set<Edition> rpmKeys;
943 std::list<PublicKeyData> zyppKeys;
944 for_( it, _keymap.begin(), _keymap.end() )
946 DBG <<
"gpg-pubkey-" << (*it).first <<
"-" << (*it).second._release <<
" " 947 << ( (*it).second._inRpmKeys ?
"R" :
"_" )
948 << ( (*it).second._inZyppKeys ?
"Z" :
"_" ) << endl;
949 if ( ! (*it).second._inRpmKeys )
951 zyppKeys.push_back( *(*it).second._inZyppKeys );
953 if ( ! (*it).second._inZyppKeys )
955 rpmKeys.insert( *(*it).second._inRpmKeys );
958 rpmKeys_r.swap( rpmKeys );
959 zyppKeys_r.swap( zyppKeys );
966 MIL <<
"Going to sync trusted keys..." << endl;
968 std::list<PublicKeyData> zyppKeys( getZYpp()->keyRing()->trustedPublicKeyData() );
969 computeKeyRingSync( rpmKeys, zyppKeys );
970 MIL << (mode_r &
SYNC_TO_KEYRING ?
"" :
"(skip) ") <<
"Rpm keys to export into zypp trusted keyring: " << rpmKeys.size() << endl;
971 MIL << (mode_r &
SYNC_FROM_KEYRING ?
"" :
"(skip) ") <<
"Zypp trusted keys to import into rpm database: " << zyppKeys.size() << endl;
977 MIL <<
"Exporting rpm keyring into zypp trusted keyring" <<endl;
982 TmpFile tmpfile( getZYpp()->tmpPath() );
984 std::ofstream tmpos( tmpfile.
path().
c_str() );
985 for_( it, rpmKeys.begin(), rpmKeys.end() )
989 getData(
"gpg-pubkey", *it, result );
990 tmpos << result->tag_description() << endl;
995 getZYpp()->keyRing()->multiKeyImport( tmpfile.
path(),
true );
999 ERR <<
"Could not import keys into in zypp keyring" << endl;
1007 MIL <<
"Importing zypp trusted keyring" << std::endl;
1008 for_( it, zyppKeys.begin(), zyppKeys.end() )
1012 importPubkey( getZYpp()->keyRing()->exportTrustedPublicKey( *it ) );
1020 MIL <<
"Trusted keys synced." << endl;
1042 WAR <<
"Key " << pubkey_r <<
" can not be imported. (READONLY MODE)" << endl;
1049 bool hasOldkeys =
false;
1051 for_( it, rpmKeys.begin(), rpmKeys.end() )
1058 if ( keyEd == *it && !pubkey_r.
hasSubkeys() )
1060 MIL <<
"Key " << pubkey_r <<
" is already in the rpm trusted keyring. (skip import)" << endl;
1064 if ( keyEd.version() != (*it).version() )
1067 if ( keyEd.release() < (*it).release() )
1069 MIL <<
"Key " << pubkey_r <<
" is older than one in the rpm trusted keyring. (skip import)" << endl;
1077 MIL <<
"Key " << pubkey_r <<
" will be imported into the rpm trusted keyring." << (hasOldkeys?
"(update)":
"(new)") << endl;
1083 std::string keyName(
"gpg-pubkey-" + keyEd.version() );
1085 opts.push_back (
"-e" );
1086 opts.push_back (
"--allmatches" );
1087 opts.push_back (
"--" );
1088 opts.push_back ( keyName.c_str() );
1101 ERR <<
"Failed to remove key " << pubkey_r <<
" from RPM trusted keyring (ignored)" << endl;
1105 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1111 opts.push_back (
"--import" );
1112 opts.push_back (
"--" );
1113 std::string pubkeypath( pubkey_r.
path().asString() );
1114 opts.push_back ( pubkeypath.c_str() );
1135 MIL <<
"Key " << pubkey_r <<
" imported in rpm trusted keyring." << endl;
1152 std::set<Edition>::const_iterator found_edition = rpm_keys.end();
1155 for_( it, rpm_keys.begin(), rpm_keys.end() )
1157 if ( (*it).version() == pubkeyVersion )
1165 if (found_edition == rpm_keys.end())
1167 WAR <<
"Key " << pubkey_r.
id() <<
" is not in rpm db" << endl;
1171 std::string rpm_name(
"gpg-pubkey-" + found_edition->asString());
1174 opts.push_back (
"-e" );
1175 opts.push_back (
"--" );
1176 opts.push_back ( rpm_name.c_str() );
1185 if ( line.substr( 0, 6 ) ==
"error:" )
1187 WAR << line << endl;
1191 DBG << line << endl;
1197 if ( rpm_status != 0 )
1206 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1218 std::list<PublicKey> ret;
1221 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1223 Edition edition = it->tag_edition();
1228 getData(
"gpg-pubkey", edition, result );
1229 TmpFile file(getZYpp()->tmpPath());
1235 os << result->tag_description();
1244 catch ( std::exception & e )
1246 ERR <<
"Could not dump key " << edition.
asString() <<
" in tmp file " << file.
path() << endl;
1256 std::set<Edition> ret;
1259 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1261 Edition edition = it->tag_edition();
1263 ret.insert( edition );
1280 std::list<FileInfo> result;
1315 if (!name_r.empty())
1317 res = (it->tag_name() == name_r);
1338 return it->tag_name();
1452 struct RpmlogCapture :
public std::string
1455 { rpmlog()._cap =
this; }
1458 { rpmlog()._cap =
nullptr; }
1466 rpmlogSetCallback( rpmLogCB,
this );
1467 rpmSetVerbosity( RPMLOG_INFO );
1468 _f = ::fopen(
"/dev/null",
"w");
1469 rpmlogSetFile(
_f );
1473 {
if (
_f ) ::fclose(
_f ); }
1475 static int rpmLogCB( rpmlogRec rec_r, rpmlogCallbackData data_r )
1476 {
return reinterpret_cast<Rpmlog*
>(data_r)->rpmLog( rec_r ); }
1478 int rpmLog( rpmlogRec rec_r )
1480 if (
_cap ) (*_cap) = rpmlogRecMessage( rec_r );
1481 return RPMLOG_DEFAULT;
1488 static Rpmlog & rpmlog()
1489 {
static Rpmlog _rpmlog;
return _rpmlog; }
1494 bool requireGPGSig_r,
1495 RpmDb::CheckPackageDetail & detail_r )
1500 ERR <<
"Not a file: " << file << endl;
1504 FD_t fd = ::Fopen( file.
asString().c_str(),
"r.ufdio" );
1505 if ( fd == 0 || ::Ferror(fd) )
1507 ERR <<
"Can't open file for reading: " << file <<
" (" << ::Fstrerror(fd) <<
")" << endl;
1512 rpmts ts = ::rpmtsCreate();
1513 ::rpmtsSetRootDir( ts, root_r.
c_str() );
1514 ::rpmtsSetVSFlags( ts, RPMVSF_DEFAULT );
1516 rpmQVKArguments_s qva;
1517 memset( &qva, 0,
sizeof(rpmQVKArguments_s) );
1518 qva.qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE);
1520 RpmlogCapture vresult;
1521 int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.
basename().c_str() );
1533 std::vector<std::string> lines;
1534 str::split( vresult, std::back_inserter(lines),
"\n" );
1535 unsigned count[7] = { 0, 0, 0, 0, 0, 0, 0 };
1537 for (
unsigned i = 1; i < lines.size(); ++i )
1539 std::string & line( lines[i] );
1541 if ( line.find(
": OK" ) != std::string::npos )
1544 if ( line.find(
"Signature, key ID" ) == std::string::npos )
1547 else if ( line.find(
": NOKEY" ) != std::string::npos )
1549 else if ( line.find(
": BAD" ) != std::string::npos )
1551 else if ( line.find(
": UNKNOWN" ) != std::string::npos )
1553 else if ( line.find(
": NOTRUSTED" ) != std::string::npos )
1557 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( lineres, std::move(line) ) );
1578 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( RpmDb::CHK_NOSIG, std::string(
" ")+
_(
"Package is not signed!") ) );
1579 if ( requireGPGSig_r )
1586 WAR << path_r <<
" (" << requireGPGSig_r <<
" -> " << ret <<
")" << endl;
1599 {
return doCheckPackageSig( path_r,
root(),
false, detail_r ); }
1605 {
return doCheckPackageSig( path_r,
root(),
true, detail_r ); }
1620 opts.push_back (
"-V");
1621 opts.push_back (
"--nodeps");
1622 opts.push_back (
"--noscripts");
1623 opts.push_back (
"--nomd5");
1624 opts.push_back (
"--");
1625 opts.push_back (packageName.c_str());
1646 if (line.length() > 12 &&
1647 (line[0] ==
'S' || line[0] ==
's' ||
1648 (line[0] ==
'.' && line[7] ==
'T')))
1651 std::string filename;
1653 filename.assign(line, 11, line.length() - 11);
1654 fileList.insert(filename);
1694 #if defined(WORKAROUNDRPMPWDBUG) 1695 args.push_back(
"#/");
1697 args.push_back(
"rpm");
1698 args.push_back(
"--root");
1699 args.push_back(
_root.asString().c_str());
1700 args.push_back(
"--dbpath");
1701 args.push_back(
_dbPath.asString().c_str());
1703 const char* argv[args.size() + opts.size() + 1];
1705 const char** p = argv;
1706 p =
copy (args.begin (), args.end (), p);
1707 p =
copy (opts.begin (), opts.end (), p);
1733 int inputfileFd = ::fileno( inputfile );
1739 FD_SET( inputfileFd, &rfds );
1746 int retval = select( inputfileFd+1, &rfds, NULL, NULL, &tv );
1750 ERR <<
"select error: " <<
strerror(errno) << endl;
1751 if ( errno != EINTR )
1757 static size_t linebuffer_size = 0;
1758 static char * linebuffer = 0;
1759 ssize_t nread =
getline( &linebuffer, &linebuffer_size, inputfile );
1762 if ( ::feof( inputfile ) )
1769 if ( linebuffer[nread-1] ==
'\n' )
1771 line += std::string( linebuffer, nread );
1774 if ( ! ::ferror( inputfile ) || ::feof( inputfile ) )
1777 clearerr( inputfile );
1826 void RpmDb::processConfigFiles(
const std::string& line,
const std::string& name,
const char* typemsg,
const char* difffailmsg,
const char* diffgenmsg)
1828 std::string msg = line.substr(9);
1831 std::string file1s, file2s;
1835 pos1 = msg.find (typemsg);
1838 if ( pos1 == std::string::npos )
1841 pos2 = pos1 + strlen (typemsg);
1843 if (pos2 >= msg.length() )
1846 file1 = msg.substr (0, pos1);
1847 file2 = msg.substr (pos2);
1849 file1s = file1.asString();
1850 file2s = file2.asString();
1854 file1 =
_root + file1;
1855 file2 =
_root + file2;
1859 int ret =
diffFiles (file1.asString(), file2.asString(), out, 25);
1865 ERR <<
"Could not create " << file.asString() << endl;
1869 std::ofstream notify(file.asString().c_str(), std::ios::out|std::ios::app);
1872 ERR <<
"Could not open " << file << endl;
1878 notify <<
str::form(
_(
"Changed configuration files for %s:"), name.c_str()) << endl;
1881 ERR <<
"diff failed" << endl;
1883 file1s.c_str(), file2s.c_str()) << endl;
1888 file1s.c_str(), file2s.c_str()) << endl;
1893 if (out.substr(0,4) ==
"--- ")
1895 out.replace(4, file1.asString().length(), file1s);
1898 if (pos != std::string::npos)
1900 out.replace(pos+5, file2.asString().length(), file2s);
1903 notify << out << endl;
1906 notify.open(
"/var/lib/update-messages/yast2-packagemanager.rpmdb.configfiles");
1911 WAR <<
"rpm created " << file2 <<
" but it is not different from " << file2 << endl;
1927 report->start(filename);
1942 report->finish( excpt_r );
1958 MIL <<
"RpmDb::installPackage(" << filename <<
"," << flags <<
")" << endl;
1967 ERR <<
"backup of " << filename.asString() <<
" failed" << endl;
1970 report->progress( 0 );
1976 opts.push_back(
"-i");
1978 opts.push_back(
"-U");
1980 opts.push_back(
"--percent");
1981 opts.push_back(
"--noglob");
1985 opts.push_back(
"--ignorearch");
1988 opts.push_back(
"--nodigest");
1990 opts.push_back(
"--nosignature");
1992 opts.push_back (
"--excludedocs");
1994 opts.push_back (
"--noscripts");
1996 opts.push_back (
"--force");
1998 opts.push_back (
"--nodeps");
2000 opts.push_back (
"--ignoresize");
2002 opts.push_back (
"--justdb");
2004 opts.push_back (
"--test");
2006 opts.push_back (
"--noposttrans");
2008 opts.push_back(
"--");
2011 std::string quotedFilename( rpmQuoteFilename( workaroundRpmPwdBug( filename ) ) );
2012 opts.push_back ( quotedFilename.c_str() );
2019 std::vector<std::string> configwarnings;
2021 unsigned linecnt = 0;
2029 if (line.substr(0,2)==
"%%")
2032 sscanf (line.c_str () + 2,
"%d", &percent);
2033 report->progress( percent );
2036 rpmmsg += line+
'\n';
2038 if ( line.substr(0,8) ==
"warning:" )
2040 configwarnings.push_back(line);
2044 rpmmsg +=
"[truncated]\n";
2049 for (std::vector<std::string>::iterator it = configwarnings.begin();
2050 it != configwarnings.end(); ++it)
2054 _(
"rpm saved %s as %s, but it was impossible to determine the difference"),
2056 _(
"rpm saved %s as %s.\nHere are the first 25 lines of difference:\n"));
2059 _(
"rpm created %s as %s, but it was impossible to determine the difference"),
2061 _(
"rpm created %s as %s.\nHere are the first 25 lines of difference:\n"));
2064 if ( rpm_status != 0 )
2067 str::form(
"%s install failed", Pathname::basename(filename).c_str()),
2069 std::ostringstream sstr;
2070 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2071 historylog.
comment(sstr.str());
2075 else if ( ! rpmmsg.empty() )
2078 str::form(
"%s installed ok", Pathname::basename(filename).c_str()),
2080 std::ostringstream sstr;
2081 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2082 historylog.
comment(sstr.str());
2086 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2100 +
"-" + package->edition().version()
2101 +
"-" + package->edition().release()
2102 +
"." + package->arch().asString(), flags );
2115 report->start( name_r );
2130 report->finish( excpt_r );
2147 MIL <<
"RpmDb::doRemovePackage(" << name_r <<
"," << flags <<
")" << endl;
2156 ERR <<
"backup of " << name_r <<
" failed" << endl;
2158 report->progress( 0 );
2162 report->progress( 100 );
2167 opts.push_back(
"-e");
2168 opts.push_back(
"--allmatches");
2171 opts.push_back(
"--noscripts");
2173 opts.push_back(
"--nodeps");
2175 opts.push_back(
"--justdb");
2177 opts.push_back (
"--test");
2180 WAR <<
"IGNORE OPTION: 'rpm -e' does not support '--force'" << endl;
2183 opts.push_back(
"--");
2184 opts.push_back(name_r.c_str());
2196 report->progress( 5 );
2197 unsigned linecnt = 0;
2204 rpmmsg += line+
'\n';
2207 rpmmsg +=
"[truncated]\n";
2208 report->progress( 50 );
2211 if ( rpm_status != 0 )
2214 str::form(
"%s remove failed", name_r.c_str()),
true );
2215 std::ostringstream sstr;
2216 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2217 historylog.
comment(sstr.str());
2221 else if ( ! rpmmsg.empty() )
2224 str::form(
"%s removed ok", name_r.c_str()),
true );
2226 std::ostringstream sstr;
2227 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2228 historylog.
comment(sstr.str());
2232 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2261 Pathname backupFilename;
2266 INT <<
"_backuppath empty" << endl;
2274 ERR <<
"Error while getting changed files for package " <<
2275 packageName << endl;
2279 if (fileList.size() <= 0)
2281 DBG <<
"package " << packageName <<
" not changed -> no backup" << endl;
2293 struct tm *currentLocalTime = localtime(¤tTime);
2295 int date = (currentLocalTime->tm_year + 1900) * 10000
2296 + (currentLocalTime->tm_mon + 1) * 100
2297 + currentLocalTime->tm_mday;
2303 +
str::form(
"%s-%d-%d.tar.gz",packageName.c_str(), date, num);
2306 while ( PathInfo(backupFilename).isExist() && num++ < 1000);
2308 PathInfo pi(filestobackupfile);
2309 if (pi.isExist() && !pi.isFile())
2311 ERR << filestobackupfile.asString() <<
" already exists and is no file" << endl;
2315 std::ofstream fp ( filestobackupfile.asString().c_str(), std::ios::out|std::ios::trunc );
2319 ERR <<
"could not open " << filestobackupfile.asString() << endl;
2323 for (FileList::const_iterator cit = fileList.begin();
2324 cit != fileList.end(); ++cit)
2326 std::string name = *cit;
2327 if ( name[0] ==
'/' )
2330 name = name.substr( 1 );
2332 DBG <<
"saving file "<< name << endl;
2337 const char*
const argv[] =
2342 _root.asString().c_str(),
2343 "--ignore-failed-read",
2345 backupFilename.asString().c_str(),
2347 filestobackupfile.asString().c_str(),
2363 int ret = tar.
close();
2367 ERR <<
"tar failed: " << tarmsg << endl;
2372 MIL <<
"tar backup ok" << endl;
2374 str::form(
_(
"created backup %s"), backupFilename.asString().c_str())
2393 #define OUTS(E,S) case RpmDb::E: return str << "["<< (unsigned)obj << "-"<< S << "]"; break 2405 OUTS(
CHK_ERROR,
_(
"File does not exist or signature can't be checked") );
2410 return str <<
"UnknowSignatureCheckError("+
str::numstring(obj)+
")";
2415 for (
const auto & el : obj )
2416 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 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