15 #include <rpm/rpmcli.h> 16 #include <rpm/rpmlog.h> 56 #define WARNINGMAILPATH "/var/log/YaST2/" 57 #define FILEFORBACKUPFILES "YaSTBackupModifiedFiles" 58 #define MAXRPMMESSAGELINES 10000 60 #define WORKAROUNDRPMPWDBUG 64 namespace zypp_readonly_hack
74 #if 1 // No more need to escape whitespace since rpm-4.4.2.3 75 const char* quoteInFilename_m =
"\'\"";
77 const char* quoteInFilename_m =
" \t\'\"";
79 inline std::string rpmQuoteFilename(
const Pathname & path_r )
81 std::string path( path_r.
asString() );
83 pos != std::string::npos;
84 pos = path.find_first_of( quoteInFilename_m, pos ) )
86 path.insert( pos,
"\\" );
99 #if defined(WORKAROUNDRPMPWDBUG) 103 AutoDispose<char*> cwd( ::get_current_dir_name(), ::free );
106 WAR <<
"Can't get cwd!" << endl;
127 MIL <<
"trusted key added to zypp Keyring. Importing..." << endl;
128 _rpmdb.importPubkey( key );
133 MIL <<
"Trusted key removed from zypp Keyring. Removing..." << endl;
134 _rpmdb.removePubkey( key );
142 unsigned diffFiles(
const std::string file1,
const std::string file2, std::string& out,
int maxlines)
163 if (maxlines<0?
true:count<maxlines)
191 if ( obj == RpmDb::DbSI_NO_INIT )
197 #define ENUM_OUT(B,C) str << ( obj & RpmDb::B ? C : '-' ) 220 #define FAILIFNOTINITIALIZED if( ! initialized() ) { ZYPP_THROW(RpmDbNotOpenException()); } 231 : _dbStateInfo( DbSI_NO_INIT )
232 #warning Check for obsolete memebers
233 , _backuppath (
"/var/adm/backup")
234 , _packagebackups(false)
235 , _warndirexists(false)
242 setenv(
"RPM_IgnoreFailedSymlinks",
"1", 1 );
254 MIL <<
"~RpmDb()" << endl;
257 MIL <<
"~RpmDb() end" << endl;
267 db_path =
"/var/lib/rpm";
274 return rpmdb_info.
mtime();
294 #define ENUM_OUT(B,C) str << ( _dbStateInfo & B ? C : '-' ) 320 bool quickinit( root_r.
empty() );
322 if ( root_r.
empty() )
325 if ( dbPath_r.
empty() )
326 dbPath_r =
"/var/lib/rpm";
330 ERR <<
"Illegal root or dbPath: " <<
stringPath( root_r, dbPath_r ) << endl;
334 MIL <<
"Calling initDatabase: " <<
stringPath( root_r, dbPath_r )
335 << ( doRebuild_r ?
" (rebuilddb)" :
"" )
336 << ( quickinit ?
" (quickinit)" :
"" ) << endl;
360 MIL <<
"QUICK initDatabase (no systemRoot set)" << endl;
373 ERR <<
"Cleanup on error: state " << info << endl;
388 MIL <<
"Cleanup: state " << info << endl;
397 MIL <<
"Update mode: Cleanup delayed until closeOldDatabase." << endl;
400 #warning CHECK: notify root about conversion backup. 415 MIL <<
"Synchronizing keys with zypp keyring" << endl;
424 MIL <<
"InitDatabase: " << *
this << endl;
450 ERR <<
"Bad database directory: " << dbInfo.
dbDir() << endl;
457 MIL <<
"Found rpm4 database in " << dbInfo.
dbDir() << endl;
461 MIL <<
"Creating new rpm4 database in " << dbInfo.
dbDir() << endl;
473 DBG <<
"Initial state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
492 DBG <<
"Access state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
501 bool dbEmpty = dbptr->empty();
504 MIL <<
"Empty rpm4 database " << dbInfo.
dbV4() << endl;
509 MIL <<
"Found rpm3 database " << dbInfo.
dbV3() << endl;
520 WAR <<
"Backup converted rpm3 database failed: error(" << res <<
")" << endl;
527 MIL <<
"Backup converted rpm3 database: " << dbInfo.
dbV3ToV4() << endl;
536 WAR <<
"Non empty rpm3 and rpm4 database found: using rpm4" << endl;
542 DBG <<
"Convert state: " << info_r <<
": " <<
stringPath( root_r, dbPath_r );
548 MIL <<
"Rpm3 database backup: " << dbInfo.
dbV3ToV4() << endl;
560 const char * v3backup =
"packages.rpm3";
561 const char * master =
"Packages";
562 const char * index[] =
587 ERR <<
"Can't remove rpm4 database in non directory: " << dbdir_r << endl;
591 for (
const char ** f = index; *f; ++f )
600 pi( dbdir_r + master );
603 MIL <<
"Removing rpm4 database " << pi << endl;
609 pi( dbdir_r + v3backup );
612 MIL <<
"Removing converted rpm3 database backup " << pi << endl;
626 const char * master =
"packages.rpm";
627 const char * index[] =
629 "conflictsindex.rpm",
643 ERR <<
"Can't remove rpm3 database in non directory: " << dbdir_r << endl;
647 for (
const char ** f = index; *f; ++f )
656 #warning CHECK: compare vs existing v3 backup. notify root 657 pi( dbdir_r + master );
670 Pathname b( m.extend(
".deleted" ) );
680 MIL <<
"(Re)moved rpm3 database to " << pi << endl;
720 MIL <<
"Calling closeDatabase: " << *
this << endl;
751 MIL <<
"closeDatabase: " << *
this << endl;
782 MIL <<
"RpmDb::rebuildDatabase" << *
this << endl;
790 opts.push_back(
"--rebuilddb");
791 opts.push_back(
"-vv");
813 WAR <<
"User requested abort." << endl;
819 if ( line.compare( 0, 2,
"D:" ) )
821 errmsg += line +
'\n';
829 if ( rpm_status != 0 )
847 void computeKeyRingSync( std::set<Edition> & rpmKeys_r, std::list<PublicKeyData> & zyppKeys_r )
858 void updateIf(
const Edition & rpmKey_r )
860 std::string keyRelease( rpmKey_r.
release() );
861 int comp = _release.compare( keyRelease );
865 _release.swap( keyRelease );
866 _inRpmKeys = &rpmKey_r;
867 _inZyppKeys =
nullptr;
868 if ( !keyRelease.empty() )
869 DBG <<
"Old key in Z: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
871 else if ( comp == 0 )
875 _inRpmKeys = &rpmKey_r;
879 DBG <<
"Old key in R: gpg-pubkey-" << rpmKey_r.
version() <<
"-" << keyRelease << endl;
882 void updateIf(
const PublicKeyData & zyppKey_r )
884 std::string keyRelease( zyppKey_r.gpgPubkeyRelease() );
885 int comp = _release.compare( keyRelease );
889 _release.swap( keyRelease );
890 _inRpmKeys =
nullptr;
891 _inZyppKeys = &zyppKey_r;
892 if ( !keyRelease.empty() )
893 DBG <<
"Old key in R: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() <<
"-" << keyRelease << endl;
895 else if ( comp == 0 )
899 _inZyppKeys = &zyppKey_r;
903 DBG <<
"Old key in Z: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() <<
"-" << keyRelease << endl;
906 std::string _release;
907 const Edition * _inRpmKeys;
908 const PublicKeyData * _inZyppKeys;
913 std::map<std::string,Key> _keymap;
915 for_( it, rpmKeys_r.begin(), rpmKeys_r.end() )
917 _keymap[(*it).version()].updateIf( *it );
920 for_( it, zyppKeys_r.begin(), zyppKeys_r.end() )
922 _keymap[(*it).gpgPubkeyVersion()].updateIf( *it );
926 std::set<Edition> rpmKeys;
927 std::list<PublicKeyData> zyppKeys;
928 for_( it, _keymap.begin(), _keymap.end() )
930 DBG <<
"gpg-pubkey-" << (*it).first <<
"-" << (*it).second._release <<
" " 931 << ( (*it).second._inRpmKeys ?
"R" :
"_" )
932 << ( (*it).second._inZyppKeys ?
"Z" :
"_" ) << endl;
933 if ( ! (*it).second._inRpmKeys )
935 zyppKeys.push_back( *(*it).second._inZyppKeys );
937 if ( ! (*it).second._inZyppKeys )
939 rpmKeys.insert( *(*it).second._inRpmKeys );
942 rpmKeys_r.swap( rpmKeys );
943 zyppKeys_r.swap( zyppKeys );
950 MIL <<
"Going to sync trusted keys..." << endl;
952 std::list<PublicKeyData> zyppKeys( getZYpp()->keyRing()->trustedPublicKeyData() );
964 MIL <<
"Removing excess keys in zypp trusted keyring" << std::endl;
970 if ( ! rpmKeys.count( keyData.gpgPubkeyEdition() ) )
972 DBG <<
"Excess key in Z to delete: gpg-pubkey-" << keyData.gpgPubkeyEdition() << endl;
973 getZYpp()->keyRing()->deleteKey( keyData.id(), true );
974 if ( !dirty ) dirty =
true;
978 zyppKeys = getZYpp()->keyRing()->trustedPublicKeyData();
981 computeKeyRingSync( rpmKeys, zyppKeys );
982 MIL << (mode_r &
SYNC_TO_KEYRING ?
"" :
"(skip) ") <<
"Rpm keys to export into zypp trusted keyring: " << rpmKeys.size() << endl;
983 MIL << (mode_r &
SYNC_FROM_KEYRING ?
"" :
"(skip) ") <<
"Zypp trusted keys to import into rpm database: " << zyppKeys.size() << endl;
989 MIL <<
"Exporting rpm keyring into zypp trusted keyring" <<endl;
994 TmpFile tmpfile( getZYpp()->tmpPath() );
996 std::ofstream tmpos( tmpfile.
path().
c_str() );
997 for_( it, rpmKeys.begin(), rpmKeys.end() )
1001 getData(
"gpg-pubkey", *it, result );
1002 tmpos << result->tag_description() << endl;
1007 getZYpp()->keyRing()->multiKeyImport( tmpfile.
path(),
true );
1011 ERR <<
"Could not import keys into in zypp keyring" << endl;
1019 MIL <<
"Importing zypp trusted keyring" << std::endl;
1020 for_( it, zyppKeys.begin(), zyppKeys.end() )
1024 importPubkey( getZYpp()->keyRing()->exportTrustedPublicKey( *it ) );
1032 MIL <<
"Trusted keys synced." << endl;
1054 WAR <<
"Key " << pubkey_r <<
" can not be imported. (READONLY MODE)" << endl;
1061 bool hasOldkeys =
false;
1063 for_( it, rpmKeys.begin(), rpmKeys.end() )
1070 if ( keyEd == *it && !pubkey_r.
hasSubkeys() )
1072 MIL <<
"Key " << pubkey_r <<
" is already in the rpm trusted keyring. (skip import)" << endl;
1076 if ( keyEd.version() != (*it).version() )
1079 if ( keyEd.release() < (*it).release() )
1081 MIL <<
"Key " << pubkey_r <<
" is older than one in the rpm trusted keyring. (skip import)" << endl;
1089 MIL <<
"Key " << pubkey_r <<
" will be imported into the rpm trusted keyring." << (hasOldkeys?
"(update)":
"(new)") << endl;
1095 std::string keyName(
"gpg-pubkey-" + keyEd.version() );
1097 opts.push_back (
"-e" );
1098 opts.push_back (
"--allmatches" );
1099 opts.push_back (
"--" );
1100 opts.push_back ( keyName.c_str() );
1113 ERR <<
"Failed to remove key " << pubkey_r <<
" from RPM trusted keyring (ignored)" << endl;
1117 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1123 opts.push_back (
"--import" );
1124 opts.push_back (
"--" );
1126 opts.push_back ( pubkeypath.c_str() );
1133 std::vector<std::string> excplines;
1138 WAR << line << endl;
1139 excplines.push_back( std::move(line) );
1142 DBG << line << endl;
1155 MIL <<
"Key " << pubkey_r <<
" imported in rpm trusted keyring." << endl;
1172 std::set<Edition>::const_iterator found_edition = rpm_keys.end();
1175 for_( it, rpm_keys.begin(), rpm_keys.end() )
1177 if ( (*it).version() == pubkeyVersion )
1185 if (found_edition == rpm_keys.end())
1187 WAR <<
"Key " << pubkey_r.
id() <<
" is not in rpm db" << endl;
1191 std::string rpm_name(
"gpg-pubkey-" + found_edition->asString());
1194 opts.push_back (
"-e" );
1195 opts.push_back (
"--" );
1196 opts.push_back ( rpm_name.c_str() );
1203 std::vector<std::string> excplines;
1208 WAR << line << endl;
1209 excplines.push_back( std::move(line) );
1212 DBG << line << endl;
1225 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1237 std::list<PublicKey> ret;
1240 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1242 Edition edition = it->tag_edition();
1247 getData(
"gpg-pubkey", edition, result );
1248 TmpFile file(getZYpp()->tmpPath());
1254 os << result->tag_description();
1263 catch ( std::exception & e )
1265 ERR <<
"Could not dump key " << edition.
asString() <<
" in tmp file " << file.
path() << endl;
1275 std::set<Edition> ret;
1278 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1280 Edition edition = it->tag_edition();
1282 ret.insert( edition );
1299 std::list<FileInfo> result;
1334 if (!name_r.empty())
1336 res = (it->tag_name() == name_r);
1357 return it->tag_name();
1471 struct RpmlogCapture :
public std::string
1474 { rpmlog()._cap =
this; }
1477 { rpmlog()._cap =
nullptr; }
1485 rpmlogSetCallback( rpmLogCB,
this );
1486 rpmSetVerbosity( RPMLOG_INFO );
1487 _f = ::fopen(
"/dev/null",
"w");
1488 rpmlogSetFile(
_f );
1492 {
if (
_f ) ::fclose(
_f ); }
1494 static int rpmLogCB( rpmlogRec rec_r, rpmlogCallbackData data_r )
1495 {
return reinterpret_cast<Rpmlog*
>(data_r)->rpmLog( rec_r ); }
1497 int rpmLog( rpmlogRec rec_r )
1499 if (
_cap ) (*_cap) += rpmlogRecMessage( rec_r );
1500 return RPMLOG_DEFAULT;
1507 static Rpmlog & rpmlog()
1508 {
static Rpmlog _rpmlog;
return _rpmlog; }
1513 bool requireGPGSig_r,
1514 RpmDb::CheckPackageDetail & detail_r )
1517 if ( ! file.isFile() )
1519 ERR <<
"Not a file: " << file << endl;
1523 FD_t fd = ::Fopen( file.asString().c_str(),
"r.ufdio" );
1524 if ( fd == 0 || ::Ferror(fd) )
1526 ERR <<
"Can't open file for reading: " << file <<
" (" << ::Fstrerror(fd) <<
")" << endl;
1531 rpmts ts = ::rpmtsCreate();
1532 ::rpmtsSetRootDir( ts, root_r.
c_str() );
1533 ::rpmtsSetVSFlags( ts, RPMVSF_DEFAULT );
1535 rpmQVKArguments_s qva;
1536 memset( &qva, 0,
sizeof(rpmQVKArguments_s) );
1537 qva.qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE);
1539 RpmlogCapture vresult;
1540 LocaleGuard guard( LC_ALL,
"C" );
1541 int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.
basename().c_str() );
1554 std::vector<std::string> lines;
1555 str::split( vresult, std::back_inserter(lines),
"\n" );
1556 unsigned count[7] = { 0, 0, 0, 0, 0, 0, 0 };
1558 for (
unsigned i = 1; i < lines.size(); ++i )
1560 std::string & line( lines[i] );
1562 if ( line.find(
": OK" ) != std::string::npos )
1565 if ( line.find(
"Signature, key ID" ) == std::string::npos )
1568 else if ( line.find(
": NOKEY" ) != std::string::npos )
1570 else if ( line.find(
": BAD" ) != std::string::npos )
1572 else if ( line.find(
": UNKNOWN" ) != std::string::npos )
1574 else if ( line.find(
": NOTRUSTED" ) != std::string::npos )
1578 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( lineres, std::move(line) ) );
1599 detail_r.push_back( RpmDb::CheckPackageDetail::value_type(
RpmDb::CHK_NOSIG, std::string(
" ")+
_(
"Package is not signed!") ) );
1600 if ( requireGPGSig_r )
1607 WAR << path_r <<
" (" << requireGPGSig_r <<
" -> " << ret <<
")" << endl;
1620 {
return doCheckPackageSig( path_r,
root(),
false, detail_r ); }
1626 {
return doCheckPackageSig( path_r,
root(),
true, detail_r ); }
1641 opts.push_back (
"-V");
1642 opts.push_back (
"--nodeps");
1643 opts.push_back (
"--noscripts");
1644 opts.push_back (
"--nomd5");
1645 opts.push_back (
"--");
1646 opts.push_back (packageName.c_str());
1667 if (line.length() > 12 &&
1668 (line[0] ==
'S' || line[0] ==
's' ||
1669 (line[0] ==
'.' && line[7] ==
'T')))
1672 std::string filename;
1674 filename.assign(line, 11, line.length() - 11);
1715 #if defined(WORKAROUNDRPMPWDBUG) 1716 args.push_back(
"#/");
1718 args.push_back(
"rpm");
1719 args.push_back(
"--root");
1721 args.push_back(
"--dbpath");
1724 const char* argv[args.size() + opts.size() + 1];
1726 const char** p = argv;
1727 p =
copy (args.begin (), args.end (), p);
1728 p =
copy (opts.begin (), opts.end (), p);
1754 int inputfileFd = ::fileno( inputfile );
1760 FD_SET( inputfileFd, &rfds );
1767 int retval = select( inputfileFd+1, &rfds, NULL, NULL, &tv );
1771 ERR <<
"select error: " <<
strerror(errno) << endl;
1772 if ( errno != EINTR )
1778 static size_t linebuffer_size = 0;
1779 static char * linebuffer = 0;
1780 ssize_t nread =
getline( &linebuffer, &linebuffer_size, inputfile );
1783 if ( ::feof( inputfile ) )
1790 if ( linebuffer[nread-1] ==
'\n' )
1792 line += std::string( linebuffer, nread );
1795 if ( ! ::ferror( inputfile ) || ::feof( inputfile ) )
1798 clearerr( inputfile );
1847 void RpmDb::processConfigFiles(
const std::string& line,
const std::string& name,
const char* typemsg,
const char* difffailmsg,
const char* diffgenmsg)
1849 std::string msg = line.substr(9);
1852 std::string file1s, file2s;
1856 pos1 = msg.find (typemsg);
1859 if ( pos1 == std::string::npos )
1862 pos2 = pos1 + strlen (typemsg);
1864 if (pos2 >= msg.length() )
1867 file1 = msg.substr (0, pos1);
1868 file2 = msg.substr (pos2);
1875 file1 =
_root + file1;
1876 file2 =
_root + file2;
1886 ERR <<
"Could not create " << file.
asString() << endl;
1890 std::ofstream notify(file.
asString().c_str(), std::ios::out|std::ios::app);
1893 ERR <<
"Could not open " << file << endl;
1899 notify <<
str::form(
_(
"Changed configuration files for %s:"), name.c_str()) << endl;
1902 ERR <<
"diff failed" << endl;
1904 file1s.c_str(), file2s.c_str()) << endl;
1909 file1s.c_str(), file2s.c_str()) << endl;
1914 if (out.substr(0,4) ==
"--- ")
1916 out.replace(4, file1.
asString().length(), file1s);
1919 if (pos != std::string::npos)
1921 out.replace(pos+5, file2.
asString().length(), file2s);
1924 notify << out << endl;
1927 notify.open(
"/var/lib/update-messages/yast2-packagemanager.rpmdb.configfiles");
1932 WAR <<
"rpm created " << file2 <<
" but it is not different from " << file2 << endl;
1963 report->finish( excpt_r );
1979 MIL <<
"RpmDb::installPackage(" << filename <<
"," << flags <<
")" << endl;
1988 ERR <<
"backup of " << filename.
asString() <<
" failed" << endl;
1997 opts.push_back(
"-i");
1999 opts.push_back(
"-U");
2001 opts.push_back(
"--percent");
2002 opts.push_back(
"--noglob");
2006 opts.push_back(
"--ignorearch");
2009 opts.push_back(
"--nodigest");
2011 opts.push_back(
"--nosignature");
2013 opts.push_back (
"--excludedocs");
2015 opts.push_back (
"--noscripts");
2017 opts.push_back (
"--force");
2019 opts.push_back (
"--nodeps");
2021 opts.push_back (
"--ignoresize");
2023 opts.push_back (
"--justdb");
2025 opts.push_back (
"--test");
2027 opts.push_back (
"--noposttrans");
2029 opts.push_back(
"--");
2032 std::string quotedFilename( rpmQuoteFilename( workaroundRpmPwdBug( filename ) ) );
2033 opts.push_back ( quotedFilename.c_str() );
2040 std::vector<std::string> configwarnings;
2042 unsigned linecnt = 0;
2048 sscanf( line.c_str() + 2,
"%d", &percent );
2049 report->progress( percent );
2055 else if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2058 rpmmsg += line+
'\n';
2061 configwarnings.push_back(line);
2064 rpmmsg +=
"[truncated]\n";
2069 for (std::vector<std::string>::iterator it = configwarnings.begin();
2070 it != configwarnings.end(); ++it)
2074 _(
"rpm saved %s as %s, but it was impossible to determine the difference"),
2076 _(
"rpm saved %s as %s.\nHere are the first 25 lines of difference:\n"));
2079 _(
"rpm created %s as %s, but it was impossible to determine the difference"),
2081 _(
"rpm created %s as %s.\nHere are the first 25 lines of difference:\n"));
2084 if ( rpm_status != 0 )
2089 std::ostringstream sstr;
2090 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2091 historylog.
comment(sstr.str());
2095 else if ( ! rpmmsg.empty() )
2100 std::ostringstream sstr;
2101 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2102 historylog.
comment(sstr.str());
2106 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2120 +
"-" + package->edition().version()
2121 +
"-" + package->edition().release()
2122 +
"." + package->arch().asString(), flags );
2150 report->finish( excpt_r );
2167 MIL <<
"RpmDb::doRemovePackage(" << name_r <<
"," << flags <<
")" << endl;
2176 ERR <<
"backup of " << name_r <<
" failed" << endl;
2187 opts.push_back(
"-e");
2188 opts.push_back(
"--allmatches");
2191 opts.push_back(
"--noscripts");
2193 opts.push_back(
"--nodeps");
2195 opts.push_back(
"--justdb");
2197 opts.push_back (
"--test");
2200 WAR <<
"IGNORE OPTION: 'rpm -e' does not support '--force'" << endl;
2203 opts.push_back(
"--");
2204 opts.push_back(name_r.c_str());
2217 unsigned linecnt = 0;
2222 else if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2224 rpmmsg += line+
'\n';
2227 rpmmsg +=
"[truncated]\n";
2231 if ( rpm_status != 0 )
2234 str::form(
"%s remove failed", name_r.c_str()),
true );
2235 std::ostringstream sstr;
2236 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2237 historylog.
comment(sstr.str());
2241 else if ( ! rpmmsg.empty() )
2244 str::form(
"%s removed ok", name_r.c_str()),
true );
2246 std::ostringstream sstr;
2247 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2248 historylog.
comment(sstr.str());
2252 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2286 INT <<
"_backuppath empty" << endl;
2294 ERR <<
"Error while getting changed files for package " <<
2295 packageName << endl;
2301 DBG <<
"package " << packageName <<
" not changed -> no backup" << endl;
2313 struct tm *currentLocalTime = localtime(&
currentTime);
2315 int date = (currentLocalTime->tm_year + 1900) * 10000
2316 + (currentLocalTime->tm_mon + 1) * 100
2317 + currentLocalTime->tm_mday;
2323 +
str::form(
"%s-%d-%d.tar.gz",packageName.c_str(), date, num);
2331 ERR << filestobackupfile.
asString() <<
" already exists and is no file" << endl;
2335 std::ofstream fp ( filestobackupfile.
asString().c_str(), std::ios::out|std::ios::trunc );
2339 ERR <<
"could not open " << filestobackupfile.
asString() << endl;
2343 for (FileList::const_iterator cit =
fileList.begin();
2346 std::string name = *cit;
2347 if ( name[0] ==
'/' )
2350 name = name.substr( 1 );
2352 DBG <<
"saving file "<< name << endl;
2357 const char*
const argv[] =
2363 "--ignore-failed-read",
2367 filestobackupfile.
asString().c_str(),
2383 int ret = tar.
close();
2387 ERR <<
"tar failed: " << tarmsg << endl;
2392 MIL <<
"tar backup ok" << endl;
2413 #define OUTS(E,S) case RpmDb::E: return str << "["<< (unsigned)obj << "-"<< S << "]"; break 2415 OUTS( CHK_OK,
_(
"Signature is OK") );
2417 OUTS( CHK_NOTFOUND,
_(
"Unknown type of signature") );
2419 OUTS( CHK_FAIL,
_(
"Signature does not verify") );
2421 OUTS( CHK_NOTTRUSTED,
_(
"Signature is OK, but key is not trusted") );
2423 OUTS( CHK_NOKEY,
_(
"Signatures public key is not available") );
2425 OUTS( CHK_ERROR,
_(
"File does not exist or signature can't be checked") );
2427 OUTS( CHK_NOSIG,
_(
"File is unsigned") );
2435 for (
const auto & el : obj )
2436 str << el.second << endl;
std::ostream & operator<<(std::ostream &str, const librpmDb::DbDirInfo &obj)
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Interface to the rpm program.
unsigned diffFiles(const std::string file1, const std::string file2, std::string &out, int maxlines)
CheckPackageResult checkPackageSignature(const Pathname &path_r, CheckPackageDetail &detail_r)
Check signature of rpm file on disk (strict check returning CHK_NOSIG if file is unsigned).
bool hasRequiredBy(const std::string &tag_r) const
Return true if at least one package requires a certain tag.
static unsigned blockAccess()
Blocks further access to rpmdb.
static std::ostream & dumpState(std::ostream &str)
Dump debug info.
const Pathname & path() const
Return current Pathname.
void getData(const std::string &name_r, RpmHeader::constPtr &result_r) const
Get an installed packages data from rpmdb.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
virtual void trustedKeyAdded(const PublicKey &key)
bool kill()
Kill the program.
static ZConfig & instance()
Singleton ctor.
Pathname _root
Root directory for all operations.
bool findByProvides(const std::string &tag_r)
Reset to iterate all packages that provide a certain tag.
const PathInfo & dbV3ToV4() const
rpmV3 database backup created on conversion to rpmV4 (_dbDir/packages.rpm3)
Class representing one GPG Public Keys data.
Collect info about what kind of rpmdb seems to be present by looking at paths and filenames...
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
void exportTrustedKeysInZyppKeyRing()
insert all rpm trusted keys into zypp trusted keyring
static void dbAccess()
Access the database at the current default location.
void rebuildDatabase()
Rebuild the rpm database (rpm –rebuilddb).
void installPackage(const Pathname &filename, RpmInstFlags flags=RPMINST_NONE)
install rpm package
const char * c_str() const
String representation.
Date timestamp() const
timestamp of the rpm database (last modification)
void internal_initDatabase(const Pathname &root_r, const Pathname &dbPath_r, DbStateInfoBits &info_r)
Internal helper for initDatabase.
String related utilities and Regular expression matching.
bool hasDbV3() const
Whether dbV3 file exists.
bool findByRequiredBy(const std::string &tag_r)
Reset to iterate all packages that require a certain tag.
void modifyDatabase()
Called before the database is modified by installPackage/removePackage.
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \)
Split line_r into words.
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Edition represents [epoch:]version[-release]
bool running()
Return whether program is running.
bool usableArgs() const
Whether constructor arguments were llegal and dbDir either is a directory or may be created (path doe...
bool hasSubkeys() const
!<
std::string basename() const
Return the last component of this path.
Provide a new empty temporary file and delete it when no longer needed.
void importZyppKeyRingTrustedKeys()
iterates through zypp keyring and import all non existant keys into rpm keyring
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
bool backupPackage(const std::string &packageName)
create tar.gz of all changed files in a Package
CheckPackageResult checkPackage(const Pathname &path_r, CheckPackageDetail &detail_r)
Check signature of rpm file on disk (legacy version returning CHK_OK if file is unsigned, like 'rpm -K')
#define FILEFORBACKUPFILES
Subclass to retrieve database content.
Temporarily connect a ReceiveReport then restore the previous one.
void importPubkey(const PublicKey &pubkey_r)
Import ascii armored public key in file pubkey_r.
bool hasDbV3ToV4() const
Whether dbV3ToV4 file exists.
bool hasPackage(const std::string &name_r) const
Return true if package is installed.
void systemKill()
Forcably kill the system process.
bool empty() const
Test for an empty path.
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
void moveToHistory(TContainer &&msgc_r)
addHistory from string container types (oldest first) moving
void syncTrustedKeys(SyncTrustedKeyBits mode_r=SYNC_BOTH)
Sync trusted keys stored in rpm database and zypp trusted keyring.
#define FAILIFNOTINITIALIZED
std::string getline(std::istream &str)
Read one line from stream.
Store and operate on date (time_t).
const std::string & execError() const
Some detail telling why the execution failed, if it failed.
Pathname _backuppath
/var/adm/backup
std::string version() const
Version.
shared_ptr< RpmException > dbError() const
Return any database error.
std::string form(const std::string &format_r) const
Return string representation according to format as localtime.
std::string asString() const
int exit_code
The exit code of the rpm process, or -1 if not yet known.
std::list< PublicKey > pubkeys() const
Return the long ids of all installed public keys.
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
void dbsi_set(DbStateInfoBits &val_r, const unsigned &bits_r) const
int unlink(const Pathname &path)
Like 'unlink'.
std::string gpgPubkeyVersion() const
SyncTrustedKeyBits
Sync mode for syncTrustedKeys.
bool systemReadLine(std::string &line)
Read a line from the general rpm query.
const std::string & asString() const
String representation.
int rename(const Pathname &oldpath, const Pathname &newpath)
Like 'rename'.
int systemStatus()
Return the exit status of the general rpm process, closing the connection if not already done...
std::set< Edition > pubkeyEditions() const
Return the edition of all installed public keys.
bool isExist() const
Return whether valid stat info exists.
bool findByName(const std::string &name_r)
Reset to iterate all packages with a certain name.
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
std::string release() const
Release.
Detailed rpm signature check log messages A single multiline message if CHK_OK.
virtual std::ostream & dumpOn(std::ostream &str) const
Dump debug info.
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
Types and functions for filesystem operations.
static unsigned dbRelease(bool force_r=false)
If there are no outstanding references to the database (e.g.
static shared_ptr< KeyRingSignalReceiver > sKeyRingReceiver
ExternalProgram * process
The connection to the rpm process.
Writing the zypp history fileReference counted signleton for writhing the zypp history file...
void doRebuildDatabase(callback::SendReport< RebuildDBReport > &report)
bool absolute() const
Test for an absolute path.
bool findByFile(const std::string &file_r)
Reset to iterate all packages that own a certain file.
std::string receiveLine()
Read one line from the input stream.
void closeDatabase()
Block further access to the rpm database and go back to uninitialized state.
Stderr_Disposition
Define symbols for different policies on the handling of stderr.
DbStateInfoBits _dbStateInfo
Internal state info.
bool hasProvides(const std::string &tag_r) const
Return true if at least one package provides a certain tag.
bool dbsi_has(const DbStateInfoBits &val_r, const unsigned &bits_r) const
Just inherits Exception to separate media exceptions.
std::string numstring(char n, int w=0)
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.
bool illegalArgs() const
Whether constructor arguments were illegal.
static void unblockAccess()
Allow access to rpmdb e.g.
std::ostream & copy(std::istream &from_r, std::ostream &to_r)
Copy istream to ostream.
void doInstallPackage(const Pathname &filename, RpmInstFlags flags, callback::SendReport< RpmInstallReport > &report)
int close()
Wait for the progamm to complete.
void removePubkey(const PublicKey &pubkey_r)
Remove a public key from the rpm database.
void processConfigFiles(const std::string &line, const std::string &name, const char *typemsg, const char *difffailmsg, const char *diffgenmsg)
handle rpm messages like "/etc/testrc saved as /etc/testrc.rpmorig"
int copy(const Pathname &file, const Pathname &dest)
Like 'cp file dest'.
bool _packagebackups
create package backups?
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
std::string gpgPubkeyRelease() const
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
const PathInfo & dbV3() const
rpmV3 database (_dbDir/packages.rpm)
void doRemovePackage(const std::string &name_r, RpmInstFlags flags, callback::SendReport< RpmRemoveReport > &report)
Base class for Exception.
bool hasDbV4() const
Whether dbV4 file exists.
void setBackupPath(const Pathname &path)
set path where package backups are stored
const Pathname & root() const
bool hasConflicts(const std::string &tag_r) const
Return true if at least one package conflicts with a certain tag.
Pathname path() const
File containig the ASCII armored key.
const Pathname & dbPath() const
const PathInfo & dbV4() const
rpmV4 database (_dbDir/Packages)
static Date now()
Return the current time.
void convertV3toV4(const Pathname &v3db_r, const librpmDb::constPtr &v4db_r)
void initDatabase(Pathname root_r=Pathname(), Pathname dbPath_r=Pathname(), bool doRebuild_r=false)
Prepare access to the rpm database.
std::string error_message
Error message from running rpm as external program.
std::string whoOwnsFile(const std::string &file_r) const
Return name of package owning file or empty string if no installed package owns file.
void removePackage(const std::string &name_r, RpmInstFlags flags=RPMINST_NONE)
remove rpm package
static bool globalInit()
Initialize lib librpm (read configfiles etc.).
std::list< FileInfo > fileList(const std::string &name_r, const Edition &edition_r) const
return complete file list for installed package name_r (in FileInfo.filename) if edition_r != Edition...
std::string asString() const
bool relative() const
Test for a relative path.
bool hasFile(const std::string &file_r, const std::string &name_r="") const
Return true if at least one package owns a certain file (name_r empty) Return true if package name_r ...
void comment(const std::string &comment, bool timestamp=false)
Log a comment (even multiline).
bool findByConflicts(const std::string &tag_r)
Reset to iterate all packages that conflict with a certain tag.
Wrapper class for ::stat/::lstat.
void setBlocking(bool mode)
Set the blocking mode of the input stream.
CheckPackageResult
checkPackage result
std::string stringPath(const Pathname &root_r, const Pathname &sub_r)
static void removeV3(const Pathname &dbdir_r, bool v3backup_r)
Remove the rpm3 database in dbdir_r.
bool queryChangedFiles(FileList &fileList, const std::string &packageName)
determine which files of an installed package have been modified.
static void removeV4(const Pathname &dbdir_r, bool v3backup_r)
Remove the rpm4 database in dbdir_r and optionally any backup created on conversion.
FILE * inputFile() const
Return the input stream.
std::string strerror(int errno_r)
Return string describing the error_r code.
std::ostream & operator<<(std::ostream &str, const Glob &obj)
intrusive_ptr< const librpmDb > constPtr
Easy-to use interface to the ZYPP dependency resolver.
void run_rpm(const RpmArgVec &options, ExternalProgram::Stderr_Disposition stderr_disp=ExternalProgram::Stderr_To_Stdout)
Run rpm with the specified arguments and handle stderr.
KeyRingSignalReceiver(RpmDb &rpmdb)
void dbsi_clr(DbStateInfoBits &val_r, const unsigned &bits_r) const
void restat()
Restat all paths.
TraitsType::constPtrType constPtr
#define MAXRPMMESSAGELINES
static const Edition noedition
Value representing noedition ("") This is in fact a valid Edition.
Pathname _dbPath
Directory that contains the rpmdb.
std::set< std::string > FileList
const PathInfo & dbDir() const
database directory (unset on illegal constructor arguments)
std::vector< const char * > RpmArgVec