#include "zypp/base/Logger.h"
#include "zypp/base/String.h"
+#include "zypp/base/Regex.h"
#include "zypp/Date.h"
#include "zypp/Pathname.h"
#include "zypp/target/rpm/RpmDb.h"
#include "zypp/target/rpm/RpmCallbacks.h"
+#include "zypp/target/CommitLog.h"
#include "zypp/target/rpm/librpmDb.h"
#include "zypp/target/rpm/RpmPackageImpl.h"
#include "zypp/target/rpm/RpmException.h"
using namespace std;
using namespace zypp::filesystem;
-namespace zypp {
- namespace target {
- namespace rpm {
-
- struct KeyRingSignalReceiver : callback::ReceiveReport<KeyRingSignals>
- {
- KeyRingSignalReceiver(RpmDb &rpmdb) : _rpmdb(rpmdb)
- {
- connect();
- }
+namespace zypp
+{
+namespace target
+{
+namespace rpm
+{
+namespace
+{
+const char* quoteInFilename_m = " \t";
+inline string rpmQuoteFilename( const Pathname & path_r )
+{
+ string path( path_r.asString() );
+ for ( string::size_type pos = path.find_first_of( quoteInFilename_m );
+ pos != string::npos;
+ pos = path.find_first_of( quoteInFilename_m, pos ) )
+ {
+ path.insert( pos, "\\" );
+ pos += 2; // skip '\\' and the quoted char.
+ }
+ return path;
+}
+}
- ~KeyRingSignalReceiver()
- {
- disconnect();
- }
+struct KeyRingSignalReceiver : callback::ReceiveReport<KeyRingSignals>
+{
+ KeyRingSignalReceiver(RpmDb &rpmdb) : _rpmdb(rpmdb)
+ {
+ connect();
+ }
- virtual void trustedKeyAdded( const KeyRing &keyring, const PublicKey &key )
- {
- MIL << "trusted key added to zypp Keyring. Syncronizing keys with rpm keyring" << std::endl;
- _rpmdb.importZyppKeyRingTrustedKeys();
- _rpmdb.exportTrustedKeysInZyppKeyRing();
- }
+ ~KeyRingSignalReceiver()
+ {
+ disconnect();
+ }
- virtual void trustedKeyRemoved( const KeyRing &keyring, const PublicKey &key )
- {
+ virtual void trustedKeyAdded( const PublicKey &key )
+ {
+ MIL << "trusted key added to zypp Keyring. Importing" << endl;
+ // now import the key in rpm
+ try
+ {
+ _rpmdb.importPubkey( key );
+ }
+ catch (RpmException &e)
+ {
+ ERR << "Could not import key " << key.id() << " (" << key.name() << " from " << key.path() << " in rpm database" << endl;
+ }
+ }
- }
+ virtual void trustedKeyRemoved( const PublicKey &key )
+ {}
- RpmDb &_rpmdb;
- };
+ RpmDb &_rpmdb;
+};
- static shared_ptr<KeyRingSignalReceiver> sKeyRingReceiver;
+static shared_ptr<KeyRingSignalReceiver> sKeyRingReceiver;
-unsigned diffFiles(const std::string file1, const std::string file2, std::string& out, int maxlines)
+unsigned diffFiles(const string file1, const string file2, string& out, int maxlines)
{
- const char* argv[] =
+ const char* argv[] =
{
- "diff",
- "-u",
- file1.c_str(),
- file2.c_str(),
- NULL
+ "diff",
+ "-u",
+ file1.c_str(),
+ file2.c_str(),
+ NULL
};
- ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
+ ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
- //if(!prog)
- //return 2;
+ //if(!prog)
+ //return 2;
- string line;
- int count = 0;
- for(line = prog.receiveLine(), count=0;
- !line.empty();
- line = prog.receiveLine(), count++ )
- {
- if(maxlines<0?true:count<maxlines)
- out+=line;
- }
+ string line;
+ int count = 0;
+ for (line = prog.receiveLine(), count=0;
+ !line.empty();
+ line = prog.receiveLine(), count++ )
+ {
+ if (maxlines<0?true:count<maxlines)
+ out+=line;
+ }
- return prog.close();
+ return prog.close();
}
/******************************************************************
-**
-**
-** FUNCTION NAME : stringPath
-** FUNCTION TYPE : inline string
+ **
+ **
+ ** FUNCTION NAME : stringPath
+ ** FUNCTION TYPE : inline string
*/
inline string stringPath( const Pathname & root_r, const Pathname & sub_r )
{
}
/******************************************************************
-**
-**
-** FUNCTION NAME : operator<<
-** FUNCTION TYPE : ostream &
+ **
+ **
+ ** FUNCTION NAME : operator<<
+ ** FUNCTION TYPE : ostream &
*/
ostream & operator<<( ostream & str, const RpmDb::DbStateInfoBits & obj )
{
- if ( obj == RpmDb::DbSI_NO_INIT ) {
+ if ( obj == RpmDb::DbSI_NO_INIT )
+ {
str << "NO_INIT";
- } else {
+ }
+ else
+ {
#define ENUM_OUT(B,C) str << ( obj & RpmDb::B ? C : '-' )
str << "V4(";
ENUM_OUT( DbSI_HAVE_V4, 'X' );
///////////////////////////////////////////////////////////////////
//
-// CLASS NAME : RpmDb::Logfile
-/**
- * Simple wrapper for progress log. Refcnt, filename and corresponding
- * ofstream are static members. Logfile constructor raises, destructor
- * lowers refcounter. On refcounter changing from 0->1, file is opened.
- * Changing from 1->0 the file is closed. Thus Logfile objects should be
- * local to those functions, writing the log, and must not be stored
- * permanently;
- *
- * Usage:
- * some methothd ()
- * {
- * Logfile progresslog;
- * ...
- * progresslog() << "some message" << endl;
- * ...
- * }
- **/
-class RpmDb::Logfile {
- Logfile( const Logfile & );
- Logfile & operator=( const Logfile & );
- private:
- static ofstream _log;
- static unsigned _refcnt;
- static Pathname _fname;
- static void openLog() {
- if ( !_fname.empty() ) {
- _log.clear();
- _log.open( _fname.asString().c_str(), std::ios::out|std::ios::app );
- if( !_log )
- ERR << "Could not open logfile '" << _fname << "'" << endl;
- }
- }
- static void closeLog() {
- _log.clear();
- _log.close();
- }
- static void refUp() {
- if ( !_refcnt )
- openLog();
- ++_refcnt;
- }
- static void refDown() {
- --_refcnt;
- if ( !_refcnt )
- closeLog();
- }
- public:
- Logfile() { refUp(); }
- ~Logfile() { refDown(); }
- ostream & operator()( bool timestamp = false ) {
- if ( timestamp ) {
- _log << Date(Date::now()).form( "%Y-%m-%d %H:%M:%S ");
- }
- return _log;
- }
- static void setFname( const Pathname & fname_r ) {
- MIL << "installation log file " << fname_r << endl;
- if ( _refcnt )
- closeLog();
- _fname = fname_r;
- if ( _refcnt )
- openLog();
- }
-};
-
-///////////////////////////////////////////////////////////////////
-
-Pathname RpmDb::Logfile::_fname;
-ofstream RpmDb::Logfile::_log;
-unsigned RpmDb::Logfile::_refcnt = 0;
-
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-//
-// METHOD NAME : RpmDb::setInstallationLogfile
-// METHOD TYPE : bool
-//
-bool RpmDb::setInstallationLogfile( const Pathname & filename )
-{
- Logfile::setFname( filename );
- return true;
-}
-
-///////////////////////////////////////////////////////////////////
-//
// CLASS NAME : RpmDb::Packages
/**
* Helper class for RpmDb::getPackages() to build the
* in sync. So you may use lookup(PkgName) to retrieve a specific
* Package::Ptr.
**/
-class RpmDb::Packages {
- public:
- list<Package::Ptr> _list;
- map<std::string,Package::Ptr> _index;
- bool _valid;
- Packages() : _valid( false ) {}
- void clear() {
- _list.clear();
- _index.clear();
- _valid = false;
- }
- Package::Ptr lookup( const string & name_r ) const {
- map<string,Package::Ptr>::const_iterator got = _index.find( name_r );
- if ( got != _index.end() )
- return got->second;
- return Package::Ptr();
- }
- void buildIndex() {
- _index.clear();
- for ( list<Package::Ptr>::iterator iter = _list.begin();
- iter != _list.end(); ++iter )
+class RpmDb::Packages
+{
+public:
+ list<Package::Ptr> _list;
+ map<string,Package::Ptr> _index;
+ bool _valid;
+ Packages() : _valid( false )
+ {}
+ void clear()
+ {
+ _list.clear();
+ _index.clear();
+ _valid = false;
+ }
+ Package::Ptr lookup( const string & name_r ) const
+ {
+ map<string,Package::Ptr>::const_iterator got = _index.find( name_r );
+ if ( got != _index.end() )
+ return got->second;
+ return Package::Ptr();
+ }
+ void buildIndex()
+ {
+ _index.clear();
+ for ( list<Package::Ptr>::iterator iter = _list.begin();
+ iter != _list.end(); ++iter )
+ {
+ string name = (*iter)->name();
+ Package::Ptr & nptr = _index[name]; // be shure to get a reference!
+
+ if ( nptr )
+ {
+ WAR << "Multiple entries for package '" << name << "' in rpmdb" << endl;
+ if ( nptr->installtime() > (*iter)->installtime() )
+ continue;
+ else
+ nptr = *iter;
+ }
+ else
{
- string name = (*iter)->name();
- Package::Ptr & nptr = _index[name]; // be shure to get a reference!
-
- if ( nptr ) {
- WAR << "Multiple entries for package '" << name << "' in rpmdb" << endl;
- if ( nptr->installtime() > (*iter)->installtime() )
- continue;
- else
- nptr = *iter;
- }
- else
- {
- nptr = *iter;
- }
+ nptr = *iter;
}
- _valid = true;
}
+ _valid = true;
+ }
};
///////////////////////////////////////////////////////////////////
, _packagebackups(false)
, _warndirexists(false)
{
- process = 0;
- exit_code = -1;
+ process = 0;
+ exit_code = -1;
- // Some rpm versions are patched not to abort installation if
- // symlink creation failed.
- setenv( "RPM_IgnoreFailedSymlinks", "1", 1 );
- sKeyRingReceiver.reset(new KeyRingSignalReceiver(*this));
+ // Some rpm versions are patched not to abort installation if
+ // symlink creation failed.
+ setenv( "RPM_IgnoreFailedSymlinks", "1", 1 );
+ sKeyRingReceiver.reset(new KeyRingSignalReceiver(*this));
}
///////////////////////////////////////////////////////////////////
//
RpmDb::~RpmDb()
{
- MIL << "~RpmDb()" << endl;
- closeDatabase();
+ MIL << "~RpmDb()" << endl;
+ closeDatabase();
- delete process;
- delete &_packages;
- MIL << "~RpmDb() end" << endl;
- sKeyRingReceiver.reset();
+ delete process;
+ delete &_packages;
+ MIL << "~RpmDb() end" << endl;
+ sKeyRingReceiver.reset();
}
+Date RpmDb::timestamp() const
+{
+ Date ts_rpm;
+
+ Pathname db_path;
+ if ( dbPath().empty() )
+ db_path = "/var/lib/rpm";
+ else
+ db_path = dbPath();
+
+ PathInfo rpmdb_info(root() + db_path + "/Packages");
+
+ if ( rpmdb_info.isExist() )
+ return rpmdb_info.mtime();
+ else
+ return Date::now();
+}
///////////////////////////////////////////////////////////////////
//
//
// METHOD NAME : RpmDb::dumpOn
-// METHOD TYPE : std::ostream &
+// METHOD TYPE : ostream &
//
-std::ostream & RpmDb::dumpOn( std::ostream & str ) const
+ostream & RpmDb::dumpOn( ostream & str ) const
{
str << "RpmDb[";
- if ( _dbStateInfo == DbSI_NO_INIT ) {
+ if ( _dbStateInfo == DbSI_NO_INIT )
+ {
str << "NO_INIT";
- } else {
+ }
+ else
+ {
#define ENUM_OUT(B,C) str << ( _dbStateInfo & B ? C : '-' )
str << "V4(";
ENUM_OUT( DbSI_HAVE_V4, 'X' );
if ( dbPath_r.empty() )
dbPath_r = "/var/lib/rpm";
- if ( ! (root_r.absolute() && dbPath_r.absolute()) ) {
+ if ( ! (root_r.absolute() && dbPath_r.absolute()) )
+ {
ERR << "Illegal root or dbPath: " << stringPath( root_r, dbPath_r ) << endl;
ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r));
}
///////////////////////////////////////////////////////////////////
// Check whether already initialized
///////////////////////////////////////////////////////////////////
- if ( initialized() ) {
- if ( root_r == _root && dbPath_r == _dbPath ) {
+ if ( initialized() )
+ {
+ if ( root_r == _root && dbPath_r == _dbPath )
+ {
return;
- } else {
+ }
+ else
+ {
ZYPP_THROW(RpmDbAlreadyOpenException(_root, _dbPath, root_r, dbPath_r));
}
}
///////////////////////////////////////////////////////////////////
librpmDb::unblockAccess();
DbStateInfoBits info = DbSI_NO_INIT;
- try {
+ try
+ {
internal_initDatabase( root_r, dbPath_r, info );
}
catch (const RpmException & excpt_r)
librpmDb::blockAccess();
ERR << "Cleanup on error: state " << info << endl;
- if ( dbsi_has( info, DbSI_MADE_V4 ) ) {
+ if ( dbsi_has( info, DbSI_MADE_V4 ) )
+ {
// remove the newly created rpm4 database and
// any backup created on conversion.
removeV4( root_r + dbPath_r, dbsi_has( info, DbSI_MADE_V3TOV4 ) );
}
ZYPP_RETHROW(excpt_r);
}
- if ( dbsi_has( info, DbSI_HAVE_V3 ) ) {
- if ( root_r == "/" || dbsi_has( info, DbSI_MODIFIED_V4 ) ) {
+ if ( dbsi_has( info, DbSI_HAVE_V3 ) )
+ {
+ if ( root_r == "/" || dbsi_has( info, DbSI_MODIFIED_V4 ) )
+ {
// Move obsolete rpm3 database beside.
MIL << "Cleanup: state " << info << endl;
removeV3( root_r + dbPath_r, dbsi_has( info, DbSI_MADE_V3TOV4 ) );
dbsi_clr( info, DbSI_HAVE_V3 );
- } else {
- // Performing an update: Keep the original rpm3 database
- // and wait if the rpm4 database gets modified by installing
- // or removing packages. Cleanup in modifyDatabase or closeDatabase.
- MIL << "Update mode: Cleanup delayed until closeOldDatabase." << endl;
+ }
+ else
+ {
+ // Performing an update: Keep the original rpm3 database
+ // and wait if the rpm4 database gets modified by installing
+ // or removing packages. Cleanup in modifyDatabase or closeDatabase.
+ MIL << "Update mode: Cleanup delayed until closeOldDatabase." << endl;
}
}
#warning CHECK: notify root about conversion backup.
#warning Add rebuild database once have the info about context
#if 0
- if ( ! ( Y2PM::runningFromSystem() ) ) {
+ if ( ! ( Y2PM::runningFromSystem() ) )
+ {
if ( dbsi_has( info, DbSI_HAVE_V4 )
- && ! dbsi_has( info, DbSI_MADE_V4 ) ) {
+ && ! dbsi_has( info, DbSI_MADE_V4 ) )
+ {
err = rebuildDatabase();
}
}
#endif
- MIL << "Syncronizing keys with zypp keyring" << std::endl;
- importZyppKeyRingTrustedKeys();
+ MIL << "Syncronizing keys with zypp keyring" << endl;
+ // we do this one by one now.
+ //importZyppKeyRingTrustedKeys();
exportTrustedKeysInZyppKeyRing();
// Close the database in case any write acces (create/convert)
// METHOD TYPE : PMError
//
void RpmDb::internal_initDatabase( const Pathname & root_r, const Pathname & dbPath_r,
- DbStateInfoBits & info_r )
+ DbStateInfoBits & info_r )
{
info_r = DbSI_NO_INIT;
///////////////////////////////////////////////////////////////////
librpmDb::DbDirInfo dbInfo( root_r, dbPath_r );
- if ( dbInfo.illegalArgs() ) {
+ if ( dbInfo.illegalArgs() )
+ {
// should not happen (checked in initDatabase)
ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r));
}
- if ( ! dbInfo.usableArgs() ) {
+ if ( ! dbInfo.usableArgs() )
+ {
ERR << "Bad database directory: " << dbInfo.dbDir() << endl;
ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r));
}
- if ( dbInfo.hasDbV4() ) {
+ if ( dbInfo.hasDbV4() )
+ {
dbsi_set( info_r, DbSI_HAVE_V4 );
MIL << "Found rpm4 database in " << dbInfo.dbDir() << endl;
- } else {
+ }
+ else
+ {
MIL << "Creating new rpm4 database in " << dbInfo.dbDir() << endl;
}
- if ( dbInfo.hasDbV3() ) {
+ if ( dbInfo.hasDbV3() )
+ {
dbsi_set( info_r, DbSI_HAVE_V3 );
}
- if ( dbInfo.hasDbV3ToV4() ) {
+ if ( dbInfo.hasDbV3ToV4() )
+ {
dbsi_set( info_r, DbSI_HAVE_V3TOV4 );
}
// creates dbdir and empty rpm4 database if not present
librpmDb::dbAccess( root_r, dbPath_r );
- if ( ! dbInfo.hasDbV4() ) {
+ if ( ! dbInfo.hasDbV4() )
+ {
dbInfo.restat();
- if ( dbInfo.hasDbV4() ) {
+ if ( dbInfo.hasDbV4() )
+ {
dbsi_set( info_r, DbSI_HAVE_V4 | DbSI_MADE_V4 );
}
}
librpmDb::constPtr dbptr;
librpmDb::dbAccess( dbptr );
bool dbEmpty = dbptr->empty();
- if ( dbEmpty ) {
+ if ( dbEmpty )
+ {
MIL << "Empty rpm4 database " << dbInfo.dbV4() << endl;
}
- if ( dbInfo.hasDbV3() ) {
+ if ( dbInfo.hasDbV3() )
+ {
MIL << "Found rpm3 database " << dbInfo.dbV3() << endl;
- if ( dbEmpty ) {
+ if ( dbEmpty )
+ {
extern void convertV3toV4( const Pathname & v3db_r, const librpmDb::constPtr & v4db_r );
convertV3toV4( dbInfo.dbV3().path(), dbptr );
// create a backup copy
int res = filesystem::copy( dbInfo.dbV3().path(), dbInfo.dbV3ToV4().path() );
- if ( res ) {
- WAR << "Backup converted rpm3 database failed: error(" << res << ")" << endl;
- } else {
- dbInfo.restat();
- if ( dbInfo.hasDbV3ToV4() ) {
- MIL << "Backup converted rpm3 database: " << dbInfo.dbV3ToV4() << endl;
- dbsi_set( info_r, DbSI_HAVE_V3TOV4 | DbSI_MADE_V3TOV4 );
- }
+ if ( res )
+ {
+ WAR << "Backup converted rpm3 database failed: error(" << res << ")" << endl;
+ }
+ else
+ {
+ dbInfo.restat();
+ if ( dbInfo.hasDbV3ToV4() )
+ {
+ MIL << "Backup converted rpm3 database: " << dbInfo.dbV3ToV4() << endl;
+ dbsi_set( info_r, DbSI_HAVE_V3TOV4 | DbSI_MADE_V3TOV4 );
+ }
}
- } else {
+ }
+ else
+ {
WAR << "Non empty rpm3 and rpm4 database found: using rpm4" << endl;
#warning EXCEPTION: nonempty rpm4 and rpm3 database found.
librpmDb::dumpState( DBG ) << endl;
}
- if ( dbInfo.hasDbV3ToV4() ) {
+ if ( dbInfo.hasDbV3ToV4() )
+ {
MIL << "Rpm3 database backup: " << dbInfo.dbV3ToV4() << endl;
}
}
{
const char * v3backup = "packages.rpm3";
const char * master = "Packages";
- const char * index[] = {
- "Basenames",
- "Conflictname",
- "Depends",
- "Dirnames",
- "Filemd5s",
- "Group",
- "Installtid",
- "Name",
- "Providename",
- "Provideversion",
- "Pubkeys",
- "Requirename",
- "Requireversion",
- "Sha1header",
- "Sigmd5",
- "Triggername",
- // last entry!
- NULL
- };
+ const char * index[] =
+ {
+ "Basenames",
+ "Conflictname",
+ "Depends",
+ "Dirnames",
+ "Filemd5s",
+ "Group",
+ "Installtid",
+ "Name",
+ "Providename",
+ "Provideversion",
+ "Pubkeys",
+ "Requirename",
+ "Requireversion",
+ "Sha1header",
+ "Sigmd5",
+ "Triggername",
+ // last entry!
+ NULL
+ };
PathInfo pi( dbdir_r );
- if ( ! pi.isDir() ) {
+ if ( ! pi.isDir() )
+ {
ERR << "Can't remove rpm4 database in non directory: " << dbdir_r << endl;
return;
}
- for ( const char ** f = index; *f; ++f ) {
+ for ( const char ** f = index; *f; ++f )
+ {
pi( dbdir_r + *f );
- if ( pi.isFile() ) {
+ if ( pi.isFile() )
+ {
filesystem::unlink( pi.path() );
}
}
pi( dbdir_r + master );
- if ( pi.isFile() ) {
+ if ( pi.isFile() )
+ {
MIL << "Removing rpm4 database " << pi << endl;
filesystem::unlink( pi.path() );
}
- if ( v3backup_r ) {
+ if ( v3backup_r )
+ {
pi( dbdir_r + v3backup );
- if ( pi.isFile() ) {
+ if ( pi.isFile() )
+ {
MIL << "Removing converted rpm3 database backup " << pi << endl;
filesystem::unlink( pi.path() );
}
void RpmDb::removeV3( const Pathname & dbdir_r, bool v3backup_r )
{
const char * master = "packages.rpm";
- const char * index[] = {
- "conflictsindex.rpm",
- "fileindex.rpm",
- "groupindex.rpm",
- "nameindex.rpm",
- "providesindex.rpm",
- "requiredby.rpm",
- "triggerindex.rpm",
- // last entry!
- NULL
- };
+ const char * index[] =
+ {
+ "conflictsindex.rpm",
+ "fileindex.rpm",
+ "groupindex.rpm",
+ "nameindex.rpm",
+ "providesindex.rpm",
+ "requiredby.rpm",
+ "triggerindex.rpm",
+ // last entry!
+ NULL
+ };
PathInfo pi( dbdir_r );
- if ( ! pi.isDir() ) {
+ if ( ! pi.isDir() )
+ {
ERR << "Can't remove rpm3 database in non directory: " << dbdir_r << endl;
return;
}
- for ( const char ** f = index; *f; ++f ) {
+ for ( const char ** f = index; *f; ++f )
+ {
pi( dbdir_r + *f );
- if ( pi.isFile() ) {
+ if ( pi.isFile() )
+ {
filesystem::unlink( pi.path() );
}
}
#warning CHECK: compare vs existing v3 backup. notify root
pi( dbdir_r + master );
- if ( pi.isFile() ) {
+ if ( pi.isFile() )
+ {
Pathname m( pi.path() );
- if ( v3backup_r ) {
+ if ( v3backup_r )
+ {
// backup was already created
filesystem::unlink( m );
Pathname b( m.extend( "3" ) );
pi( b ); // stat backup
- } else {
+ }
+ else
+ {
Pathname b( m.extend( ".deleted" ) );
pi( b );
- if ( pi.isFile() ) {
- // rempve existing backup
- filesystem::unlink( b );
+ if ( pi.isFile() )
+ {
+ // rempve existing backup
+ filesystem::unlink( b );
}
filesystem::rename( m, b );
pi( b ); // stat backup
dbsi_set( _dbStateInfo, DbSI_MODIFIED_V4 );
// Move outdated rpm3 database beside.
- if ( dbsi_has( _dbStateInfo, DbSI_HAVE_V3 ) ) {
+ if ( dbsi_has( _dbStateInfo, DbSI_HAVE_V3 ) )
+ {
MIL << "Update mode: Delayed cleanup: state " << _dbStateInfo << endl;
removeV3( _root + _dbPath, dbsi_has( _dbStateInfo, DbSI_MADE_V3TOV4 ) );
dbsi_clr( _dbStateInfo, DbSI_HAVE_V3 );
//
void RpmDb::closeDatabase()
{
- if ( ! initialized() ) {
+ if ( ! initialized() )
+ {
return;
}
///////////////////////////////////////////////////////////////////
// Check fate if old version database still present
///////////////////////////////////////////////////////////////////
- if ( dbsi_has( _dbStateInfo, DbSI_HAVE_V3 ) ) {
+ if ( dbsi_has( _dbStateInfo, DbSI_HAVE_V3 ) )
+ {
MIL << "Update mode: Delayed cleanup: state " << _dbStateInfo << endl;
- if ( dbsi_has( _dbStateInfo, DbSI_MODIFIED_V4 ) ) {
+ if ( dbsi_has( _dbStateInfo, DbSI_MODIFIED_V4 ) )
+ {
// Move outdated rpm3 database beside.
removeV3( _root + _dbPath, dbsi_has( _dbStateInfo, DbSI_MADE_V3TOV4 ) );
- } else {
+ }
+ else
+ {
// Remove unmodified rpm4 database
removeV4( _root + _dbPath, dbsi_has( _dbStateInfo, DbSI_MADE_V3TOV4 ) );
}
report->start( root() + dbPath() );
- try {
+ try
+ {
doRebuildDatabase(report);
}
catch (RpmException & excpt_r)
FAILIFNOTINITIALIZED;
MIL << "RpmDb::rebuildDatabase" << *this << endl;
-// FIXME Timecount _t( "RpmDb::rebuildDatabase" );
+ // FIXME Timecount _t( "RpmDb::rebuildDatabase" );
PathInfo dbMaster( root() + dbPath() + "Packages" );
PathInfo dbMasterBackup( dbMaster.path().extend( ".y2backup" ) );
// progress report: watch this file growing
PathInfo newMaster( root()
- + dbPath().extend( str::form( "rebuilddb.%d",
- process?process->getpid():0) )
- + "Packages" );
+ + dbPath().extend( str::form( "rebuilddb.%d",
+ process?process->getpid():0) )
+ + "Packages" );
string line;
string errmsg;
- while ( systemReadLine( line ) ) {
- if ( newMaster() ) { // file is removed at the end of rebuild.
+ while ( systemReadLine( line ) )
+ {
+ if ( newMaster() )
+ { // file is removed at the end of rebuild.
// current size should be upper limit for new db
report->progress( (100 * newMaster.size()) / dbMaster.size(), root() + dbPath());
}
- if ( line.compare( 0, 2, "D:" ) ) {
+ if ( line.compare( 0, 2, "D:" ) )
+ {
errmsg += line + '\n';
-// report.notify( line );
+ // report.notify( line );
WAR << line << endl;
}
}
int rpm_status = systemStatus();
- if ( rpm_status != 0 ) {
+ if ( rpm_status != 0 )
+ {
ZYPP_THROW(RpmSubprocessException(string("rpm failed with message: ") + errmsg));
- } else {
+ }
+ else
+ {
report->progress( 100, root() + dbPath() ); // 100%
}
}
void RpmDb::exportTrustedKeysInZyppKeyRing()
{
- MIL << "Exporting rpm keyring into zypp trusted keyring" <<std::endl;
+ MIL << "Exporting rpm keyring into zypp trusted keyring" <<endl;
- std::set<Edition> rpm_keys = pubkeyEditions();
+ set<Edition> rpm_keys = pubkeyEditions();
- std::list<PublicKey> zypp_keys;
+ list<PublicKey> zypp_keys;
zypp_keys = getZYpp()->keyRing()->trustedPublicKeys();
- for ( std::set<Edition>::const_iterator it = rpm_keys.begin(); it != rpm_keys.end(); ++it)
+ for ( set<Edition>::const_iterator it = rpm_keys.begin(); it != rpm_keys.end(); ++it)
{
// search the zypp key into the rpm keys
// long id is edition version + release
- std::string id = str::toUpper( (*it).version() + (*it).release());
- std::list<PublicKey>::iterator ik = find( zypp_keys.begin(), zypp_keys.end(), id);
+ string id = str::toUpper( (*it).version() + (*it).release());
+ list<PublicKey>::iterator ik = find( zypp_keys.begin(), zypp_keys.end(), id);
if ( ik != zypp_keys.end() )
{
- MIL << "Key " << (*it) << " is already in zypp database." << std::endl;
+ MIL << "Key " << (*it) << " is already in zypp database." << endl;
}
else
{
// we export the rpm key into a file
RpmHeader::constPtr result = new RpmHeader();
- getData( std::string("gpg-pubkey"), *it, result );
+ getData( string("gpg-pubkey"), *it, result );
TmpFile file(getZYpp()->tmpPath());
- std::ofstream os;
+ ofstream os;
try
{
os.open(file.path().asString().c_str());
// dump rpm key into the tmp file
os << result->tag_description();
- //MIL << "-----------------------------------------------" << std::endl;
- //MIL << result->tag_description() <<std::endl;
- //MIL << "-----------------------------------------------" << std::endl;
+ //MIL << "-----------------------------------------------" << endl;
+ //MIL << result->tag_description() <<endl;
+ //MIL << "-----------------------------------------------" << endl;
os.close();
}
- catch (std::exception &e)
+ catch (exception &e)
{
- ERR << "Could not dump key " << (*it) << " in tmp file " << file.path() << std::endl;
+ ERR << "Could not dump key " << (*it) << " in tmp file " << file.path() << endl;
// just ignore the key
}
try
{
getZYpp()->keyRing()->importKey( file.path(), true /*trusted*/);
- MIL << "Trusted key " << (*it) << " imported in zypp keyring." << std::endl;
+ MIL << "Trusted key " << (*it) << " imported in zypp keyring." << endl;
}
catch (Exception &e)
{
- ERR << "Could not import key " << (*it) << " in zypp keyring" << std::endl;
- }
- }
- }
-}
-
-void RpmDb::importZyppKeyRingTrustedKeys()
-{
- MIL << "Importing zypp trusted keyring" << std::endl;
-
- std::list<PublicKey> rpm_keys = pubkeys();
-
- std::list<PublicKey> zypp_keys;
-
- zypp_keys = getZYpp()->keyRing()->trustedPublicKeys();
-
- for ( std::list<PublicKey>::const_iterator it = zypp_keys.begin(); it != zypp_keys.end(); ++it)
- {
- // we find only the left part of the long gpg key, as rpm does not support long ids
- std::list<PublicKey>::iterator ik = find( rpm_keys.begin(), rpm_keys.end(), (*it));
- if ( ik != rpm_keys.end() )
- {
- MIL << "Key " << (*it).id() << " (" << (*it).name() << ") is already in rpm database." << std::endl;
- }
- else
- {
- // now import the key in rpm
- try
- {
- importPubkey((*it).path());
- MIL << "Trusted key " << (*it).id() << " (" << (*it).name() << ") imported in rpm database." << std::endl;
- }
- catch (RpmException &e)
- {
- ERR << "Could not import key " << (*it).id() << " (" << (*it).name() << " from " << (*it).path() << " in rpm database" << std::endl;
+ ERR << "Could not import key " << (*it) << " in zypp keyring" << endl;
}
}
}
// METHOD NAME : RpmDb::importPubkey
// METHOD TYPE : PMError
//
-void RpmDb::importPubkey( const Pathname & pubkey_r )
+void RpmDb::importPubkey( const PublicKey & pubkey_r )
{
FAILIFNOTINITIALIZED;
+ // check if the key is already in the rpm database and just
+ // return if it does.
+ set<Edition> rpm_keys = pubkeyEditions();
+ for ( set<Edition>::const_iterator it = rpm_keys.begin(); it != rpm_keys.end(); ++it)
+ {
+ string id = str::toUpper( (*it).version() );
+ string keyshortid = pubkey_r.id().substr(8,8);
+ MIL << "Comparing '" << id << "' to '" << keyshortid << "'" << endl;
+ if ( id == keyshortid )
+ {
+ // they match id
+ // FIXME id is not sufficient?
+ MIL << "Key " << pubkey_r << " is already in the rpm trusted keyring." << endl;
+ return;
+ }
+ }
+ // key does not exists, lets import it
+
RpmArgVec opts;
opts.push_back ( "--import" );
opts.push_back ( "--" );
- opts.push_back ( pubkey_r.asString().c_str() );
+ opts.push_back ( pubkey_r.path().asString().c_str() );
// don't call modifyDatabase because it would remove the old
// rpm3 database, if the current database is a temporary one.
run_rpm( opts, ExternalProgram::Stderr_To_Stdout );
string line;
- while ( systemReadLine( line ) ) {
- if ( line.substr( 0, 6 ) == "error:" ) {
+ while ( systemReadLine( line ) )
+ {
+ if ( line.substr( 0, 6 ) == "error:" )
+ {
WAR << line << endl;
- } else {
+ }
+ else
+ {
DBG << line << endl;
}
}
int rpm_status = systemStatus();
- if ( rpm_status != 0 ) {
+ if ( rpm_status != 0 )
+ {
ZYPP_THROW(RpmSubprocessException(string("Failed to import public key from file ") + pubkey_r.asString() + string(": rpm returned ") + str::numstring(rpm_status)));
- } else {
- MIL << "Imported public key from file " << pubkey_r << endl;
+ }
+ else
+ {
+ MIL << "Key " << pubkey_r << " imported in rpm trusted keyring." << endl;
}
}
{
// we export the rpm key into a file
RpmHeader::constPtr result = new RpmHeader();
- getData( std::string("gpg-pubkey"), edition, result );
+ getData( string("gpg-pubkey"), edition, result );
TmpFile file(getZYpp()->tmpPath());
- std::ofstream os;
+ ofstream os;
try
{
os.open(file.path().asString().c_str());
// dump rpm key into the tmp file
os << result->tag_description();
- //MIL << "-----------------------------------------------" << std::endl;
- //MIL << result->tag_description() <<std::endl;
- //MIL << "-----------------------------------------------" << std::endl;
+ //MIL << "-----------------------------------------------" << endl;
+ //MIL << result->tag_description() <<endl;
+ //MIL << "-----------------------------------------------" << endl;
os.close();
// read the public key from the dumped file
PublicKey key(file.path());
ret.push_back(key);
}
- catch (std::exception &e)
+ catch (exception &e)
{
- ERR << "Could not dump key " << edition.asString() << " in tmp file " << file.path() << std::endl;
+ ERR << "Could not dump key " << edition.asString() << " in tmp file " << file.path() << endl;
// just ignore the key
}
}
}
set<Edition> RpmDb::pubkeyEditions() const
-{
- set<Edition> ret;
+ {
+ set<Edition> ret;
- librpmDb::db_const_iterator it;
- for ( it.findByName( string( "gpg-pubkey" ) ); *it; ++it ) {
- Edition edition = it->tag_edition();
- if (edition != Edition::noedition)
- ret.insert( edition );
+ librpmDb::db_const_iterator it;
+ for ( it.findByName( string( "gpg-pubkey" ) ); *it; ++it )
+ {
+ Edition edition = it->tag_edition();
+ if (edition != Edition::noedition)
+ ret.insert( edition );
+ }
+ return ret;
}
- return ret;
-}
///////////////////////////////////////////////////////////////////
//
//
//
// METHOD NAME : RpmDb::getPackages
-// METHOD TYPE : const std::list<Package::Ptr> &
+// METHOD TYPE : const list<Package::Ptr> &
//
// DESCRIPTION :
//
-const std::list<Package::Ptr> & RpmDb::getPackages()
+const list<Package::Ptr> & RpmDb::getPackages()
{
callback::SendReport<ScanDBReport> report;
report->start ();
- try {
- const std::list<Package::Ptr> & ret = doGetPackages(report);
+ try
+ {
+ const list<Package::Ptr> & ret = doGetPackages(report);
report->finish(ScanDBReport::NO_ERROR, "");
return ret;
}
ZYPP_RETHROW(excpt_r);
}
#warning fixme
- static const std::list<Package::Ptr> empty_list;
+ static const list<Package::Ptr> empty_list;
return empty_list;
}
+inline static void insertCaps( CapSet &capset, capability::CapabilityImplPtrSet ptrset, CapFactory &factory )
+{
+ for ( capability::CapabilityImplPtrSet::const_iterator it = ptrset.begin();
+ it != ptrset.end();
+ ++it )
+ {
+ capset.insert( factory.fromImpl(*it) );
+ }
+}
//
// make Package::Ptr from RpmHeader
// return NULL on error
//
-Package::Ptr RpmDb::makePackageFromHeader( const RpmHeader::constPtr header, std::set<std::string> * filerequires, const Pathname & location, Source_Ref source )
+Package::Ptr RpmDb::makePackageFromHeader( const RpmHeader::constPtr header,
+ set<string> * filerequires,
+ const Pathname & location, Repository repo )
{
- if ( ! header )
- return 0;
+ if ( ! header )
+ return 0;
- if ( header->isSrc() )
- {
- WAR << "Can't make Package from SourcePackage header" << endl;
- return 0;
- }
+ if ( header->isSrc() )
+ {
+ WAR << "Can't make Package from SourcePackage header" << endl;
+ return 0;
+ }
- Package::Ptr pptr;
+ Package::Ptr pptr;
- string name = header->tag_name();
+ string name = header->tag_name();
- // create dataprovider
- detail::ResImplTraits<RPMPackageImpl>::Ptr impl( new RPMPackageImpl( header ) );
+ // create dataprovider
+ detail::ResImplTraits<RPMPackageImpl>::Ptr impl( new RPMPackageImpl( header ) );
- impl->setSource( source );
- if (!location.empty())
- impl->setLocation( location );
+ impl->setRepository( repo );
+ if (!location.empty())
+ impl->setLocation( OnMediaLocation(location,1) );
- Edition edition;
- try {
- edition = Edition( header->tag_version(),
- header->tag_release(),
- header->tag_epoch());
- }
- catch (Exception & excpt_r) {
- ZYPP_CAUGHT( excpt_r );
- WAR << "Package " << name << " has bad edition '"
- << (header->tag_epoch().empty()?"":(header->tag_epoch()+":"))
- << header->tag_version()
- << (header->tag_release().empty()?"":(string("-") + header->tag_release())) << "'";
- return pptr;
- }
+ Edition edition;
+ try
+ {
+ edition = Edition( header->tag_version(),
+ header->tag_release(),
+ header->tag_epoch());
+ }
+ catch (Exception & excpt_r)
+ {
+ ZYPP_CAUGHT( excpt_r );
+ WAR << "Package " << name << " has bad edition '"
+ << (header->tag_epoch().empty()?"":(header->tag_epoch()+":"))
+ << header->tag_version()
+ << (header->tag_release().empty()?"":(string("-") + header->tag_release())) << "'";
+ return pptr;
+ }
- Arch arch;
- try {
- arch = Arch( header->tag_arch() );
- }
- catch (Exception & excpt_r) {
- ZYPP_CAUGHT( excpt_r );
- WAR << "Package " << name << " has bad architecture '" << header->tag_arch() << "'";
- return pptr;
- }
+ Arch arch;
+ try
+ {
+ arch = Arch( header->tag_arch() );
+ }
+ catch (Exception & excpt_r)
+ {
+ ZYPP_CAUGHT( excpt_r );
+ WAR << "Package " << name << " has bad architecture '" << header->tag_arch() << "'";
+ return pptr;
+ }
- // Collect basic Resolvable data
- NVRAD dataCollect( header->tag_name(),
- edition,
- arch );
+ // Collect basic Resolvable data
+ NVRAD dataCollect( header->tag_name(),
+ edition,
+ arch );
- list<string> filenames = impl->filenames();
- dataCollect[Dep::PROVIDES] = header->tag_provides ( filerequires );
- CapFactory capfactory;
+ list<string> filenames = impl->filenames();
+ CapFactory capfactory;
+ insertCaps( dataCollect[Dep::PROVIDES], header->tag_provides( filerequires ), capfactory );
- static str::smatch what;
- static const str::regex filenameRegex( "/(s?bin|lib(64)?|etc)/|^/usr/(games/|share/(dict/words|magic\\.mime)$)|^/opt/gnome/games/",
- str::regex::optimize|str::regex::nosubs );
+ static str::smatch what;
+ static const str::regex filenameRegex( "/(s?bin|lib(64)?|etc)/|^/usr/(games/|share/(dict/words|magic\\.mime)$)|^/opt/gnome/games/",
+ str::regex::optimize|str::regex::nosubs );
- for (list<string>::const_iterator filename = filenames.begin();
- filename != filenames.end();
- ++filename)
+ for (list<string>::const_iterator filename = filenames.begin();
+ filename != filenames.end();
+ ++filename)
+ {
+ if ( str::regex_match( *filename, what, filenameRegex ) )
{
- if ( str::regex_search( filename->begin(), filename->end(), what, filenameRegex ) )
- {
- try {
- dataCollect[Dep::PROVIDES].insert( capfactory.parse(ResTraits<Package>::kind, *filename) );
- }
- catch (Exception & excpt_r)
- {
- ZYPP_CAUGHT( excpt_r );
- WAR << "Ignoring invalid capability: " << *filename << endl;
- }
+ try
+ {
+ dataCollect[Dep::PROVIDES].insert(capfactory.fromImpl(capability::buildFile(ResTraits<Package>::kind, *filename) ));
+ }
+ catch (Exception & excpt_r)
+ {
+ ZYPP_CAUGHT( excpt_r );
+ WAR << "Ignoring invalid capability: " << *filename << endl;
}
}
+ }
- dataCollect[Dep::REQUIRES] = header->tag_requires( filerequires );
- dataCollect[Dep::PREREQUIRES] = header->tag_prerequires( filerequires );
- dataCollect[Dep::CONFLICTS] = header->tag_conflicts( filerequires );
- dataCollect[Dep::OBSOLETES] = header->tag_obsoletes( filerequires );
- dataCollect[Dep::ENHANCES] = header->tag_enhances( filerequires );
- dataCollect[Dep::SUPPLEMENTS] = header->tag_supplements( filerequires );
+ insertCaps( dataCollect[Dep::REQUIRES], header->tag_requires( filerequires ), capfactory );
+ insertCaps( dataCollect[Dep::PREREQUIRES], header->tag_prerequires( filerequires ), capfactory );
+ insertCaps( dataCollect[Dep::CONFLICTS], header->tag_conflicts( filerequires ), capfactory );
+ insertCaps( dataCollect[Dep::OBSOLETES], header->tag_obsoletes( filerequires ), capfactory );
+ insertCaps( dataCollect[Dep::ENHANCES], header->tag_enhances( filerequires ), capfactory );
+ insertCaps( dataCollect[Dep::SUPPLEMENTS], header->tag_supplements( filerequires ), capfactory );
- try {
- // create package from dataprovider
- pptr = detail::makeResolvableFromImpl( dataCollect, impl );
- }
- catch (Exception & excpt_r) {
- ZYPP_CAUGHT( excpt_r );
- ERR << "Can't create Package::Ptr" << endl;
- }
+ try
+ {
+ // create package from dataprovider
+ pptr = detail::makeResolvableFromImpl( dataCollect, impl );
+ }
+ catch (Exception & excpt_r)
+ {
+ ZYPP_CAUGHT( excpt_r );
+ ERR << "Can't create Package::Ptr" << endl;
+ }
- return pptr;
+ return pptr;
}
-
-const std::list<Package::Ptr> & RpmDb::doGetPackages(callback::SendReport<ScanDBReport> & report)
+const list<Package::Ptr> & RpmDb::doGetPackages(callback::SendReport<ScanDBReport> & report)
{
- if ( packagesValid() ) {
+ if ( packagesValid() )
+ {
return _packages._list;
}
CapFactory _f;
Pathname location;
- for ( iter.findAll(); *iter; ++iter, ++current, report->progress( (100*current)/expect)) {
+ for ( iter.findAll(); *iter; ++iter, ++current, report->progress( (100*current)/expect))
+ {
string name = iter->tag_name();
- if ( name == string( "gpg-pubkey" ) ) {
+ if ( name == string( "gpg-pubkey" ) )
+ {
DBG << "Ignoring pseudo package " << name << endl;
// pseudo package filtered, as we can't handle multiple instances
// of 'gpg-pubkey-VERS-REL'.
continue;
}
- Date installtime = iter->tag_installtime();
- Package::Ptr pptr = makePackageFromHeader( *iter, &_filerequires, location, Source_Ref() );
+ Package::Ptr pptr = makePackageFromHeader( *iter, &_filerequires, location, Repository() );
+ if ( ! pptr )
+ {
+ WAR << "Failed to make package from database header '" << name << "'" << endl;
+ continue;
+ }
_packages._list.push_back( pptr );
}
///////////////////////////////////////////////////////////////////
// Evaluate filerequires collected so far
///////////////////////////////////////////////////////////////////
- for( set<string>::iterator it = _filerequires.begin(); it != _filerequires.end(); ++it ) {
+ for ( set<string>::iterator it = _filerequires.begin(); it != _filerequires.end(); ++it )
+ {
- for ( iter.findByFile( *it ); *iter; ++iter ) {
- Package::Ptr pptr = _packages.lookup( iter->tag_name() );
- if ( !pptr ) {
- WAR << "rpmdb.findByFile returned unknown package " << *iter << endl;
- continue;
+ for ( iter.findByFile( *it ); *iter; ++iter )
+ {
+ Package::Ptr pptr = _packages.lookup( iter->tag_name() );
+ if ( !pptr )
+ {
+ WAR << "rpmdb.findByFile returned unknown package " << *iter << endl;
+ continue;
+ }
+ pptr->injectProvides(_f.parse(ResTraits<Package>::kind, *it));
}
- pptr->injectProvides(_f.parse(ResTraits<Package>::kind, *it));
- }
- }
+ }
///////////////////////////////////////////////////////////////////
// Build final packages list
//
// DESCRIPTION :
//
-std::list<FileInfo>
-RpmDb::fileList( const std::string & name_r, const Edition & edition_r ) const
+list<FileInfo>
+RpmDb::fileList( const string & name_r, const Edition & edition_r ) const
{
- std::list<FileInfo> result;
+ list<FileInfo> result;
librpmDb::db_const_iterator it;
bool found;
- if (edition_r == Edition::noedition) {
- found = it.findPackage( name_r );
+ if (edition_r == Edition::noedition)
+ {
+ found = it.findPackage( name_r );
}
- else {
- found = it.findPackage( name_r, edition_r );
+ else
+ {
+ found = it.findPackage( name_r, edition_r );
}
if (!found)
return result;
//
// DESCRIPTION :
//
-bool RpmDb::hasFile( const std::string & file_r, const std::string & name_r ) const
+bool RpmDb::hasFile( const string & file_r, const string & name_r ) const
{
librpmDb::db_const_iterator it;
bool res;
- do {
+ do
+ {
res = it.findByFile( file_r );
if (!res) break;
- if (!name_r.empty()) {
+ if (!name_r.empty())
+ {
res = (it->tag_name() == name_r);
}
++it;
- } while (res && *it);
+ }
+ while (res && *it);
return res;
}
//
// DESCRIPTION :
//
-std::string RpmDb::whoOwnsFile( const std::string & file_r) const
+string RpmDb::whoOwnsFile( const string & file_r) const
{
librpmDb::db_const_iterator it;
- if (it.findByFile( file_r )) {
+ if (it.findByFile( file_r ))
+ {
return it->tag_name();
}
return "";
//
// DESCRIPTION :
//
-bool RpmDb::hasProvides( const std::string & tag_r ) const
+bool RpmDb::hasProvides( const string & tag_r ) const
{
librpmDb::db_const_iterator it;
return it.findByProvides( tag_r );
//
// DESCRIPTION :
//
-bool RpmDb::hasRequiredBy( const std::string & tag_r ) const
+bool RpmDb::hasRequiredBy( const string & tag_r ) const
{
librpmDb::db_const_iterator it;
return it.findByRequiredBy( tag_r );
//
// DESCRIPTION :
//
-bool RpmDb::hasConflicts( const std::string & tag_r ) const
+bool RpmDb::hasConflicts( const string & tag_r ) const
{
librpmDb::db_const_iterator it;
return it.findByConflicts( tag_r );
// DESCRIPTION :
//
void RpmDb::getData( const string & name_r,
- RpmHeader::constPtr & result_r ) const
+ RpmHeader::constPtr & result_r ) const
{
librpmDb::db_const_iterator it;
it.findPackage( name_r );
//
//
// METHOD NAME : RpmDb::getData
-// METHOD TYPE : PMError
+// METHOD TYPE : void
//
// DESCRIPTION :
//
-void RpmDb::getData( const std::string & name_r, const Edition & ed_r,
- RpmHeader::constPtr & result_r ) const
+void RpmDb::getData( const string & name_r, const Edition & ed_r,
+ RpmHeader::constPtr & result_r ) const
{
librpmDb::db_const_iterator it;
it.findPackage( name_r, ed_r );
ZYPP_THROW(*(it.dbError()));
}
-/*--------------------------------------------------------------*/
-/* Checking the source rpm <rpmpath> with rpm --chcksig and */
-/* the version number. */
-/*--------------------------------------------------------------*/
-unsigned
-RpmDb::checkPackage (const Pathname & packagePath, string version, string md5 )
+///////////////////////////////////////////////////////////////////
+//
+// METHOD NAME : RpmDb::checkPackage
+// METHOD TYPE : RpmDb::checkPackageResult
+//
+RpmDb::checkPackageResult RpmDb::checkPackage( const Pathname & path_r )
{
- unsigned result = 0;
-
- if ( ! version.empty() ) {
- RpmHeader::constPtr h( RpmHeader::readPackage( packagePath, RpmHeader::NOSIGNATURE ) );
- if ( ! h || Edition( version ) != h->tag_edition() ) {
- result |= CHK_INCORRECT_VERSION;
- }
- }
-
- if(!md5.empty())
- {
-#warning TBD MD5 check
- WAR << "md5sum check not yet implemented" << endl;
- return CHK_INCORRECT_FILEMD5;
- }
-
- std::string path = packagePath.asString();
- // checking --checksig
- const char *const argv[] = {
- "rpm", "--checksig", "--", path.c_str(), 0
- };
-
- exit_code = -1;
-
- string output = "";
- unsigned int k;
- for ( k = 0; k < (sizeof(argv) / sizeof(*argv)) -1; k++ )
- {
- output = output + " " + argv[k];
- }
-
- DBG << "rpm command: " << output << endl;
-
- if ( process != NULL )
- {
- delete process;
- process = NULL;
- }
- // Launch the program
- process = new ExternalProgram( argv, ExternalProgram::Stderr_To_Stdout, false, -1, true);
-
+ PathInfo file( path_r );
+ if ( ! file.isFile() )
+ {
+ ERR << "Not a file: " << file << endl;
+ return CHK_ERROR;
+ }
- if ( process == NULL )
- {
- result |= CHK_OTHER_FAILURE;
- DBG << "create process failed" << endl;
- }
+ FD_t fd = ::Fopen( file.asString().c_str(), "r.ufdio" );
+ if ( fd == 0 || ::Ferror(fd) )
+ {
+ ERR << "Can't open file for reading: " << file << " (" << ::Fstrerror(fd) << ")" << endl;
+ if ( fd )
+ ::Fclose( fd );
+ return CHK_ERROR;
+ }
- string value;
- output = process->receiveLine();
+ rpmts ts = ::rpmtsCreate();
+ ::rpmtsSetRootDir( ts, root().asString().c_str() );
+ ::rpmtsSetVSFlags( ts, RPMVSF_DEFAULT );
+ int res = ::rpmReadPackageFile( ts, fd, path_r.asString().c_str(), NULL );
+ ts = ::rpmtsFree(ts);
- while ( output.length() > 0)
- {
- string::size_type ret;
-
- // extract \n
- ret = output.find_first_of ( "\n" );
- if ( ret != string::npos )
- {
- value.assign ( output, 0, ret );
- }
- else
- {
- value = output;
- }
-
- DBG << "stdout: " << value << endl;
-
- string::size_type pos;
- if((pos = value.find (path)) != string::npos)
- {
- string rest = value.substr (pos + path.length() + 1);
- if (rest.find("NOT OK") == string::npos)
- {
- // see what checks are ok
- if (rest.find("md5") == string::npos)
- {
- result |= CHK_MD5SUM_MISSING;
- }
- if (rest.find("gpg") == string::npos)
- {
- result |= CHK_GPGSIG_MISSING;
- }
- }
- else
- {
- // see what checks are not ok
- if (rest.find("MD5") != string::npos)
- {
- result |= CHK_INCORRECT_PKGMD5;
- }
- else
- {
- result |= CHK_MD5SUM_MISSING;
- }
-
- if (rest.find("GPG") != string::npos)
- {
- result |= CHK_INCORRECT_GPGSIG;
- }
- else
- {
- result |= CHK_GPGSIG_MISSING;
- }
- }
- }
-
- output = process->receiveLine();
- }
+ ::Fclose( fd );
- if ( result == 0 && systemStatus() != 0 )
- {
- // error
- result |= CHK_OTHER_FAILURE;
- }
-
- return ( result );
+ switch ( res )
+ {
+ case RPMRC_OK:
+ return CHK_OK;
+ break;
+ case RPMRC_NOTFOUND:
+ WAR << "Signature is unknown type. " << file << endl;
+ return CHK_NOTFOUND;
+ break;
+ case RPMRC_FAIL:
+ WAR << "Signature does not verify. " << file << endl;
+ return CHK_FAIL;
+ break;
+ case RPMRC_NOTTRUSTED:
+ WAR << "Signature is OK, but key is not trusted. " << file << endl;
+ return CHK_NOTTRUSTED;
+ break;
+ case RPMRC_NOKEY:
+ WAR << "Public key is unavailable. " << file << endl;
+ return CHK_NOKEY;
+ break;
+ }
+ ERR << "Error reading header." << file << endl;
+ return CHK_ERROR;
}
// determine changed files of installed package
bool
RpmDb::queryChangedFiles(FileList & fileList, const string& packageName)
{
- bool ok = true;
+ bool ok = true;
- fileList.clear();
+ fileList.clear();
- if( ! initialized() ) return false;
+ if ( ! initialized() ) return false;
- RpmArgVec opts;
+ RpmArgVec opts;
- opts.push_back ("-V");
- opts.push_back ("--nodeps");
- opts.push_back ("--noscripts");
- opts.push_back ("--nomd5");
- opts.push_back ("--");
- opts.push_back (packageName.c_str());
-
- run_rpm (opts, ExternalProgram::Discard_Stderr);
-
- if ( process == NULL )
- return false;
-
- /* from rpm manpage
- 5 MD5 sum
- S File size
- L Symlink
- T Mtime
- D Device
- U User
- G Group
- M Mode (includes permissions and file type)
- */
-
- string line;
- while (systemReadLine(line))
+ opts.push_back ("-V");
+ opts.push_back ("--nodeps");
+ opts.push_back ("--noscripts");
+ opts.push_back ("--nomd5");
+ opts.push_back ("--");
+ opts.push_back (packageName.c_str());
+
+ run_rpm (opts, ExternalProgram::Discard_Stderr);
+
+ if ( process == NULL )
+ return false;
+
+ /* from rpm manpage
+ 5 MD5 sum
+ S File size
+ L Symlink
+ T Mtime
+ D Device
+ U User
+ G Group
+ M Mode (includes permissions and file type)
+ */
+
+ string line;
+ while (systemReadLine(line))
+ {
+ if (line.length() > 12 &&
+ (line[0] == 'S' || line[0] == 's' ||
+ (line[0] == '.' && line[7] == 'T')))
{
- if (line.length() > 12 &&
- (line[0] == 'S' || line[0] == 's' ||
- (line[0] == '.' && line[7] == 'T')))
- {
- // file has been changed
- string filename;
-
- filename.assign(line, 11, line.length() - 11);
- fileList.insert(filename);
- }
+ // file has been changed
+ string filename;
+
+ filename.assign(line, 11, line.length() - 11);
+ fileList.insert(filename);
}
+ }
- systemStatus();
- // exit code ignored, rpm returns 1 no matter if package is installed or
- // not
+ systemStatus();
+ // exit code ignored, rpm returns 1 no matter if package is installed or
+ // not
- return ok;
+ return ok;
}
/*--------------------------------------------------------------*/
void
RpmDb::run_rpm (const RpmArgVec& opts,
- ExternalProgram::Stderr_Disposition disp)
+ ExternalProgram::Stderr_Disposition disp)
{
- if ( process ) {
- delete process;
- process = NULL;
- }
- exit_code = -1;
+ if ( process )
+ {
+ delete process;
+ process = NULL;
+ }
+ exit_code = -1;
- if ( ! initialized() ) {
- ZYPP_THROW(RpmDbNotOpenException());
- }
+ if ( ! initialized() )
+ {
+ ZYPP_THROW(RpmDbNotOpenException());
+ }
- RpmArgVec args;
+ RpmArgVec args;
- // always set root and dbpath
- args.push_back("rpm");
- args.push_back("--root");
- args.push_back(_root.asString().c_str());
- args.push_back("--dbpath");
- args.push_back(_dbPath.asString().c_str());
+ // always set root and dbpath
+ args.push_back("rpm");
+ args.push_back("--root");
+ args.push_back(_root.asString().c_str());
+ args.push_back("--dbpath");
+ args.push_back(_dbPath.asString().c_str());
- const char* argv[args.size() + opts.size() + 1];
+ const char* argv[args.size() + opts.size() + 1];
- const char** p = argv;
- p = copy (args.begin (), args.end (), p);
- p = copy (opts.begin (), opts.end (), p);
- *p = 0;
+ const char** p = argv;
+ p = copy (args.begin (), args.end (), p);
+ p = copy (opts.begin (), opts.end (), p);
+ *p = 0;
- // Invalidate all outstanding database handles in case
- // the database gets modified.
- librpmDb::dbRelease( true );
+ // Invalidate all outstanding database handles in case
+ // the database gets modified.
+ librpmDb::dbRelease( true );
- // Launch the program with default locale
- process = new ExternalProgram(argv, disp, false, -1, true);
- return;
+ // Launch the program with default locale
+ process = new ExternalProgram(argv, disp, false, -1, true);
+ return;
}
/*--------------------------------------------------------------*/
bool
RpmDb::systemReadLine(string &line)
{
- line.erase();
+ line.erase();
- if ( process == NULL )
- return false;
+ if ( process == NULL )
+ return false;
- line = process->receiveLine();
+ line = process->receiveLine();
- if (line.length() == 0)
- return false;
+ if (line.length() == 0)
+ return false;
- if (line[line.length() - 1] == '\n')
- line.erase(line.length() - 1);
+ if (line[line.length() - 1] == '\n')
+ line.erase(line.length() - 1);
- return true;
+ return true;
}
/*--------------------------------------------------------------*/
int
RpmDb::systemStatus()
{
- if ( process == NULL )
- return -1;
+ if ( process == NULL )
+ return -1;
- exit_code = process->close();
- process->kill();
- delete process;
- process = 0;
+ exit_code = process->close();
+ process->kill();
+ delete process;
+ process = 0;
-// DBG << "exit code " << exit_code << endl;
+ // DBG << "exit code " << exit_code << endl;
return exit_code;
}
// generate diff mails for config files
void RpmDb::processConfigFiles(const string& line, const string& name, const char* typemsg, const char* difffailmsg, const char* diffgenmsg)
{
- string msg = line.substr(9);
- string::size_type pos1 = string::npos;
- string::size_type pos2 = string::npos;
- string file1s, file2s;
- Pathname file1;
- Pathname file2;
-
- pos1 = msg.find (typemsg);
- for (;;)
+ string msg = line.substr(9);
+ string::size_type pos1 = string::npos;
+ string::size_type pos2 = string::npos;
+ string file1s, file2s;
+ Pathname file1;
+ Pathname file2;
+
+ pos1 = msg.find (typemsg);
+ for (;;)
+ {
+ if ( pos1 == string::npos )
+ break;
+
+ pos2 = pos1 + strlen (typemsg);
+
+ if (pos2 >= msg.length() )
+ break;
+
+ file1 = msg.substr (0, pos1);
+ file2 = msg.substr (pos2);
+
+ file1s = file1.asString();
+ file2s = file2.asString();
+
+ if (!_root.empty() && _root != "/")
{
- if( pos1 == string::npos )
- break;
-
- pos2 = pos1 + strlen (typemsg);
-
- if (pos2 >= msg.length() )
- break;
-
- file1 = msg.substr (0, pos1);
- file2 = msg.substr (pos2);
-
- file1s = file1.asString();
- file2s = file2.asString();
-
- if (!_root.empty() && _root != "/")
- {
- file1 = _root + file1;
- file2 = _root + file2;
- }
-
- string out;
- int ret = diffFiles (file1.asString(), file2.asString(), out, 25);
- if (ret)
- {
- Pathname file = _root + WARNINGMAILPATH;
- if (filesystem::assert_dir(file) != 0)
- {
- ERR << "Could not create " << file.asString() << endl;
- break;
- }
- file += Date(Date::now()).form("config_diff_%Y_%m_%d.log");
- ofstream notify(file.asString().c_str(), std::ios::out|std::ios::app);
- if(!notify)
- {
- ERR << "Could not open " << file << endl;
- break;
- }
-
- // Translator: %s = name of an rpm package. A list of diffs follows
- // this message.
- notify << str::form(_("Changed configuration files for %s:"), name.c_str()) << endl;
- if(ret>1)
- {
- ERR << "diff failed" << endl;
- notify << str::form(difffailmsg,
- file1s.c_str(), file2s.c_str()) << endl;
- }
- else
- {
- notify << str::form(diffgenmsg,
- file1s.c_str(), file2s.c_str()) << endl;
-
- // remove root for the viewer's pleasure (#38240)
- if (!_root.empty() && _root != "/")
- {
- if(out.substr(0,4) == "--- ")
- {
- out.replace(4, file1.asString().length(), file1s);
- }
- string::size_type pos = out.find("\n+++ ");
- if(pos != string::npos)
- {
- out.replace(pos+5, file2.asString().length(), file2s);
- }
- }
- notify << out << endl;
- }
- notify.close();
- notify.open("/var/lib/update-messages/yast2-packagemanager.rpmdb.configfiles");
- notify.close();
- }
- else
- {
- WAR << "rpm created " << file2 << " but it is not different from " << file2 << endl;
- }
- break;
+ file1 = _root + file1;
+ file2 = _root + file2;
}
+
+ string out;
+ int ret = diffFiles (file1.asString(), file2.asString(), out, 25);
+ if (ret)
+ {
+ Pathname file = _root + WARNINGMAILPATH;
+ if (filesystem::assert_dir(file) != 0)
+ {
+ ERR << "Could not create " << file.asString() << endl;
+ break;
+ }
+ file += Date(Date::now()).form("config_diff_%Y_%m_%d.log");
+ ofstream notify(file.asString().c_str(), ios::out|ios::app);
+ if (!notify)
+ {
+ ERR << "Could not open " << file << endl;
+ break;
+ }
+
+ // Translator: %s = name of an rpm package. A list of diffs follows
+ // this message.
+ notify << str::form(_("Changed configuration files for %s:"), name.c_str()) << endl;
+ if (ret>1)
+ {
+ ERR << "diff failed" << endl;
+ notify << str::form(difffailmsg,
+ file1s.c_str(), file2s.c_str()) << endl;
+ }
+ else
+ {
+ notify << str::form(diffgenmsg,
+ file1s.c_str(), file2s.c_str()) << endl;
+
+ // remove root for the viewer's pleasure (#38240)
+ if (!_root.empty() && _root != "/")
+ {
+ if (out.substr(0,4) == "--- ")
+ {
+ out.replace(4, file1.asString().length(), file1s);
+ }
+ string::size_type pos = out.find("\n+++ ");
+ if (pos != string::npos)
+ {
+ out.replace(pos+5, file2.asString().length(), file2s);
+ }
+ }
+ notify << out << endl;
+ }
+ notify.close();
+ notify.open("/var/lib/update-messages/yast2-packagemanager.rpmdb.configfiles");
+ notify.close();
+ }
+ else
+ {
+ WAR << "rpm created " << file2 << " but it is not different from " << file2 << endl;
+ }
+ break;
+ }
}
///////////////////////////////////////////////////////////////////
report->start(filename);
do
- try {
+ try
+ {
doInstallPackage(filename, flags, report);
report->finish();
break;
{
RpmInstallReport::Action user = report->problem( excpt_r );
- if( user == RpmInstallReport::ABORT ) {
- report->finish( excpt_r );
- ZYPP_RETHROW(excpt_r);
- } else if ( user == RpmInstallReport::IGNORE ) {
- break;
+ if ( user == RpmInstallReport::ABORT )
+ {
+ report->finish( excpt_r );
+ ZYPP_RETHROW(excpt_r);
+ }
+ else if ( user == RpmInstallReport::IGNORE )
+ {
+ break;
}
}
while (true);
void RpmDb::doInstallPackage( const Pathname & filename, unsigned flags, callback::SendReport<RpmInstallReport> & report )
{
- FAILIFNOTINITIALIZED;
- Logfile progresslog;
+ FAILIFNOTINITIALIZED;
+ CommitLog progresslog;
- MIL << "RpmDb::installPackage(" << filename << "," << flags << ")" << endl;
+ MIL << "RpmDb::installPackage(" << filename << "," << flags << ")" << endl;
- // backup
- if ( _packagebackups ) {
-// FIXME report->progress( pd.init( -2, 100 ) ); // allow 1% for backup creation.
- if ( ! backupPackage( filename ) ) {
- ERR << "backup of " << filename.asString() << " failed" << endl;
- }
-// FIXME status handling
- report->progress( 0 ); // allow 1% for backup creation.
- } else {
- report->progress( 100 );
+ // backup
+ if ( _packagebackups )
+ {
+ // FIXME report->progress( pd.init( -2, 100 ) ); // allow 1% for backup creation.
+ if ( ! backupPackage( filename ) )
+ {
+ ERR << "backup of " << filename.asString() << " failed" << endl;
}
+ // FIXME status handling
+ report->progress( 0 ); // allow 1% for backup creation.
+ }
+ else
+ {
+ report->progress( 100 );
+ }
- // run rpm
- RpmArgVec opts;
- if (flags & RPMINST_NOUPGRADE)
- opts.push_back("-i");
- else
- opts.push_back("-U");
- opts.push_back("--percent");
-
- if (flags & RPMINST_NODIGEST)
- opts.push_back("--nodigest");
- if (flags & RPMINST_NOSIGNATURE)
- opts.push_back("--nosignature");
- if (flags & RPMINST_NODOCS)
- opts.push_back ("--excludedocs");
- if (flags & RPMINST_NOSCRIPTS)
- opts.push_back ("--noscripts");
- if (flags & RPMINST_FORCE)
- opts.push_back ("--force");
- if (flags & RPMINST_NODEPS)
- opts.push_back ("--nodeps");
- if(flags & RPMINST_IGNORESIZE)
- opts.push_back ("--ignoresize");
- if(flags & RPMINST_JUSTDB)
- opts.push_back ("--justdb");
- if(flags & RPMINST_TEST)
- opts.push_back ("--test");
-
- opts.push_back("--");
- opts.push_back (filename.asString().c_str());
-
- modifyDatabase(); // BEFORE run_rpm
- run_rpm( opts, ExternalProgram::Stderr_To_Stdout );
-
- string line;
- string rpmmsg;
- vector<string> configwarnings;
- vector<string> errorlines;
-
- while (systemReadLine(line))
+ // run rpm
+ RpmArgVec opts;
+ if (flags & RPMINST_NOUPGRADE)
+ opts.push_back("-i");
+ else
+ opts.push_back("-U");
+ opts.push_back("--percent");
+
+ if (flags & RPMINST_NODIGEST)
+ opts.push_back("--nodigest");
+ if (flags & RPMINST_NOSIGNATURE)
+ opts.push_back("--nosignature");
+ if (flags & RPMINST_NODOCS)
+ opts.push_back ("--excludedocs");
+ if (flags & RPMINST_NOSCRIPTS)
+ opts.push_back ("--noscripts");
+ if (flags & RPMINST_FORCE)
+ opts.push_back ("--force");
+ if (flags & RPMINST_NODEPS)
+ opts.push_back ("--nodeps");
+ if (flags & RPMINST_IGNORESIZE)
+ opts.push_back ("--ignoresize");
+ if (flags & RPMINST_JUSTDB)
+ opts.push_back ("--justdb");
+ if (flags & RPMINST_TEST)
+ opts.push_back ("--test");
+
+ opts.push_back("--");
+
+ // rpm requires additional quoting of special chars:
+ string quotedFilename( rpmQuoteFilename( filename ) );
+ opts.push_back ( quotedFilename.c_str() );
+
+ modifyDatabase(); // BEFORE run_rpm
+ run_rpm( opts, ExternalProgram::Stderr_To_Stdout );
+
+ string line;
+ string rpmmsg;
+ vector<string> configwarnings;
+ vector<string> errorlines;
+
+ while (systemReadLine(line))
+ {
+ if (line.substr(0,2)=="%%")
{
- if (line.substr(0,2)=="%%")
- {
- int percent;
- sscanf (line.c_str () + 2, "%d", &percent);
- report->progress( percent );
- }
- else
- rpmmsg += line+'\n';
-
- if( line.substr(0,8) == "warning:" )
- {
- configwarnings.push_back(line);
- }
+ int percent;
+ sscanf (line.c_str () + 2, "%d", &percent);
+ report->progress( percent );
}
- int rpm_status = systemStatus();
+ else
+ rpmmsg += line+'\n';
- // evaluate result
- for(vector<string>::iterator it = configwarnings.begin();
- it != configwarnings.end(); ++it)
+ if ( line.substr(0,8) == "warning:" )
{
- processConfigFiles(*it, Pathname::basename(filename), " saved as ",
- // %s = filenames
- _("rpm saved %s as %s but it was impossible to determine the difference"),
- // %s = filenames
- _("rpm saved %s as %s.\nHere are the first 25 lines of difference:\n"));
- processConfigFiles(*it, Pathname::basename(filename), " created as ",
- // %s = filenames
- _("rpm created %s as %s but it was impossible to determine the difference"),
- // %s = filenames
- _("rpm created %s as %s.\nHere are the first 25 lines of difference:\n"));
+ configwarnings.push_back(line);
}
+ }
+ int rpm_status = systemStatus();
- if ( rpm_status != 0 ) {
- // %s = filename of rpm package
- progresslog(/*timestamp*/true) << str::form(_("%s install failed"), Pathname::basename(filename).c_str()) << endl;
- progresslog() << _("rpm output:") << endl << rpmmsg << endl;
- ZYPP_THROW(RpmSubprocessException(string("RPM failed: ") + rpmmsg));
- } else {
- // %s = filename of rpm package
- progresslog(/*timestamp*/true) << str::form(_("%s installed ok"), Pathname::basename(filename).c_str()) << endl;
- if( ! rpmmsg.empty() ) {
- progresslog() << _("Additional rpm output:") << endl << rpmmsg << endl;
- }
+ // evaluate result
+ for (vector<string>::iterator it = configwarnings.begin();
+ it != configwarnings.end(); ++it)
+ {
+ processConfigFiles(*it, Pathname::basename(filename), " saved as ",
+ // %s = filenames
+ _("rpm saved %s as %s but it was impossible to determine the difference"),
+ // %s = filenames
+ _("rpm saved %s as %s.\nHere are the first 25 lines of difference:\n"));
+ processConfigFiles(*it, Pathname::basename(filename), " created as ",
+ // %s = filenames
+ _("rpm created %s as %s but it was impossible to determine the difference"),
+ // %s = filenames
+ _("rpm created %s as %s.\nHere are the first 25 lines of difference:\n"));
+ }
+
+ if ( rpm_status != 0 )
+ {
+ // %s = filename of rpm package
+ progresslog(/*timestamp*/true) << str::form(_("%s install failed"), Pathname::basename(filename).c_str()) << endl;
+ progresslog() << _("rpm output:") << endl << rpmmsg << endl;
+ ZYPP_THROW(RpmSubprocessException(string("RPM failed: ") + rpmmsg));
+ }
+ else
+ {
+ // %s = filename of rpm package
+ progresslog(/*timestamp*/true) << str::form(_("%s installed ok"), Pathname::basename(filename).c_str()) << endl;
+ if ( ! rpmmsg.empty() )
+ {
+ progresslog() << _("Additional rpm output:") << endl << rpmmsg << endl;
}
+ }
}
///////////////////////////////////////////////////////////////////
void RpmDb::removePackage( Package::constPtr package, unsigned flags )
{
return removePackage( package->name()
- + "-" + package->edition().asString()
- + "." + package->arch().asString(), flags );
+ + "-" + package->edition().asString()
+ + "." + package->arch().asString(), flags );
}
///////////////////////////////////////////////////////////////////
report->start( name_r );
- try {
+ try
+ {
doRemovePackage(name_r, flags, report);
}
catch (RpmException & excpt_r)
void RpmDb::doRemovePackage( const string & name_r, unsigned flags, callback::SendReport<RpmRemoveReport> & report )
{
- FAILIFNOTINITIALIZED;
- Logfile progresslog;
-
- MIL << "RpmDb::doRemovePackage(" << name_r << "," << flags << ")" << endl;
+ FAILIFNOTINITIALIZED;
+ CommitLog progresslog;
- // backup
- if ( _packagebackups ) {
-// FIXME solve this status report somehow
-// report->progress( pd.init( -2, 100 ) ); // allow 1% for backup creation.
- if ( ! backupPackage( name_r ) ) {
- ERR << "backup of " << name_r << " failed" << endl;
- }
- report->progress( 0 );
- } else {
- report->progress( 100 );
- }
+ MIL << "RpmDb::doRemovePackage(" << name_r << "," << flags << ")" << endl;
- // run rpm
- RpmArgVec opts;
- opts.push_back("-e");
- opts.push_back("--allmatches");
-
- if (flags & RPMINST_NOSCRIPTS)
- opts.push_back("--noscripts");
- if (flags & RPMINST_NODEPS)
- opts.push_back("--nodeps");
- if (flags & RPMINST_JUSTDB)
- opts.push_back("--justdb");
- if (flags & RPMINST_TEST)
- opts.push_back ("--test");
- if (flags & RPMINST_FORCE) {
- WAR << "IGNORE OPTION: 'rpm -e' does not support '--force'" << endl;
+ // backup
+ if ( _packagebackups )
+ {
+ // FIXME solve this status report somehow
+ // report->progress( pd.init( -2, 100 ) ); // allow 1% for backup creation.
+ if ( ! backupPackage( name_r ) )
+ {
+ ERR << "backup of " << name_r << " failed" << endl;
}
+ report->progress( 0 );
+ }
+ else
+ {
+ report->progress( 100 );
+ }
- opts.push_back("--");
- opts.push_back(name_r.c_str());
+ // run rpm
+ RpmArgVec opts;
+ opts.push_back("-e");
+ opts.push_back("--allmatches");
+
+ if (flags & RPMINST_NOSCRIPTS)
+ opts.push_back("--noscripts");
+ if (flags & RPMINST_NODEPS)
+ opts.push_back("--nodeps");
+ if (flags & RPMINST_JUSTDB)
+ opts.push_back("--justdb");
+ if (flags & RPMINST_TEST)
+ opts.push_back ("--test");
+ if (flags & RPMINST_FORCE)
+ {
+ WAR << "IGNORE OPTION: 'rpm -e' does not support '--force'" << endl;
+ }
- modifyDatabase(); // BEFORE run_rpm
- run_rpm (opts, ExternalProgram::Stderr_To_Stdout);
+ opts.push_back("--");
+ opts.push_back(name_r.c_str());
- string line;
- string rpmmsg;
+ modifyDatabase(); // BEFORE run_rpm
+ run_rpm (opts, ExternalProgram::Stderr_To_Stdout);
- // got no progress from command, so we fake it:
- // 5 - command started
- // 50 - command completed
- // 100 if no error
- report->progress( 5 );
- while (systemReadLine(line))
- {
- rpmmsg += line+'\n';
- }
- report->progress( 50 );
- int rpm_status = systemStatus();
-
- if ( rpm_status != 0 ) {
- // %s = name of rpm package
- progresslog(/*timestamp*/true) << str::form(_("%s remove failed"), name_r.c_str()) << endl;
- progresslog() << _("rpm output:") << endl << rpmmsg << endl;
- ZYPP_THROW(RpmSubprocessException(string("RPM failed: ") + rpmmsg));
- } else {
- progresslog(/*timestamp*/true) << str::form(_("%s remove ok"), name_r.c_str()) << endl;
- if( ! rpmmsg.empty() ) {
- progresslog() << _("Additional rpm output:") << endl << rpmmsg << endl;
- }
- }
-}
+ string line;
+ string rpmmsg;
+
+ // got no progress from command, so we fake it:
+ // 5 - command started
+ // 50 - command completed
+ // 100 if no error
+ report->progress( 5 );
+ while (systemReadLine(line))
+ {
+ rpmmsg += line+'\n';
+ }
+ report->progress( 50 );
+ int rpm_status = systemStatus();
-string
-RpmDb::checkPackageResult2string(unsigned code)
-{
- string msg;
- // begin of line characters
- string bol = " - ";
- // end of line characters
- string eol = "\n";
- if(code == 0)
- return string(_("Ok"))+eol;
-
- //translator: these are different kinds of how an rpm package can be broken
- msg = _("The package is not OK for the following reasons:");
- msg += eol;
-
- if(code&CHK_INCORRECT_VERSION)
- {
- msg += bol;
- msg+=_("The package contains different version than expected");
- msg += eol;
- }
- if(code&CHK_INCORRECT_FILEMD5)
- {
- msg += bol;
- msg+=_("The package file has incorrect MD5 sum");
- msg += eol;
- }
- if(code&CHK_GPGSIG_MISSING)
- {
- msg += bol;
- msg+=_("The package is not signed");
- msg += eol;
- }
- if(code&CHK_MD5SUM_MISSING)
- {
- msg += bol;
- msg+=_("The package has no MD5 sum");
- msg += eol;
- }
- if(code&CHK_INCORRECT_GPGSIG)
- {
- msg += bol;
- msg+=_("The package has incorrect signature");
- msg += eol;
- }
- if(code&CHK_INCORRECT_PKGMD5)
- {
- msg += bol;
- msg+=_("The package archive has incorrect MD5 sum");
- msg += eol;
- }
- if(code&CHK_OTHER_FAILURE)
+ if ( rpm_status != 0 )
+ {
+ // %s = name of rpm package
+ progresslog(/*timestamp*/true) << str::form(_("%s remove failed"), name_r.c_str()) << endl;
+ progresslog() << _("rpm output:") << endl << rpmmsg << endl;
+ ZYPP_THROW(RpmSubprocessException(string("RPM failed: ") + rpmmsg));
+ }
+ else
+ {
+ progresslog(/*timestamp*/true) << str::form(_("%s remove ok"), name_r.c_str()) << endl;
+ if ( ! rpmmsg.empty() )
{
- msg += bol;
- msg+=_("rpm failed for unkown reason, see log file");
- msg += eol;
+ progresslog() << _("Additional rpm output:") << endl << rpmmsg << endl;
}
-
- return msg;
+ }
}
///////////////////////////////////////////////////////////////////
bool RpmDb::backupPackage( const Pathname & filename )
{
RpmHeader::constPtr h( RpmHeader::readPackage( filename, RpmHeader::NOSIGNATURE ) );
- if( ! h )
+ if ( ! h )
return false;
return backupPackage( h->tag_name() );
//
bool RpmDb::backupPackage(const string& packageName)
{
- Logfile progresslog;
- bool ret = true;
- Pathname backupFilename;
- Pathname filestobackupfile = _root+_backuppath+FILEFORBACKUPFILES;
+ CommitLog progresslog;
+ bool ret = true;
+ Pathname backupFilename;
+ Pathname filestobackupfile = _root+_backuppath+FILEFORBACKUPFILES;
+
+ if (_backuppath.empty())
+ {
+ INT << "_backuppath empty" << endl;
+ return false;
+ }
+
+ FileList fileList;
+
+ if (!queryChangedFiles(fileList, packageName))
+ {
+ ERR << "Error while getting changed files for package " <<
+ packageName << endl;
+ return false;
+ }
+
+ if (fileList.size() <= 0)
+ {
+ DBG << "package " << packageName << " not changed -> no backup" << endl;
+ return true;
+ }
+
+ if (filesystem::assert_dir(_root + _backuppath) != 0)
+ {
+ return false;
+ }
- if (_backuppath.empty())
+ {
+ // build up archive name
+ time_t currentTime = time(0);
+ struct tm *currentLocalTime = localtime(¤tTime);
+
+ int date = (currentLocalTime->tm_year + 1900) * 10000
+ + (currentLocalTime->tm_mon + 1) * 100
+ + currentLocalTime->tm_mday;
+
+ int num = 0;
+ do
{
- INT << "_backuppath empty" << endl;
- return false;
+ backupFilename = _root + _backuppath
+ + str::form("%s-%d-%d.tar.gz",packageName.c_str(), date, num);
+
}
+ while ( PathInfo(backupFilename).isExist() && num++ < 1000);
- FileList fileList;
+ PathInfo pi(filestobackupfile);
+ if (pi.isExist() && !pi.isFile())
+ {
+ ERR << filestobackupfile.asString() << " already exists and is no file" << endl;
+ return false;
+ }
+
+ ofstream fp ( filestobackupfile.asString().c_str(), ios::out|ios::trunc );
- if (!queryChangedFiles(fileList, packageName))
+ if (!fp)
{
- ERR << "Error while getting changed files for package " <<
- packageName << endl;
- return false;
+ ERR << "could not open " << filestobackupfile.asString() << endl;
+ return false;
}
- if (fileList.size() <= 0)
+ for (FileList::const_iterator cit = fileList.begin();
+ cit != fileList.end(); ++cit)
{
- DBG << "package " << packageName << " not changed -> no backup" << endl;
- return true;
+ string name = *cit;
+ if ( name[0] == '/' )
+ {
+ // remove slash, file must be relative to -C parameter of tar
+ name = name.substr( 1 );
+ }
+ DBG << "saving file "<< name << endl;
+ fp << name << endl;
}
+ fp.close();
+
+ const char* const argv[] =
+ {
+ "tar",
+ "-czhP",
+ "-C",
+ _root.asString().c_str(),
+ "--ignore-failed-read",
+ "-f",
+ backupFilename.asString().c_str(),
+ "-T",
+ filestobackupfile.asString().c_str(),
+ NULL
+ };
- if (filesystem::assert_dir(_root + _backuppath) != 0)
+ // execute tar in inst-sys (we dont know if there is a tar below _root !)
+ ExternalProgram tar(argv, ExternalProgram::Stderr_To_Stdout, false, -1, true);
+
+ string tarmsg;
+
+ // TODO: its probably possible to start tar with -v and watch it adding
+ // files to report progress
+ for (string output = tar.receiveLine(); output.length() ;output = tar.receiveLine())
{
- return false;
+ tarmsg+=output;
}
+ int ret = tar.close();
+
+ if ( ret != 0)
{
- // build up archive name
- time_t currentTime = time(0);
- struct tm *currentLocalTime = localtime(¤tTime);
-
- int date = (currentLocalTime->tm_year + 1900) * 10000
- + (currentLocalTime->tm_mon + 1) * 100
- + currentLocalTime->tm_mday;
-
- int num = 0;
- do
- {
- backupFilename = _root + _backuppath
- + str::form("%s-%d-%d.tar.gz",packageName.c_str(), date, num);
-
- }
- while ( PathInfo(backupFilename).isExist() && num++ < 1000);
-
- PathInfo pi(filestobackupfile);
- if(pi.isExist() && !pi.isFile())
- {
- ERR << filestobackupfile.asString() << " already exists and is no file" << endl;
- return false;
- }
-
- std::ofstream fp ( filestobackupfile.asString().c_str(), std::ios::out|std::ios::trunc );
-
- if(!fp)
- {
- ERR << "could not open " << filestobackupfile.asString() << endl;
- return false;
- }
-
- for (FileList::const_iterator cit = fileList.begin();
- cit != fileList.end(); ++cit)
- {
- string name = *cit;
- if ( name[0] == '/' )
- {
- // remove slash, file must be relative to -C parameter of tar
- name = name.substr( 1 );
- }
- DBG << "saving file "<< name << endl;
- fp << name << endl;
- }
- fp.close();
-
- const char* const argv[] =
- {
- "tar",
- "-czhP",
- "-C",
- _root.asString().c_str(),
- "--ignore-failed-read",
- "-f",
- backupFilename.asString().c_str(),
- "-T",
- filestobackupfile.asString().c_str(),
- NULL
- };
-
- // execute tar in inst-sys (we dont know if there is a tar below _root !)
- ExternalProgram tar(argv, ExternalProgram::Stderr_To_Stdout, false, -1, true);
-
- string tarmsg;
-
- // TODO: its probably possible to start tar with -v and watch it adding
- // files to report progress
- for (string output = tar.receiveLine(); output.length() ;output = tar.receiveLine())
- {
- tarmsg+=output;
- }
-
- int ret = tar.close();
-
- if ( ret != 0)
- {
- ERR << "tar failed: " << tarmsg << endl;
- ret = false;
- }
- else
- {
- MIL << "tar backup ok" << endl;
- progresslog(/*timestamp*/true) << str::form(_("created backup %s"), backupFilename.asString().c_str()) << endl;
- }
-
- filesystem::unlink(filestobackupfile);
+ ERR << "tar failed: " << tarmsg << endl;
+ ret = false;
+ }
+ else
+ {
+ MIL << "tar backup ok" << endl;
+ progresslog(/*timestamp*/true) << str::form(_("created backup %s"), backupFilename.asString().c_str()) << endl;
}
- return ret;
+ filesystem::unlink(filestobackupfile);
+ }
+
+ return ret;
}
void RpmDb::setBackupPath(const Pathname& path)
{
- _backuppath = path;
+ _backuppath = path;
}
- } // namespace rpm
- } // namespace target
+} // namespace rpm
+} // namespace target
} // namespace zypp