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,
"\\" );
97 inline Pathname workaroundRpmPwdBug( Pathname path_r )
99 #if defined(WORKAROUNDRPMPWDBUG) 100 if ( path_r.relative() )
105 return Pathname( cwd ) / path_r;
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)
178 inline std::string
stringPath(
const Pathname & root_r,
const Pathname & sub_r )
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;
258 sKeyRingReceiver.reset();
267 db_path =
"/var/lib/rpm";
271 PathInfo rpmdb_info(
root() + db_path +
"/Packages");
273 if ( rpmdb_info.isExist() )
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";
328 if ( ! (root_r.absolute() && dbPath_r.absolute()) )
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[] =
584 PathInfo pi( dbdir_r );
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",
640 PathInfo pi( dbdir_r );
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 );
660 Pathname m( pi.path() );
665 Pathname b( m.extend(
"3" ) );
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;
785 PathInfo dbMaster(
root() +
dbPath() +
"Packages" );
786 PathInfo dbMasterBackup( dbMaster.path().extend(
".y2backup" ) );
790 opts.push_back(
"--rebuilddb");
791 opts.push_back(
"-vv");
798 PathInfo newMaster(
root()
811 if ( ! report->progress( (100 * newMaster.size()) / dbMaster.size(),
root() +
dbPath()) )
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 )
854 : _inRpmKeys(
nullptr )
855 , _inZyppKeys(
nullptr )
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;
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;
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() );
953 computeKeyRingSync( rpmKeys, zyppKeys );
954 MIL << (mode_r &
SYNC_TO_KEYRING ?
"" :
"(skip) ") <<
"Rpm keys to export into zypp trusted keyring: " << rpmKeys.size() << endl;
955 MIL << (mode_r &
SYNC_FROM_KEYRING ?
"" :
"(skip) ") <<
"Zypp trusted keys to import into rpm database: " << zyppKeys.size() << endl;
961 MIL <<
"Exporting rpm keyring into zypp trusted keyring" <<endl;
966 TmpFile tmpfile( getZYpp()->tmpPath() );
968 std::ofstream tmpos( tmpfile.
path().
c_str() );
969 for_( it, rpmKeys.begin(), rpmKeys.end() )
973 getData(
"gpg-pubkey", *it, result );
974 tmpos << result->tag_description() << endl;
979 getZYpp()->keyRing()->multiKeyImport( tmpfile.
path(),
true );
983 ERR <<
"Could not import keys into in zypp keyring" << endl;
991 MIL <<
"Importing zypp trusted keyring" << std::endl;
992 for_( it, zyppKeys.begin(), zyppKeys.end() )
996 importPubkey( getZYpp()->keyRing()->exportTrustedPublicKey( *it ) );
1004 MIL <<
"Trusted keys synced." << endl;
1026 WAR <<
"Key " << pubkey_r <<
" can not be imported. (READONLY MODE)" << endl;
1033 bool hasOldkeys =
false;
1035 for_( it, rpmKeys.begin(), rpmKeys.end() )
1042 if ( keyEd == *it && !pubkey_r.
hasSubkeys() )
1044 MIL <<
"Key " << pubkey_r <<
" is already in the rpm trusted keyring. (skip import)" << endl;
1048 if ( keyEd.version() != (*it).version() )
1051 if ( keyEd.release() < (*it).release() )
1053 MIL <<
"Key " << pubkey_r <<
" is older than one in the rpm trusted keyring. (skip import)" << endl;
1061 MIL <<
"Key " << pubkey_r <<
" will be imported into the rpm trusted keyring." << (hasOldkeys?
"(update)":
"(new)") << endl;
1067 std::string keyName(
"gpg-pubkey-" + keyEd.version() );
1069 opts.push_back (
"-e" );
1070 opts.push_back (
"--allmatches" );
1071 opts.push_back (
"--" );
1072 opts.push_back ( keyName.c_str() );
1085 ERR <<
"Failed to remove key " << pubkey_r <<
" from RPM trusted keyring (ignored)" << endl;
1089 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1095 opts.push_back (
"--import" );
1096 opts.push_back (
"--" );
1097 std::string pubkeypath( pubkey_r.
path().asString() );
1098 opts.push_back ( pubkeypath.c_str() );
1105 std::vector<std::string> excplines;
1110 WAR << line << endl;
1111 excplines.push_back( std::move(line) );
1114 DBG << line << endl;
1127 MIL <<
"Key " << pubkey_r <<
" imported in rpm trusted keyring." << endl;
1144 std::set<Edition>::const_iterator found_edition = rpm_keys.end();
1147 for_( it, rpm_keys.begin(), rpm_keys.end() )
1149 if ( (*it).version() == pubkeyVersion )
1157 if (found_edition == rpm_keys.end())
1159 WAR <<
"Key " << pubkey_r.
id() <<
" is not in rpm db" << endl;
1163 std::string rpm_name(
"gpg-pubkey-" + found_edition->asString());
1166 opts.push_back (
"-e" );
1167 opts.push_back (
"--" );
1168 opts.push_back ( rpm_name.c_str() );
1175 std::vector<std::string> excplines;
1180 WAR << line << endl;
1181 excplines.push_back( std::move(line) );
1184 DBG << line << endl;
1197 MIL <<
"Key " << pubkey_r <<
" has been removed from RPM trusted keyring" << endl;
1209 std::list<PublicKey> ret;
1212 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1214 Edition edition = it->tag_edition();
1219 getData(
"gpg-pubkey", edition, result );
1220 TmpFile file(getZYpp()->tmpPath());
1226 os << result->tag_description();
1235 catch ( std::exception & e )
1237 ERR <<
"Could not dump key " << edition.
asString() <<
" in tmp file " << file.
path() << endl;
1247 std::set<Edition> ret;
1250 for ( it.
findByName(
"gpg-pubkey" ); *it; ++it )
1252 Edition edition = it->tag_edition();
1254 ret.insert( edition );
1271 std::list<FileInfo> result;
1306 if (!name_r.empty())
1308 res = (it->tag_name() == name_r);
1329 return it->tag_name();
1443 struct RpmlogCapture :
public std::string
1446 { rpmlog()._cap =
this; }
1449 { rpmlog()._cap =
nullptr; }
1457 rpmlogSetCallback( rpmLogCB,
this );
1458 rpmSetVerbosity( RPMLOG_INFO );
1459 _f = ::fopen(
"/dev/null",
"w");
1460 rpmlogSetFile(
_f );
1464 {
if (
_f ) ::fclose(
_f ); }
1466 static int rpmLogCB( rpmlogRec rec_r, rpmlogCallbackData data_r )
1467 {
return reinterpret_cast<Rpmlog*
>(data_r)->rpmLog( rec_r ); }
1469 int rpmLog( rpmlogRec rec_r )
1471 if (
_cap ) (*_cap) = rpmlogRecMessage( rec_r );
1472 return RPMLOG_DEFAULT;
1479 static Rpmlog & rpmlog()
1480 {
static Rpmlog _rpmlog;
return _rpmlog; }
1485 bool requireGPGSig_r,
1486 RpmDb::CheckPackageDetail & detail_r )
1491 ERR <<
"Not a file: " << file << endl;
1495 FD_t fd = ::Fopen( file.
asString().c_str(),
"r.ufdio" );
1496 if ( fd == 0 || ::Ferror(fd) )
1498 ERR <<
"Can't open file for reading: " << file <<
" (" << ::Fstrerror(fd) <<
")" << endl;
1503 rpmts ts = ::rpmtsCreate();
1504 ::rpmtsSetRootDir( ts, root_r.
c_str() );
1505 ::rpmtsSetVSFlags( ts, RPMVSF_DEFAULT );
1507 rpmQVKArguments_s qva;
1508 memset( &qva, 0,
sizeof(rpmQVKArguments_s) );
1509 qva.qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE);
1511 RpmlogCapture vresult;
1512 LocaleGuard guard( LC_ALL,
"C" );
1513 int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.
basename().c_str() );
1526 std::vector<std::string> lines;
1527 str::split( vresult, std::back_inserter(lines),
"\n" );
1528 unsigned count[7] = { 0, 0, 0, 0, 0, 0, 0 };
1530 for (
unsigned i = 1; i < lines.size(); ++i )
1532 std::string & line( lines[i] );
1534 if ( line.find(
": OK" ) != std::string::npos )
1537 if ( line.find(
"Signature, key ID" ) == std::string::npos )
1540 else if ( line.find(
": NOKEY" ) != std::string::npos )
1542 else if ( line.find(
": BAD" ) != std::string::npos )
1544 else if ( line.find(
": UNKNOWN" ) != std::string::npos )
1546 else if ( line.find(
": NOTRUSTED" ) != std::string::npos )
1550 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( lineres, std::move(line) ) );
1571 detail_r.push_back( RpmDb::CheckPackageDetail::value_type( RpmDb::CHK_NOSIG, std::string(
" ")+
_(
"Package is not signed!") ) );
1572 if ( requireGPGSig_r )
1579 WAR << path_r <<
" (" << requireGPGSig_r <<
" -> " << ret <<
")" << endl;
1592 {
return doCheckPackageSig( path_r,
root(),
false, detail_r ); }
1598 {
return doCheckPackageSig( path_r,
root(),
true, detail_r ); }
1613 opts.push_back (
"-V");
1614 opts.push_back (
"--nodeps");
1615 opts.push_back (
"--noscripts");
1616 opts.push_back (
"--nomd5");
1617 opts.push_back (
"--");
1618 opts.push_back (packageName.c_str());
1639 if (line.length() > 12 &&
1640 (line[0] ==
'S' || line[0] ==
's' ||
1641 (line[0] ==
'.' && line[7] ==
'T')))
1644 std::string filename;
1646 filename.assign(line, 11, line.length() - 11);
1647 fileList.insert(filename);
1687 #if defined(WORKAROUNDRPMPWDBUG) 1688 args.push_back(
"#/");
1690 args.push_back(
"rpm");
1691 args.push_back(
"--root");
1692 args.push_back(
_root.asString().c_str());
1693 args.push_back(
"--dbpath");
1694 args.push_back(
_dbPath.asString().c_str());
1696 const char* argv[args.size() + opts.size() + 1];
1698 const char** p = argv;
1699 p =
copy (args.begin (), args.end (), p);
1700 p =
copy (opts.begin (), opts.end (), p);
1726 int inputfileFd = ::fileno( inputfile );
1732 FD_SET( inputfileFd, &rfds );
1739 int retval = select( inputfileFd+1, &rfds, NULL, NULL, &tv );
1743 ERR <<
"select error: " <<
strerror(errno) << endl;
1744 if ( errno != EINTR )
1750 static size_t linebuffer_size = 0;
1751 static char * linebuffer = 0;
1752 ssize_t nread =
getline( &linebuffer, &linebuffer_size, inputfile );
1755 if ( ::feof( inputfile ) )
1762 if ( linebuffer[nread-1] ==
'\n' )
1764 line += std::string( linebuffer, nread );
1767 if ( ! ::ferror( inputfile ) || ::feof( inputfile ) )
1770 clearerr( inputfile );
1819 void RpmDb::processConfigFiles(
const std::string& line,
const std::string& name,
const char* typemsg,
const char* difffailmsg,
const char* diffgenmsg)
1821 std::string msg = line.substr(9);
1824 std::string file1s, file2s;
1828 pos1 = msg.find (typemsg);
1831 if ( pos1 == std::string::npos )
1834 pos2 = pos1 + strlen (typemsg);
1836 if (pos2 >= msg.length() )
1839 file1 = msg.substr (0, pos1);
1840 file2 = msg.substr (pos2);
1842 file1s = file1.asString();
1843 file2s = file2.asString();
1847 file1 =
_root + file1;
1848 file2 =
_root + file2;
1852 int ret =
diffFiles (file1.asString(), file2.asString(), out, 25);
1858 ERR <<
"Could not create " << file.asString() << endl;
1862 std::ofstream notify(file.asString().c_str(), std::ios::out|std::ios::app);
1865 ERR <<
"Could not open " << file << endl;
1871 notify <<
str::form(
_(
"Changed configuration files for %s:"), name.c_str()) << endl;
1874 ERR <<
"diff failed" << endl;
1876 file1s.c_str(), file2s.c_str()) << endl;
1881 file1s.c_str(), file2s.c_str()) << endl;
1886 if (out.substr(0,4) ==
"--- ")
1888 out.replace(4, file1.asString().length(), file1s);
1891 if (pos != std::string::npos)
1893 out.replace(pos+5, file2.asString().length(), file2s);
1896 notify << out << endl;
1899 notify.open(
"/var/lib/update-messages/yast2-packagemanager.rpmdb.configfiles");
1904 WAR <<
"rpm created " << file2 <<
" but it is not different from " << file2 << endl;
1920 report->start(filename);
1935 report->finish( excpt_r );
1951 MIL <<
"RpmDb::installPackage(" << filename <<
"," << flags <<
")" << endl;
1960 ERR <<
"backup of " << filename.asString() <<
" failed" << endl;
1963 report->progress( 0 );
1969 opts.push_back(
"-i");
1971 opts.push_back(
"-U");
1973 opts.push_back(
"--percent");
1974 opts.push_back(
"--noglob");
1978 opts.push_back(
"--ignorearch");
1981 opts.push_back(
"--nodigest");
1983 opts.push_back(
"--nosignature");
1985 opts.push_back (
"--excludedocs");
1987 opts.push_back (
"--noscripts");
1989 opts.push_back (
"--force");
1991 opts.push_back (
"--nodeps");
1993 opts.push_back (
"--ignoresize");
1995 opts.push_back (
"--justdb");
1997 opts.push_back (
"--test");
1999 opts.push_back (
"--noposttrans");
2001 opts.push_back(
"--");
2004 std::string quotedFilename( rpmQuoteFilename( workaroundRpmPwdBug( filename ) ) );
2005 opts.push_back ( quotedFilename.c_str() );
2012 std::vector<std::string> configwarnings;
2014 unsigned linecnt = 0;
2020 sscanf( line.c_str() + 2,
"%d", &percent );
2021 report->progress( percent );
2027 else if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2030 rpmmsg += line+
'\n';
2033 configwarnings.push_back(line);
2036 rpmmsg +=
"[truncated]\n";
2041 for (std::vector<std::string>::iterator it = configwarnings.begin();
2042 it != configwarnings.end(); ++it)
2046 _(
"rpm saved %s as %s, but it was impossible to determine the difference"),
2048 _(
"rpm saved %s as %s.\nHere are the first 25 lines of difference:\n"));
2051 _(
"rpm created %s as %s, but it was impossible to determine the difference"),
2053 _(
"rpm created %s as %s.\nHere are the first 25 lines of difference:\n"));
2056 if ( rpm_status != 0 )
2059 str::form(
"%s install failed", Pathname::basename(filename).c_str()),
2061 std::ostringstream sstr;
2062 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2063 historylog.
comment(sstr.str());
2067 else if ( ! rpmmsg.empty() )
2070 str::form(
"%s installed ok", Pathname::basename(filename).c_str()),
2072 std::ostringstream sstr;
2073 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2074 historylog.
comment(sstr.str());
2078 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2092 +
"-" + package->edition().version()
2093 +
"-" + package->edition().release()
2094 +
"." + package->arch().asString(), flags );
2107 report->start( name_r );
2122 report->finish( excpt_r );
2139 MIL <<
"RpmDb::doRemovePackage(" << name_r <<
"," << flags <<
")" << endl;
2148 ERR <<
"backup of " << name_r <<
" failed" << endl;
2150 report->progress( 0 );
2154 report->progress( 100 );
2159 opts.push_back(
"-e");
2160 opts.push_back(
"--allmatches");
2163 opts.push_back(
"--noscripts");
2165 opts.push_back(
"--nodeps");
2167 opts.push_back(
"--justdb");
2169 opts.push_back (
"--test");
2172 WAR <<
"IGNORE OPTION: 'rpm -e' does not support '--force'" << endl;
2175 opts.push_back(
"--");
2176 opts.push_back(name_r.c_str());
2188 report->progress( 5 );
2189 unsigned linecnt = 0;
2194 else if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2196 rpmmsg += line+
'\n';
2199 rpmmsg +=
"[truncated]\n";
2200 report->progress( 50 );
2203 if ( rpm_status != 0 )
2206 str::form(
"%s remove failed", name_r.c_str()),
true );
2207 std::ostringstream sstr;
2208 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2209 historylog.
comment(sstr.str());
2213 else if ( ! rpmmsg.empty() )
2216 str::form(
"%s removed ok", name_r.c_str()),
true );
2218 std::ostringstream sstr;
2219 sstr <<
"Additional rpm output:" << endl << rpmmsg << endl;
2220 historylog.
comment(sstr.str());
2224 report->finishInfo(
str::form(
"%s:\n%s\n",
_(
"Additional rpm output"), rpmmsg.c_str() ));
2253 Pathname backupFilename;
2258 INT <<
"_backuppath empty" << endl;
2266 ERR <<
"Error while getting changed files for package " <<
2267 packageName << endl;
2271 if (fileList.size() <= 0)
2273 DBG <<
"package " << packageName <<
" not changed -> no backup" << endl;
2285 struct tm *currentLocalTime = localtime(¤tTime);
2287 int date = (currentLocalTime->tm_year + 1900) * 10000
2288 + (currentLocalTime->tm_mon + 1) * 100
2289 + currentLocalTime->tm_mday;
2295 +
str::form(
"%s-%d-%d.tar.gz",packageName.c_str(), date, num);
2298 while ( PathInfo(backupFilename).isExist() && num++ < 1000);
2300 PathInfo pi(filestobackupfile);
2301 if (pi.isExist() && !pi.isFile())
2303 ERR << filestobackupfile.asString() <<
" already exists and is no file" << endl;
2307 std::ofstream fp ( filestobackupfile.asString().c_str(), std::ios::out|std::ios::trunc );
2311 ERR <<
"could not open " << filestobackupfile.asString() << endl;
2315 for (FileList::const_iterator cit = fileList.begin();
2316 cit != fileList.end(); ++cit)
2318 std::string name = *cit;
2319 if ( name[0] ==
'/' )
2322 name = name.substr( 1 );
2324 DBG <<
"saving file "<< name << endl;
2329 const char*
const argv[] =
2334 _root.asString().c_str(),
2335 "--ignore-failed-read",
2337 backupFilename.asString().c_str(),
2339 filestobackupfile.asString().c_str(),
2355 int ret = tar.
close();
2359 ERR <<
"tar failed: " << tarmsg << endl;
2364 MIL <<
"tar backup ok" << endl;
2366 str::form(
_(
"created backup %s"), backupFilename.asString().c_str())
2385 #define OUTS(E,S) case RpmDb::E: return str << "["<< (unsigned)obj << "-"<< S << "]"; break 2397 OUTS(
CHK_ERROR,
_(
"File does not exist or signature can't be checked") );
2402 return str <<
"UnknowSignatureCheckError("+
str::numstring(obj)+
")";
2407 for (
const auto & el : obj )
2408 str << el.second << endl;
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Interface to the rpm program.
unsigned diffFiles(const std::string file1, const std::string file2, std::string &out, int maxlines)
bool hasDbV3ToV4() const
Whether dbV3ToV4 file exists.
CheckPackageResult checkPackageSignature(const Pathname &path_r, CheckPackageDetail &detail_r)
Check signature of rpm file on disk (strict check returning CHK_NOSIG if file is unsigned).
std::string gpgPubkeyRelease() const
Gpg-pubkey release as computed by rpm (hexencoded created)
bool hasPackage(const std::string &name_r) const
Return true if package is installed.
static unsigned blockAccess()
Blocks further access to rpmdb.
std::string basename() const
Return the last component of this path.
static std::ostream & dumpState(std::ostream &str)
Dump debug info.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
bool hasProvides(const std::string &tag_r) const
Return true if at least one package provides a certain tag.
virtual void trustedKeyAdded(const PublicKey &key)
bool kill()
Kill the program.
static ZConfig & instance()
Singleton ctor.
Pathname _root
Root directory for all operations.
bool findByProvides(const std::string &tag_r)
Reset to iterate all packages that provide a certain tag.
std::string release() const
Release.
void getData(const std::string &name_r, RpmHeader::constPtr &result_r) const
Get an installed packages data from rpmdb.
bool hasSubkeys() const
!<
Class representing one GPG Public Keys data.
const std::string & asString() const
String representation.
const std::string & execError() const
Some detail telling why the execution failed, if it failed.
Collect info about what kind of rpmdb seems to be present by looking at paths and filenames...
void exportTrustedKeysInZyppKeyRing()
insert all rpm trusted keys into zypp trusted keyring
static void dbAccess()
Access the database at the current default location.
void rebuildDatabase()
Rebuild the rpm database (rpm –rebuilddb).
void installPackage(const Pathname &filename, RpmInstFlags flags=RPMINST_NONE)
install rpm package
std::string asString() const
void internal_initDatabase(const Pathname &root_r, const Pathname &dbPath_r, DbStateInfoBits &info_r)
Internal helper for initDatabase.
String related utilities and Regular expression matching.
bool findByRequiredBy(const std::string &tag_r)
Reset to iterate all packages that require a certain tag.
void modifyDatabase()
Called before the database is modified by installPackage/removePackage.
std::string gpgPubkeyVersion() const
Gpg-pubkey version as computed by rpm (trailing 8 byte id)
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Edition represents [epoch:]version[-release]
bool running()
Return whether program is running.
bool illegalArgs() const
Whether constructor arguments were illegal.
bool hasConflicts(const std::string &tag_r) const
Return true if at least one package conflicts with a certain tag.
Provide a new empty temporary file and delete it when no longer needed.
void importZyppKeyRingTrustedKeys()
iterates through zypp keyring and import all non existant keys into rpm keyring
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
bool backupPackage(const std::string &packageName)
create tar.gz of all changed files in a Package
CheckPackageResult checkPackage(const Pathname &path_r, CheckPackageDetail &detail_r)
Check signature of rpm file on disk (legacy version returning CHK_OK if file is unsigned, like 'rpm -K')
std::list< FileInfo > fileList(const std::string &name_r, const Edition &edition_r) const
return complete file list for installed package name_r (in FileInfo.filename) if edition_r != Edition...
#define FILEFORBACKUPFILES
Subclass to retrieve database content.
Temporarily connect a ReceiveReport then restore the previous one.
std::string gpgPubkeyVersion() const
bool hasDbV4() const
Whether dbV4 file exists.
void importPubkey(const PublicKey &pubkey_r)
Import ascii armored public key in file pubkey_r.
void systemKill()
Forcably kill the system process.
bool dbsi_has(const DbStateInfoBits &val_r, const unsigned &bits_r) const
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
void moveToHistory(TContainer &&msgc_r)
addHistory from string container types (oldest first) moving
void syncTrustedKeys(SyncTrustedKeyBits mode_r=SYNC_BOTH)
Sync trusted keys stored in rpm database and zypp trusted keyring.
#define FAILIFNOTINITIALIZED
Pathname path() const
File containig the ASCII armored key.
std::string getline(std::istream &str)
Read one line from stream.
virtual std::ostream & dumpOn(std::ostream &str) const
Dump debug info.
Store and operate on date (time_t).
Pathname _backuppath
/var/adm/backup
const PathInfo & dbV3ToV4() const
rpmV3 database backup created on conversion to rpmV4 (_dbDir/packages.rpm3)
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t")
Split line_r into words.
const std::string & asString() const
Return current Pathname as String.
int exit_code
The exit code of the rpm process, or -1 if not yet known.
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
int unlink(const Pathname &path)
Like 'unlink'.
std::string asString() const
shared_ptr< RpmException > dbError() const
Return any database error.
SyncTrustedKeyBits
Sync mode for syncTrustedKeys.
bool systemReadLine(std::string &line)
Read a line from the general rpm query.
int rename(const Pathname &oldpath, const Pathname &newpath)
Like 'rename'.
int systemStatus()
Return the exit status of the general rpm process, closing the connection if not already done...
bool findByName(const std::string &name_r)
Reset to iterate all packages with a certain name.
const char * c_str() const
String representation.
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
Detailed rpm signature check log messages A single multiline message if CHK_OK.
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
Types and functions for filesystem operations.
static unsigned dbRelease(bool force_r=false)
If there are no outstanding references to the database (e.g.
static shared_ptr< KeyRingSignalReceiver > sKeyRingReceiver
bool hasDbV3() const
Whether dbV3 file exists.
std::string version() const
Version.
ExternalProgram * process
The connection to the rpm process.
Writing the zypp history fileReference counted signleton for writhing the zypp history file...
void doRebuildDatabase(callback::SendReport< RebuildDBReport > &report)
std::set< Edition > pubkeyEditions() const
Return the edition of all installed public keys.
bool findByFile(const std::string &file_r)
Reset to iterate all packages that own a certain file.
std::string receiveLine()
Read one line from the input stream.
const Pathname & root() const
void closeDatabase()
Block further access to the rpm database and go back to uninitialized state.
Stderr_Disposition
Define symbols for different policies on the handling of stderr.
DbStateInfoBits _dbStateInfo
Internal state info.
Just inherits Exception to separate media exceptions.
FILE * inputFile() const
Return the input stream.
std::string numstring(char n, int w=0)
export rpm trusted keys into zypp trusted keyring
virtual void trustedKeyRemoved(const PublicKey &key)
bool findPackage(const std::string &name_r)
Find package by name.
static void unblockAccess()
Allow access to rpmdb e.g.
std::ostream & copy(std::istream &from_r, std::ostream &to_r)
Copy istream to ostream.
void doInstallPackage(const Pathname &filename, RpmInstFlags flags, callback::SendReport< RpmInstallReport > &report)
int close()
Wait for the progamm to complete.
void removePubkey(const PublicKey &pubkey_r)
Remove a public key from the rpm database.
void processConfigFiles(const std::string &line, const std::string &name, const char *typemsg, const char *difffailmsg, const char *diffgenmsg)
handle rpm messages like "/etc/testrc saved as /etc/testrc.rpmorig"
int copy(const Pathname &file, const Pathname &dest)
Like 'cp file dest'.
const PathInfo & dbV4() const
rpmV4 database (_dbDir/Packages)
bool _packagebackups
create package backups?
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
bool hasRequiredBy(const std::string &tag_r) const
Return true if at least one package requires a certain tag.
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
void doRemovePackage(const std::string &name_r, RpmInstFlags flags, callback::SendReport< RpmRemoveReport > &report)
Base class for Exception.
std::string form(const std::string &format_r) const
Return string representation according to format as localtime.
void setBackupPath(const Pathname &path)
set path where package backups are stored
static Date now()
Return the current time.
void convertV3toV4(const Pathname &v3db_r, const librpmDb::constPtr &v4db_r)
void initDatabase(Pathname root_r=Pathname(), Pathname dbPath_r=Pathname(), bool doRebuild_r=false)
Prepare access to the rpm database.
std::string error_message
Error message from running rpm as external program.
void removePackage(const std::string &name_r, RpmInstFlags flags=RPMINST_NONE)
remove rpm package
static bool globalInit()
Initialize lib librpm (read configfiles etc.).
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
bool hasFile(const std::string &file_r, const std::string &name_r="") const
Return true if at least one package owns a certain file (name_r empty) Return true if package name_r ...
void comment(const std::string &comment, bool timestamp=false)
Log a comment (even multiline).
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
Date timestamp() const
timestamp of the rpm database (last modification)
const Pathname & dbPath() const
bool findByConflicts(const std::string &tag_r)
Reset to iterate all packages that conflict with a certain tag.
Wrapper class for ::stat/::lstat.
const PathInfo & dbDir() const
database directory (unset on illegal constructor arguments)
void setBlocking(bool mode)
Set the blocking mode of the input stream.
CheckPackageResult
checkPackage result
std::list< PublicKey > pubkeys() const
Return the long ids of all installed public keys.
void dbsi_set(DbStateInfoBits &val_r, const unsigned &bits_r) const
std::string stringPath(const Pathname &root_r, const Pathname &sub_r)
static void removeV3(const Pathname &dbdir_r, bool v3backup_r)
Remove the rpm3 database in dbdir_r.
bool queryChangedFiles(FileList &fileList, const std::string &packageName)
determine which files of an installed package have been modified.
void dbsi_clr(DbStateInfoBits &val_r, const unsigned &bits_r) const
static void removeV4(const Pathname &dbdir_r, bool v3backup_r)
Remove the rpm4 database in dbdir_r and optionally any backup created on conversion.
std::string strerror(int errno_r)
Return string describing the error_r code.
std::ostream & operator<<(std::ostream &str, const Glob &obj)
bool usableArgs() const
Whether constructor arguments were llegal and dbDir either is a directory or may be created (path doe...
const PathInfo & dbV3() const
rpmV3 database (_dbDir/packages.rpm)
intrusive_ptr< const librpmDb > constPtr
friend std::ostream & operator<<(std::ostream &str, const DbStateInfoBits &obj)
Easy-to use interface to the ZYPP dependency resolver.
std::string gpgPubkeyRelease() const
void run_rpm(const RpmArgVec &options, ExternalProgram::Stderr_Disposition stderr_disp=ExternalProgram::Stderr_To_Stdout)
Run rpm with the specified arguments and handle stderr.
KeyRingSignalReceiver(RpmDb &rpmdb)
void restat()
Restat all paths.
TraitsType::constPtrType constPtr
#define MAXRPMMESSAGELINES
std::string whoOwnsFile(const std::string &file_r) const
Return name of package owning file or empty string if no installed package owns file.
static const Edition noedition
Value representing noedition ("") This is in fact a valid Edition.
Pathname _dbPath
Directory that contains the rpmdb.
std::set< std::string > FileList
std::vector< const char * > RpmArgVec