15 #include <rpm/rpmcli.h>
16 #include <rpm/rpmlog.h>
32 #include <boost/format.hpp>
57 #define WARNINGMAILPATH "/var/log/YaST2/"
58 #define FILEFORBACKUPFILES "YaSTBackupModifiedFiles"
59 #define MAXRPMMESSAGELINES 10000
61 #define WORKAROUNDRPMPWDBUG
65 namespace zypp_readonly_hack
75 #if 1 // No more need to escape whitespace since rpm-4.4.2.3
76 const char* quoteInFilename_m =
"\'\"";
78 const char* quoteInFilename_m =
" \t\'\"";
80 inline string rpmQuoteFilename(
const Pathname & path_r )
82 string path( path_r.asString() );
85 pos = path.find_first_of( quoteInFilename_m, pos ) )
87 path.insert( pos,
"\\" );
100 #if defined(WORKAROUNDRPMPWDBUG)
104 AutoDispose<char*> cwd( ::get_current_dir_name(), ::free );
107 WAR <<
"Can't get cwd!" << endl;
128 MIL <<
"trusted key added to zypp Keyring. Importing" << endl;
132 _rpmdb.importPubkey( key );
136 ERR <<
"Could not import key " << key.
id() <<
" (" << key.
name() <<
" from " << key.
path() <<
" in rpm database" << endl;
142 MIL <<
"Trusted key removed from zypp Keyring. Removing..." << endl;
147 _rpmdb.removePubkey( key );
151 ERR <<
"Could not remove key " << key.
id() <<
" (" << key.
name() <<
") from rpm database" << endl;
160 unsigned diffFiles(
const string file1,
const string file2,
string& out,
int maxlines)
170 ExternalProgram prog(argv,ExternalProgram::Discard_Stderr,
false, -1,
true);
181 if (maxlines<0?
true:count<maxlines)
196 inline string stringPath(
const Pathname & root_r,
const Pathname & sub_r )
209 if ( obj == RpmDb::DbSI_NO_INIT )
215 #define ENUM_OUT(B,C) str << ( obj & RpmDb::B ? C : '-' )
238 #define FAILIFNOTINITIALIZED if( ! initialized() ) { ZYPP_THROW(RpmDbNotOpenException()); }
249 : _dbStateInfo( DbSI_NO_INIT )
250 #warning Check for obsolete memebers
251 , _backuppath (
"/var/adm/backup")
252 , _packagebackups(false)
253 , _warndirexists(false)
260 setenv(
"RPM_IgnoreFailedSymlinks",
"1", 1 );
272 MIL <<
"~RpmDb()" << endl;
275 MIL <<
"~RpmDb() end" << endl;
276 sKeyRingReceiver.reset();
285 db_path =
"/var/lib/rpm";
289 PathInfo rpmdb_info(
root() + db_path +
"/Packages");
291 if ( rpmdb_info.isExist() )
292 return rpmdb_info.mtime();
312 #define ENUM_OUT(B,C) str << ( _dbStateInfo & B ? C : '-' )
338 bool quickinit( root_r.empty() );
340 if ( root_r.empty() )
343 if ( dbPath_r.empty() )
344 dbPath_r =
"/var/lib/rpm";
346 if ( ! (root_r.absolute() && dbPath_r.absolute()) )
348 ERR <<
"Illegal root or dbPath: " <<
stringPath( root_r, dbPath_r ) << endl;
352 MIL <<
"Calling initDatabase: " <<
stringPath( root_r, dbPath_r )
353 << ( doRebuild_r ?
" (rebuilddb)" :
"" )
354 << ( quickinit ?
" (quickinit)" :
"" ) << endl;
378 MIL <<
"QUICK initDatabase (no systemRoot set)" << endl;
391 ERR <<
"Cleanup on error: state " << info << endl;
406 MIL <<
"Cleanup: state " << info << endl;
415 MIL <<
"Update mode: Cleanup delayed until closeOldDatabase." << endl;
418 #warning CHECK: notify root about conversion backup.
433 MIL <<
"Synchronizing keys with zypp keyring" << endl;
442 MIL <<
"InitDatabase: " << *
this << endl;
468 ERR <<
"Bad database directory: " << dbInfo.
dbDir() << endl;
475 MIL <<
"Found rpm4 database in " << dbInfo.
dbDir() << endl;
479 MIL <<
"Creating new rpm4 database in " << dbInfo.
dbDir() << endl;
491 DBG <<
"Initial state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
510 DBG <<
"Access state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
519 bool dbEmpty = dbptr->empty();
522 MIL <<
"Empty rpm4 database " << dbInfo.
dbV4() << endl;
527 MIL <<
"Found rpm3 database " << dbInfo.
dbV3() << endl;
538 WAR <<
"Backup converted rpm3 database failed: error(" << res <<
")" << endl;
545 MIL <<
"Backup converted rpm3 database: " << dbInfo.
dbV3ToV4() << endl;
554 WAR <<
"Non empty rpm3 and rpm4 database found: using rpm4" << endl;
560 DBG <<
"Convert state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
566 MIL <<
"Rpm3 database backup: " << dbInfo.
dbV3ToV4() << endl;
578 const char * v3backup =
"packages.rpm3";
579 const char * master =
"Packages";
580 const char * index[] =
602 PathInfo pi( dbdir_r );
605 ERR <<
"Can't remove rpm4 database in non directory: " << dbdir_r << endl;
609 for (
const char ** f = index; *f; ++f )
618 pi( dbdir_r + master );
621 MIL <<
"Removing rpm4 database " << pi << endl;
627 pi( dbdir_r + v3backup );
630 MIL <<
"Removing converted rpm3 database backup " << pi << endl;
644 const char * master =
"packages.rpm";
645 const char * index[] =
647 "conflictsindex.rpm",
658 PathInfo pi( dbdir_r );
661 ERR <<
"Can't remove rpm3 database in non directory: " << dbdir_r << endl;
665 for (
const char ** f = index; *f; ++f )
674 #warning CHECK: compare vs existing v3 backup. notify root
675 pi( dbdir_r + master );
678 Pathname m( pi.path() );
683 Pathname b( m.extend(
"3" ) );
688 Pathname b( m.extend(
".deleted" ) );
698 MIL <<
"(Re)moved rpm3 database to " << pi << endl;
738 MIL <<
"Calling closeDatabase: " << *
this << endl;
769 MIL <<
"closeDatabase: " << *
this << endl;
800 MIL <<
"RpmDb::rebuildDatabase" << *
this << endl;
803 PathInfo dbMaster(
root() +
dbPath() +
"Packages" );
804 PathInfo dbMasterBackup( dbMaster.path().extend(
".y2backup" ) );
808 opts.push_back(
"--rebuilddb");
809 opts.push_back(
"-vv");
816 PathInfo newMaster(
root()
829 if ( ! report->progress( (100 * newMaster.size()) / dbMaster.size(),
root() +
dbPath()) )
831 WAR <<
"User requested abort." << endl;
837 if ( line.compare( 0, 2,
"D:" ) )
839 errmsg += line +
'\n';
847 if ( rpm_status != 0 )
866 void computeKeyRingSync( std::set<Edition> & rpmKeys_r, std::list<PublicKeyData> & zyppKeys_r )
877 void updateIf(
const Edition & rpmKey_r )
879 std::string keyRelease( rpmKey_r.
release() );
880 int comp = _release.compare( keyRelease );
884 _release.swap( keyRelease );
885 _inRpmKeys = &rpmKey_r;
886 _inZyppKeys =
nullptr;
887 if ( !keyRelease.empty() )
888 DBG <<
"Old key in R: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
890 else if ( comp == 0 )
894 _inRpmKeys = &rpmKey_r;
898 DBG <<
"Old key in R: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
901 void updateIf(
const PublicKeyData & zyppKey_r )
903 std::string keyRelease( zyppKey_r.gpgPubkeyRelease() );
904 int comp = _release.compare( keyRelease );
908 _release.swap( keyRelease );
909 _inRpmKeys =
nullptr;
910 _inZyppKeys = &zyppKey_r;
911 if ( !keyRelease.empty() )
912 DBG <<
"Old key in Z: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() <<
"-" << keyRelease << endl;
914 else if ( comp == 0 )
918 _inZyppKeys = &zyppKey_r;
922 DBG <<
"Old key in Z: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() <<
"-" << keyRelease << endl;
925 std::string _release;
926 const Edition * _inRpmKeys;
927 const PublicKeyData * _inZyppKeys;
932 std::map<std::string,Key> _keymap;
934 for_( it, rpmKeys_r.begin(), rpmKeys_r.end() )
936 _keymap[(*it).version()].updateIf( *it );
939 for_( it, zyppKeys_r.begin(), zyppKeys_r.end() )
941 _keymap[(*it).gpgPubkeyVersion()].updateIf( *it );
945 std::set<Edition> rpmKeys;
946 std::list<PublicKeyData> zyppKeys;
947 for_( it, _keymap.begin(), _keymap.end() )
949 DBG <<
"gpg-pubkey-" << (*it).first <<
"-" << (*it).second._release <<
" "
950 << ( (*it).second._inRpmKeys ?
"R" :
"_" )
951 << ( (*it).second._inZyppKeys ?
"Z" :
"_" ) << endl;
952 if ( ! (*it).second._inRpmKeys )
954 zyppKeys.push_back( *(*it).second._inZyppKeys );
956 if ( ! (*it).second._inZyppKeys )
958 rpmKeys.insert( *(*it).second._inRpmKeys );
961 rpmKeys_r.swap( rpmKeys );
962 zyppKeys_r.swap( zyppKeys );
969 MIL <<
"Going to sync trusted keys..." << endl;
971 std::list<PublicKeyData> zyppKeys( getZYpp()->keyRing()->trustedPublicKeyData() );
972 computeKeyRingSync( rpmKeys, zyppKeys );
973 MIL << (mode_r &
SYNC_TO_KEYRING ?
"" :
"(skip) ") <<
"Rpm keys to export into zypp trusted keyring: " << rpmKeys.size() << endl;
974 MIL << (mode_r &
SYNC_FROM_KEYRING ?
"" :
"(skip) ") <<
"Zypp trusted keys to import into rpm database: " << zyppKeys.size() << endl;
980 MIL <<
"Exporting rpm keyring into zypp trusted keyring" <<endl;
985 TmpFile tmpfile( getZYpp()->tmpPath() );
987 ofstream tmpos( tmpfile.
path().
c_str() );
988 for_( it, rpmKeys.begin(), rpmKeys.end() )
992 getData(
string(
"gpg-pubkey"), *it, result );
993 tmpos << result->tag_description() << endl;
998 getZYpp()->keyRing()->multiKeyImport( tmpfile.
path(),
true );
1002 ERR <<
"Could not import keys into in zypp keyring" << endl;
1010 MIL <<
"Importing zypp trusted keyring" << std::endl;
1011 for_( it, zyppKeys.begin(), zyppKeys.end() )
1015 importPubkey( getZYpp()->keyRing()->exportTrustedPublicKey( *it ) );
1023 MIL <<
"Trusted keys synced." << endl;
1045 WAR <<
"Key " << pubkey_r <<
" can not be imported. (READONLY MODE)" << endl;
1052 bool hasOldkeys =
false;
1054 for_( it, rpmKeys.begin(), rpmKeys.end() )
1058 MIL <<
"Key " << pubkey_r <<
" is already in the rpm trusted keyring. (skip import)" << endl;
1062 if ( keyEd.version() != (*it).version() )
1065 if ( keyEd.release() < (*it).release() )
1067 MIL <<
"Key " << pubkey_r <<
" is older than one in the rpm trusted keyring. (skip import)" << endl;
1075 MIL <<
"Key " << pubkey_r <<
" will be imported into the rpm trusted keyring." << (hasOldkeys?
"(update)":
"(new)") << endl;
1081 std::string keyName(
"gpg-pubkey-" + keyEd.version() );
1083 opts.push_back (
"-e" );
1084 opts.push_back (
"--allmatches" );
1085 opts.push_back (
"--" );
1086 opts.push_back ( keyName.c_str() );
1099 ERR <<
"Failed to remove key " << pubkey_r <<
" from RPM trusted keyring (ignored)" << endl;
1103 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1109 opts.push_back (
"--import" );
1110 opts.push_back (
"--" );
1111 opts.push_back ( pubkey_r.
path().asString().c_str() );
1127 _(
"Failed to import public key from file %s: %s"))
1132 MIL <<
"Key " << pubkey_r <<
" imported in rpm trusted keyring." << endl;
1149 set<Edition>::const_iterator found_edition = rpm_keys.end();
1152 for_( it, rpm_keys.begin(), rpm_keys.end() )
1154 if ( (*it).version() == pubkeyVersion )
1162 if (found_edition == rpm_keys.end())
1164 WAR <<
"Key " << pubkey_r.
id() <<
" is not in rpm db" << endl;
1168 string rpm_name(
"gpg-pubkey-" + found_edition->asString());
1171 opts.push_back (
"-e" );
1172 opts.push_back (
"--" );
1173 opts.push_back ( rpm_name.c_str() );
1182 if ( line.substr( 0, 6 ) ==
"error:" )
1184 WAR << line << endl;
1188 DBG << line << endl;
1194 if ( rpm_status != 0 )
1198 _(
"Failed to remove public key %s: %s")) % pubkey_r.
asString()
1203 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1215 list<PublicKey> ret;
1218 for ( it.
findByName(
string(
"gpg-pubkey" ) ); *it; ++it )
1220 Edition edition = it->tag_edition();
1225 getData(
string(
"gpg-pubkey"), edition, result );
1226 TmpFile file(getZYpp()->tmpPath());
1232 os << result->tag_description();
1241 catch (exception &e)
1243 ERR <<
"Could not dump key " << edition.
asString() <<
" in tmp file " << file.
path() << endl;
1256 for ( it.
findByName(
string(
"gpg-pubkey" ) ); *it; ++it )
1258 Edition edition = it->tag_edition();
1260 ret.insert( edition );
1277 list<FileInfo> result;
1312 if (!name_r.empty())
1314 res = (it->tag_name() == name_r);
1335 return it->tag_name();
1449 struct RpmlogCapture :
public std::string
1452 { rpmlog()._cap =
this; }
1455 { rpmlog()._cap =
nullptr; }
1463 rpmlogSetCallback( rpmLogCB,
this );
1464 rpmSetVerbosity( RPMLOG_INFO );
1465 _f = ::fopen(
"/dev/null",
"w");
1466 rpmlogSetFile(
_f );
1470 {
if (
_f ) ::fclose(
_f ); }
1472 static int rpmLogCB( rpmlogRec rec_r, rpmlogCallbackData data_r )
1473 {
return reinterpret_cast<Rpmlog*
>(data_r)->rpmLog( rec_r ); }
1475 int rpmLog( rpmlogRec rec_r )
1477 if (
_cap ) (*_cap) = rpmlogRecMessage( rec_r );
1478 return RPMLOG_DEFAULT;
1485 static Rpmlog & rpmlog()
1486 {
static Rpmlog _rpmlog;
return _rpmlog; }
1498 PathInfo file( path_r );
1499 if ( ! file.isFile() )
1501 ERR <<
"Not a file: " << file << endl;
1505 FD_t fd = ::Fopen( file.asString().c_str(),
"r.ufdio" );
1506 if ( fd == 0 || ::Ferror(fd) )
1508 ERR <<
"Can't open file for reading: " << file <<
" (" << ::Fstrerror(fd) <<
")" << endl;
1513 rpmts ts = ::rpmtsCreate();
1515 ::rpmtsSetVSFlags( ts, RPMVSF_DEFAULT );
1517 rpmQVKArguments_s qva;
1518 memset( &qva, 0,
sizeof(rpmQVKArguments_s) );
1519 qva.qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE);
1521 RpmlogCapture vresult;
1522 int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.basename().c_str() );
1530 detail_r.push_back( CheckPackageDetail::value_type(
CHK_OK, std::move(vresult) ) );
1536 std::vector<std::string> lines;
1537 str::split( vresult, std::back_inserter(lines),
"\n" );
1538 unsigned count[6] = { 0, 0, 0, 0, 0, 0 };
1540 for (
unsigned i = 1; i < lines.size(); ++i )
1542 std::string & line( lines[i] );
1544 if ( line.find(
": OK" ) != std::string::npos )
1546 else if ( line.find(
": NOKEY" ) != std::string::npos )
1548 else if ( line.find(
": BAD" ) != std::string::npos )
1550 else if ( line.find(
": UNKNOWN" ) != std::string::npos )
1552 else if ( line.find(
": NOTRUSTED" ) != std::string::npos )
1556 detail_r.push_back( CheckPackageDetail::value_type( lineres, std::move(line) ) );
1591 opts.push_back (
"-V");
1592 opts.push_back (
"--nodeps");
1593 opts.push_back (
"--noscripts");
1594 opts.push_back (
"--nomd5");
1595 opts.push_back (
"--");
1596 opts.push_back (packageName.c_str());
1617 if (line.length() > 12 &&
1618 (line[0] ==
'S' || line[0] ==
's' ||
1619 (line[0] ==
'.' && line[7] ==
'T')))
1624 filename.assign(line, 11, line.length() - 11);
1625 fileList.insert(filename);
1665 #if defined(WORKAROUNDRPMPWDBUG)
1666 args.push_back(
"#/");
1668 args.push_back(
"rpm");
1669 args.push_back(
"--root");
1670 args.push_back(
_root.asString().c_str());
1671 args.push_back(
"--dbpath");
1672 args.push_back(
_dbPath.asString().c_str());
1674 const char* argv[args.size() + opts.size() + 1];
1676 const char** p = argv;
1677 p =
copy (args.begin (), args.end (), p);
1678 p =
copy (opts.begin (), opts.end (), p);
1704 int inputfileFd = ::fileno( inputfile );
1710 FD_SET( inputfileFd, &rfds );
1717 int retval = select( inputfileFd+1, &rfds, NULL, NULL, &tv );
1721 ERR <<
"select error: " <<
strerror(errno) << endl;
1722 if ( errno != EINTR )
1728 static size_t linebuffer_size = 0;
1729 static char * linebuffer = 0;
1730 ssize_t nread =
getline( &linebuffer, &linebuffer_size, inputfile );
1733 if ( ::feof( inputfile ) )
1740 if ( linebuffer[nread-1] ==
'\n' )
1742 line += string( linebuffer, nread );
1745 if ( ! ::ferror( inputfile ) || ::feof( inputfile ) )
1748 clearerr( inputfile );
1797 void RpmDb::processConfigFiles(
const string& line,
const string& name,
const char* typemsg,
const char* difffailmsg,
const char* diffgenmsg)
1799 string msg = line.substr(9);
1802 string file1s, file2s;
1806 pos1 = msg.find (typemsg);
1809 if ( pos1 == string::npos )
1812 pos2 = pos1 + strlen (typemsg);
1814 if (pos2 >= msg.length() )
1817 file1 = msg.substr (0, pos1);
1818 file2 = msg.substr (pos2);
1820 file1s = file1.asString();
1821 file2s = file2.asString();
1825 file1 =
_root + file1;
1826 file2 =
_root + file2;
1830 int ret =
diffFiles (file1.asString(), file2.asString(), out, 25);
1836 ERR <<
"Could not create " << file.asString() << endl;
1840 ofstream notify(file.asString().c_str(), ios::out|ios::app);
1843 ERR <<
"Could not open " << file << endl;
1849 notify <<
str::form(
_(
"Changed configuration files for %s:"), name.c_str()) << endl;
1852 ERR <<
"diff failed" << endl;
1854 file1s.c_str(), file2s.c_str()) << endl;
1859 file1s.c_str(), file2s.c_str()) << endl;
1864 if (out.substr(0,4) ==
"--- ")
1866 out.replace(4, file1.asString().length(), file1s);
1869 if (pos != string::npos)
1871 out.replace(pos+5, file2.asString().length(), file2s);
1874 notify << out << endl;
1877 notify.open(
"/var/lib/update-messages/yast2-packagemanager.rpmdb.configfiles");
1882 WAR <<
"rpm created " << file2 <<
" but it is not different from " << file2 << endl;
1898 report->start(filename);
1913 report->finish( excpt_r );
1929 MIL <<
"RpmDb::installPackage(" << filename <<
"," << flags <<
")" << endl;
1938 ERR <<
"backup of " << filename.asString() <<
" failed" << endl;
1941 report->progress( 0 );
1947 opts.push_back(
"-i");
1949 opts.push_back(
"-U");
1951 opts.push_back(
"--percent");
1952 opts.push_back(
"--noglob");
1956 opts.push_back(
"--ignorearch");
1959 opts.push_back(
"--nodigest");
1961 opts.push_back(
"--nosignature");
1963 opts.push_back (
"--excludedocs");
1965 opts.push_back (
"--noscripts");
1967 opts.push_back (
"--force");
1969 opts.push_back (
"--nodeps");
1971 opts.push_back (
"--ignoresize");
1973 opts.push_back (
"--justdb");
1975 opts.push_back (
"--test");
1977 opts.push_back (
"--noposttrans");
1979 opts.push_back(
"--");
1982 string quotedFilename( rpmQuoteFilename( workaroundRpmPwdBug( filename ) ) );
1983 opts.push_back ( quotedFilename.c_str() );
1990 vector<string> configwarnings;
1992 unsigned linecnt = 0;
2000 if (line.substr(0,2)==
"%%")
2003 sscanf (line.c_str () + 2,
"%d", &percent);
2004 report->progress( percent );
2007 rpmmsg += line+
'\n';
2009 if ( line.substr(0,8) ==
"warning:" )
2011 configwarnings.push_back(line);
2015 rpmmsg +=
"[truncated]\n";
2020 for (vector<string>::iterator it = configwarnings.begin();
2021 it != configwarnings.end(); ++it)
2025 _(
"rpm saved %s as %s, but it was impossible to determine the difference"),
2027 _(
"rpm saved %s as %s.\nHere are the first 25 lines of difference:\n"));
2030 _(
"rpm created %s as %s, but it was impossible to determine the difference"),
2032 _(
"rpm created %s as %s.\nHere are the first 25 lines of difference:\n"));
2035 if ( rpm_status != 0 )
2038 str::form(
"%s install failed", Pathname::basename(filename).c_str()),
2041 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2042 historylog.
comment(sstr.str());
2047 else if ( ! rpmmsg.empty() )
2050 str::form(
"%s installed ok", Pathname::basename(filename).c_str()),
2053 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2054 historylog.
comment(sstr.str());
2058 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2072 +
"-" + package->edition().version()
2073 +
"-" + package->edition().release()
2074 +
"." + package->arch().asString(), flags );
2087 report->start( name_r );
2102 report->finish( excpt_r );
2119 MIL <<
"RpmDb::doRemovePackage(" << name_r <<
"," << flags <<
")" << endl;
2128 ERR <<
"backup of " << name_r <<
" failed" << endl;
2130 report->progress( 0 );
2134 report->progress( 100 );
2139 opts.push_back(
"-e");
2140 opts.push_back(
"--allmatches");
2143 opts.push_back(
"--noscripts");
2145 opts.push_back(
"--nodeps");
2147 opts.push_back(
"--justdb");
2149 opts.push_back (
"--test");
2152 WAR <<
"IGNORE OPTION: 'rpm -e' does not support '--force'" << endl;
2155 opts.push_back(
"--");
2156 opts.push_back(name_r.c_str());
2168 report->progress( 5 );
2169 unsigned linecnt = 0;
2176 rpmmsg += line+
'\n';
2179 rpmmsg +=
"[truncated]\n";
2180 report->progress( 50 );
2183 if ( rpm_status != 0 )
2186 str::form(
"%s remove failed", name_r.c_str()),
true );
2188 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2189 historylog.
comment(sstr.str());
2194 else if ( ! rpmmsg.empty() )
2197 str::form(
"%s removed ok", name_r.c_str()),
true );
2200 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2201 historylog.
comment(sstr.str());
2205 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2234 Pathname backupFilename;
2239 INT <<
"_backuppath empty" << endl;
2247 ERR <<
"Error while getting changed files for package " <<
2248 packageName << endl;
2252 if (fileList.size() <= 0)
2254 DBG <<
"package " << packageName <<
" not changed -> no backup" << endl;
2266 struct tm *currentLocalTime = localtime(¤tTime);
2268 int date = (currentLocalTime->tm_year + 1900) * 10000
2269 + (currentLocalTime->tm_mon + 1) * 100
2270 + currentLocalTime->tm_mday;
2276 +
str::form(
"%s-%d-%d.tar.gz",packageName.c_str(), date, num);
2279 while ( PathInfo(backupFilename).isExist() && num++ < 1000);
2281 PathInfo pi(filestobackupfile);
2282 if (pi.isExist() && !pi.isFile())
2284 ERR << filestobackupfile.asString() <<
" already exists and is no file" << endl;
2288 ofstream fp ( filestobackupfile.asString().c_str(), ios::out|ios::trunc );
2292 ERR <<
"could not open " << filestobackupfile.asString() << endl;
2296 for (FileList::const_iterator cit = fileList.begin();
2297 cit != fileList.end(); ++cit)
2300 if ( name[0] ==
'/' )
2303 name = name.substr( 1 );
2305 DBG <<
"saving file "<< name << endl;
2310 const char*
const argv[] =
2315 _root.asString().c_str(),
2316 "--ignore-failed-read",
2318 backupFilename.asString().c_str(),
2320 filestobackupfile.asString().c_str(),
2336 int ret = tar.
close();
2340 ERR <<
"tar failed: " << tarmsg << endl;
2345 MIL <<
"tar backup ok" << endl;
2347 str::form(
_(
"created backup %s"), backupFilename.asString().c_str())
2366 #define OUTS(E,S) case RpmDb::E: return str << "["<< (unsigned)obj << "-"<< S << "]"; break
2368 OUTS( CHK_OK,
_(
"Signature is OK") );
2370 OUTS( CHK_NOTFOUND,
_(
"Unknown type of signature") );
2372 OUTS( CHK_FAIL,
_(
"Signature does not verify") );
2374 OUTS( CHK_NOTTRUSTED,
_(
"Signature is OK, but key is not trusted") );
2376 OUTS( CHK_NOKEY,
_(
"Signatures public key is not available") );
2378 OUTS( CHK_ERROR,
_(
"File does not exist or signature can't be checked") );
2381 return str <<
"UnknowSignatureCheckError("+
str::numstring(obj)+
")";
2386 for (
const auto & el : obj )
2387 str << el.second << endl;
std::ostream & operator<<(std::ostream &str, const librpmDb::DbDirInfo &obj)
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Interface to the rpm program.
bool hasDbV3ToV4() const
Whether dbV3ToV4 file exists.
bool hasPackage(const std::string &name_r) const
Return true if package is installed.
static unsigned blockAccess()
Blocks further access to rpmdb.
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.
unsigned split(const C_Str &line_r, _OutputIterator result_r, const C_Str &sepchars_r=" \t")
Split line_r into words.
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.
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
unsigned diffFiles(const string file1, const string file2, string &out, int maxlines)
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.
virtual std::ostream & dumpOn(std::ostream &str) const
Dump debug info.
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Edition represents [epoch:]version[-release]
bool relative() const
Test for a relative path.
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.
#define FILEFORBACKUPFILES
string stringPath(const Pathname &root_r, const Pathname &sub_r)
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.
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)
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...
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)
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.
std::ostream & operator<<(std::ostream &str, const zypp::shared_ptr< void > &obj)
std::string asString(const Patch::SeverityFlag &obj)
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)
std::set< Edition > pubkeyEditions() const
Return the edition of all installed public keys.
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.).
std::list< PublicKey > pubkeys() const
Return the long ids of all installed public keys.
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.
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
void dbsi_set(DbStateInfoBits &val_r, const unsigned &bits_r) const
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 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.
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
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
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