*
*/
#include "librpm.h"
+#ifdef _RPM_4_4
+#include <rpm/ugid.h>
+#else
+////////////////////////////////////////////////////////////////////
+// unameToUid and gnameToGid are shamelessly stolen from rpm-4.4.
+// (rpmio/ugid.c) Those functions were dropped in RPM_4_7
+extern "C"
+{
+#include <pwd.h>
+#include <grp.h>
+}
+/* unameToUid(), uidTouname() and the group variants are really poorly
+ implemented. They really ought to use hash tables. I just made the
+ guess that most files would be owned by root or the same person/group
+ who owned the last file. Those two values are cached, everything else
+ is looked up via getpw() and getgr() functions. If this performs
+ too poorly I'll have to implement it properly :-( */
+
+int unameToUid(const char * thisUname, uid_t * uid)
+{
+/*@only@*/ static char * lastUname = NULL;
+ static size_t lastUnameLen = 0;
+ static size_t lastUnameAlloced;
+ static uid_t lastUid;
+ struct passwd * pwent;
+ size_t thisUnameLen;
+
+ if (!thisUname) {
+ lastUnameLen = 0;
+ return -1;
+ } else if (strcmp(thisUname, "root") == 0) {
+/*@-boundswrite@*/
+ *uid = 0;
+/*@=boundswrite@*/
+ return 0;
+ }
+
+ thisUnameLen = strlen(thisUname);
+ if (lastUname == NULL || thisUnameLen != lastUnameLen ||
+ strcmp(thisUname, lastUname) != 0)
+ {
+ if (lastUnameAlloced < thisUnameLen + 1) {
+ lastUnameAlloced = thisUnameLen + 10;
+ lastUname = (char *)realloc(lastUname, lastUnameAlloced); /* XXX memory leak */
+ }
+/*@-boundswrite@*/
+ strcpy(lastUname, thisUname);
+/*@=boundswrite@*/
+
+ pwent = getpwnam(thisUname);
+ if (pwent == NULL) {
+ /*@-internalglobs@*/ /* FIX: shrug */
+ endpwent();
+ /*@=internalglobs@*/
+ pwent = getpwnam(thisUname);
+ if (pwent == NULL) return -1;
+ }
+
+ lastUid = pwent->pw_uid;
+ }
+
+/*@-boundswrite@*/
+ *uid = lastUid;
+/*@=boundswrite@*/
+
+ return 0;
+}
+
+int gnameToGid(const char * thisGname, gid_t * gid)
+{
+/*@only@*/ static char * lastGname = NULL;
+ static size_t lastGnameLen = 0;
+ static size_t lastGnameAlloced;
+ static gid_t lastGid;
+ size_t thisGnameLen;
+ struct group * grent;
+
+ if (thisGname == NULL) {
+ lastGnameLen = 0;
+ return -1;
+ } else if (strcmp(thisGname, "root") == 0) {
+/*@-boundswrite@*/
+ *gid = 0;
+/*@=boundswrite@*/
+ return 0;
+ }
+
+ thisGnameLen = strlen(thisGname);
+ if (lastGname == NULL || thisGnameLen != lastGnameLen ||
+ strcmp(thisGname, lastGname) != 0)
+ {
+ if (lastGnameAlloced < thisGnameLen + 1) {
+ lastGnameAlloced = thisGnameLen + 10;
+ lastGname = (char *)realloc(lastGname, lastGnameAlloced); /* XXX memory leak */
+ }
+/*@-boundswrite@*/
+ strcpy(lastGname, thisGname);
+/*@=boundswrite@*/
+
+ grent = getgrnam(thisGname);
+ if (grent == NULL) {
+ /*@-internalglobs@*/ /* FIX: shrug */
+ endgrent();
+ /*@=internalglobs@*/
+ grent = getgrnam(thisGname);
+ if (grent == NULL) {
+ /* XXX The filesystem package needs group/lock w/o getgrnam. */
+ if (strcmp(thisGname, "lock") == 0) {
+/*@-boundswrite@*/
+ *gid = lastGid = 54;
+/*@=boundswrite@*/
+ return 0;
+ } else
+ if (strcmp(thisGname, "mail") == 0) {
+/*@-boundswrite@*/
+ *gid = lastGid = 12;
+/*@=boundswrite@*/
+ return 0;
+ } else
+ return -1;
+ }
+ }
+ lastGid = grent->gr_gid;
+ }
+
+/*@-boundswrite@*/
+ *gid = lastGid;
+/*@=boundswrite@*/
+
+ return 0;
+}
+////////////////////////////////////////////////////////////////////
+#endif
#include <iostream>
#include <map>
#include <set>
+#include <vector>
+#include "zypp/base/Easy.h"
#include "zypp/base/Logger.h"
-#include "zypp/PathInfo.h"
+#include "zypp/base/Exception.h"
+#include "zypp/target/rpm/librpmDb.h"
#include "zypp/target/rpm/RpmHeader.h"
-#include "zypp/CapFactory.h"
-#include "zypp/Rel.h"
-#warning FIXME this include
-#if 0
-#include <y2pm/PkgDu.h>
-#endif
+#include "zypp/Package.h"
+#include "zypp/PathInfo.h"
-using namespace std;
-
-namespace zypp {
- namespace target {
- namespace rpm {
-
- ///////////////////////////////////////////////////////////////////
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::RpmHeader
- // METHOD TYPE : Constructor
- //
- // DESCRIPTION :
- //
- RpmHeader::RpmHeader( Header h_r )
- : BinHeader( h_r )
- {
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::RpmHeader
- // METHOD TYPE : Constructor
- //
- RpmHeader::RpmHeader( BinHeader::Ptr & rhs )
- : BinHeader( rhs )
- {
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::~RpmHeader
- // METHOD TYPE : Destructor
- //
- // DESCRIPTION :
- //
- RpmHeader::~RpmHeader()
- {
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::readPackage
- // METHOD TYPE : constRpmHeaderPtr
- //
- RpmHeader::constPtr RpmHeader::readPackage( const Pathname & path_r,
- VERIFICATION verification_r )
+using std::endl;
+
+namespace zypp
+{
+namespace target
+{
+namespace rpm
+{
+
+///////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::RpmHeader
+// METHOD TYPE : Constructor
+//
+// DESCRIPTION :
+//
+RpmHeader::RpmHeader( Header h_r )
+ : BinHeader( h_r )
+{}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::RpmHeader
+// METHOD TYPE : Constructor
+//
+RpmHeader::RpmHeader( BinHeader::Ptr & rhs )
+ : BinHeader( rhs )
+{}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::~RpmHeader
+// METHOD TYPE : Destructor
+//
+// DESCRIPTION :
+//
+RpmHeader::~RpmHeader()
+{}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::readPackage
+// METHOD TYPE : constRpmHeaderPtr
+//
+RpmHeader::constPtr RpmHeader::readPackage( const Pathname & path_r,
+ VERIFICATION verification_r )
+{
+ PathInfo file( path_r );
+ if ( ! file.isFile() )
+ {
+ ERR << "Not a file: " << file << endl;
+ return (RpmHeader*)0;
+ }
+
+ FD_t fd = ::Fopen( file.asString().c_str(), "r.ufdio" );
+ if ( fd == 0 || ::Ferror(fd) )
+ {
+ ERR << "Can't open file for reading: " << file << " (" << ::Fstrerror(fd) << ")" << endl;
+ if ( fd )
+ ::Fclose( fd );
+ return (RpmHeader*)0;
+ }
+
+ librpmDb::globalInit();
+ rpmts ts = ::rpmtsCreate();
+ unsigned vsflag = RPMVSF_DEFAULT;
+ if ( verification_r & NODIGEST )
+ vsflag |= _RPMVSF_NODIGESTS;
+ if ( verification_r & NOSIGNATURE )
+ vsflag |= _RPMVSF_NOSIGNATURES;
+ ::rpmtsSetVSFlags( ts, rpmVSFlags(vsflag) );
+
+ Header nh = 0;
+ int res = ::rpmReadPackageFile( ts, fd, path_r.asString().c_str(), &nh );
+
+ ts = rpmtsFree(ts);
+
+ ::Fclose( fd );
+
+ if ( ! nh )
+ {
+ WAR << "Error reading header from " << path_r << " error(" << res << ")" << endl;
+ return (RpmHeader*)0;
+ }
+
+ RpmHeader::constPtr h( new RpmHeader( nh ) );
+ headerFree( nh ); // clear the reference set in ReadPackageFile
+
+ MIL << h << " from " << path_r << endl;
+ return h;
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::dumpOn
+// METHOD TYPE : std::ostream &
+//
+// DESCRIPTION :
+//
+std::ostream & RpmHeader::dumpOn( std::ostream & str ) const
+{
+ return BinHeader::dumpOn( str ) << '{' << tag_name() << "-"
+ << (tag_epoch()==0?"":(tag_epoch()+":"))
+ << tag_version()
+ << (tag_release().empty()?"":(std::string("-")+tag_release()))
+ << ( isSrc() ? ".src}" : "}");
+}
+
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::isSrc
+// METHOD TYPE : bool
+//
+bool RpmHeader::isSrc() const
+{
+ return has_tag( RPMTAG_SOURCEPACKAGE );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_name
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_name() const
+{
+ return string_val( RPMTAG_NAME );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_epoch
+// METHOD TYPE : Edition::epoch_t
+//
+// DESCRIPTION :
+//
+Edition::epoch_t RpmHeader::tag_epoch() const
+{
+ return int_val ( RPMTAG_EPOCH );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_version
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_version() const
+{
+ return string_val ( RPMTAG_VERSION );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_release
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_release() const
+{
+ return string_val( RPMTAG_RELEASE );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_edition
+// METHOD TYPE : Edition
+//
+// DESCRIPTION :
+//
+Edition RpmHeader::tag_edition () const
+{
+ return Edition( tag_version(), tag_release(), tag_epoch() );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_arch
+// METHOD TYPE : Arch
+//
+// DESCRIPTION :
+//
+Arch RpmHeader::tag_arch() const
+{
+ return Arch( string_val( RPMTAG_ARCH ) );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_installtime
+// METHOD TYPE : Date
+//
+// DESCRIPTION :
+//
+Date RpmHeader::tag_installtime() const
+{
+ return int_val( RPMTAG_INSTALLTIME );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_buildtime
+// METHOD TYPE : Date
+//
+// DESCRIPTION :
+//
+Date RpmHeader::tag_buildtime() const
+{
+ return int_val( RPMTAG_BUILDTIME );
+}
+#warning CHECK IF FILE REQUIRES HANDLING IS OBSOLETE
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::PkgRelList_val
+// METHOD TYPE : CapabilitySet
+//
+// DESCRIPTION :
+//
+CapabilitySet RpmHeader::PkgRelList_val( tag tag_r, bool pre, std::set<std::string> * freq_r ) const
+ {
+ CapabilitySet ret;
+
+ rpmTag kindFlags = rpmTag(0);
+ rpmTag kindVersion = rpmTag(0);
+
+ switch ( tag_r )
+ {
+ case RPMTAG_REQUIRENAME:
+ kindFlags = RPMTAG_REQUIREFLAGS;
+ kindVersion = RPMTAG_REQUIREVERSION;
+ break;
+ case RPMTAG_PROVIDENAME:
+ kindFlags = RPMTAG_PROVIDEFLAGS;
+ kindVersion = RPMTAG_PROVIDEVERSION;
+ break;
+ case RPMTAG_OBSOLETENAME:
+ kindFlags = RPMTAG_OBSOLETEFLAGS;
+ kindVersion = RPMTAG_OBSOLETEVERSION;
+ break;
+ case RPMTAG_CONFLICTNAME:
+ kindFlags = RPMTAG_CONFLICTFLAGS;
+ kindVersion = RPMTAG_CONFLICTVERSION;
+ break;
+ case RPMTAG_ENHANCESNAME:
+ kindFlags = RPMTAG_ENHANCESFLAGS;
+ kindVersion = RPMTAG_ENHANCESVERSION;
+ break;
+ case RPMTAG_SUGGESTSNAME:
+ kindFlags = RPMTAG_SUGGESTSFLAGS;
+ kindVersion = RPMTAG_SUGGESTSVERSION;
+ break;
+ default:
+ INT << "Illegal RPMTAG_dependencyNAME " << tag_r << endl;
+ return ret;
+ break;
+ }
+
+ stringList names;
+ unsigned count = string_list( tag_r, names );
+ if ( !count )
+ return ret;
+
+ intList flags;
+ int_list( kindFlags, flags );
+
+ stringList versions;
+ string_list( kindVersion, versions );
+
+ for ( unsigned i = 0; i < count; ++i )
+ {
+
+ std::string n( names[i] );
+
+ Rel op = Rel::ANY;
+ int32_t f = flags[i];
+ std::string v = versions[i];
+
+ if ( n[0] == '/' )
{
- PathInfo file( path_r );
- if ( ! file.isFile() ) {
- ERR << "Not a file: " << file << endl;
- return (RpmHeader*)0;
- }
-
- FD_t fd = ::Fopen( file.asString().c_str(), "r.ufdio" );
- if ( fd == 0 || ::Ferror(fd) ) {
- ERR << "Can't open file for reading: " << file << " (" << ::Fstrerror(fd) << ")" << endl;
- if ( fd )
- ::Fclose( fd );
- return (RpmHeader*)0;
+ if ( freq_r )
+ {
+ freq_r->insert( n );
}
-
- rpmts ts = ::rpmtsCreate();
- unsigned vsflag = RPMVSF_DEFAULT;
- if ( verification_r & NODIGEST )
- vsflag |= _RPMVSF_NODIGESTS;
- if ( verification_r & NOSIGNATURE )
- vsflag |= _RPMVSF_NOSIGNATURES;
- ::rpmtsSetVSFlags( ts, rpmVSFlags(vsflag) );
-
- Header nh = 0;
- int res = ::rpmReadPackageFile( ts, fd, path_r.asString().c_str(), &nh );
-
- ts = ::rpmtsFree(ts);
-
- ::Fclose( fd );
-
- if ( ! nh ) {
- WAR << "Error reading header from " << path_r << " error(" << res << ")" << endl;
- return (RpmHeader*)0;
- }
-
- RpmHeader::constPtr h( new RpmHeader( nh ) );
- headerFree( nh ); // clear the reference set in ReadPackageFile
-
- MIL << h << " from " << path_r << endl;
- return h;
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::dumpOn
- // METHOD TYPE : ostream &
- //
- // DESCRIPTION :
- //
- ostream & RpmHeader::dumpOn( ostream & str ) const
- {
- return BinHeader::dumpOn( str ) << '{' << tag_name() << "-" << tag_edition() << ( isSrc() ? ".src}" : "}");
}
-
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::isSrc
- // METHOD TYPE : bool
- //
- bool RpmHeader::isSrc() const
+ else
{
- return has_tag( RPMTAG_SOURCEPACKAGE );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_name
- // METHOD TYPE : string
- //
- // DESCRIPTION :
- //
- string RpmHeader::tag_name() const
- {
- return string( string_val( RPMTAG_NAME ) );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_edition
- // METHOD TYPE : Edition
- //
- // DESCRIPTION :
- //
- Edition RpmHeader::tag_edition() const
- {
- return Edition( string_val( RPMTAG_VERSION ),
- string_val( RPMTAG_RELEASE ),
- string_val ( RPMTAG_EPOCH ));
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_arch
- // METHOD TYPE : Arch
- //
- // DESCRIPTION :
- //
- Arch RpmHeader::tag_arch() const
- {
- return Arch( string_val( RPMTAG_ARCH ) );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_installtime
- // METHOD TYPE : Date
- //
- // DESCRIPTION :
- //
- Date RpmHeader::tag_installtime() const
- {
- return int_val( RPMTAG_INSTALLTIME );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_buildtime
- // METHOD TYPE : Date
- //
- // DESCRIPTION :
- //
- Date RpmHeader::tag_buildtime() const
- {
- return int_val( RPMTAG_BUILDTIME );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::PkgRelList_val
- // METHOD TYPE : unsigned
- //
- // DESCRIPTION :
- //
- CapSet RpmHeader::PkgRelList_val( tag tag_r, bool pre, set<string> * freq_r ) const
- {
- CapSet ret;
-
- int_32 kindFlags = 0;
- int_32 kindVersion = 0;
-
- switch ( tag_r ) {
- case RPMTAG_REQUIRENAME:
- kindFlags = RPMTAG_REQUIREFLAGS;
- kindVersion = RPMTAG_REQUIREVERSION;
- break;
- case RPMTAG_PROVIDENAME:
- kindFlags = RPMTAG_PROVIDEFLAGS;
- kindVersion = RPMTAG_PROVIDEVERSION;
- break;
- case RPMTAG_OBSOLETENAME:
- kindFlags = RPMTAG_OBSOLETEFLAGS;
- kindVersion = RPMTAG_OBSOLETEVERSION;
- break;
- case RPMTAG_CONFLICTNAME:
- kindFlags = RPMTAG_CONFLICTFLAGS;
- kindVersion = RPMTAG_CONFLICTVERSION;
- break;
- default:
- INT << "Illegal RPMTAG_dependencyNAME " << tag_r << endl;
- return ret;
- break;
- }
-
- stringList names;
- unsigned count = string_list( tag_r, names );
- if ( !count )
- return ret;
-
- intList flags;
- int_list( kindFlags, flags );
-
- stringList versions;
- string_list( kindVersion, versions );
-
- for ( unsigned i = 0; i < count; ++i ) {
-
- string n( names[i] );
-
- Rel op = Rel::ANY;
- int_32 f = flags[i];
- string v = versions[i];
-
- if ( n[0] == '/' ) {
- if ( freq_r ) {
- freq_r->insert( n );
- }
- } else {
- if ( v.size() ) {
- switch ( f & RPMSENSE_SENSEMASK ) {
- case RPMSENSE_LESS:
- op = Rel::LT;
- break;
- case RPMSENSE_LESS|RPMSENSE_EQUAL:
- op = Rel::LE;
- break;
- case RPMSENSE_GREATER:
- op = Rel::GT;
- break;
- case RPMSENSE_GREATER|RPMSENSE_EQUAL:
- op = Rel::GE;
- break;
- case RPMSENSE_EQUAL:
- op = Rel::EQ;
- break;
- }
- }
+ if ( v.size() )
+ {
+ switch ( f & RPMSENSE_SENSEMASK )
+ {
+ case RPMSENSE_LESS:
+ op = Rel::LT;
+ break;
+ case RPMSENSE_LESS|RPMSENSE_EQUAL:
+ op = Rel::LE;
+ break;
+ case RPMSENSE_GREATER:
+ op = Rel::GT;
+ break;
+ case RPMSENSE_GREATER|RPMSENSE_EQUAL:
+ op = Rel::GE;
+ break;
+ case RPMSENSE_EQUAL:
+ op = Rel::EQ;
+ break;
}
- if ((pre && (f & RPMSENSE_PREREQ))
- || ((! pre) && !(f & RPMSENSE_PREREQ)))
- {
- CapFactory _f;
- Capability cap = _f.parse(
- ResTraits<Package>::kind,
- n,
- op,
- Edition(v)
- );
- ret.insert(cap);
- }
}
-
- return ret;
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_provides
- // METHOD TYPE : CapSet
- //
- // DESCRIPTION :
- //
- CapSet RpmHeader::tag_provides( set<string> * freq_r ) const
- {
- return PkgRelList_val( RPMTAG_PROVIDENAME, false, freq_r );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_requires
- // METHOD TYPE : CapSet
- //
- // DESCRIPTION :
- //
- CapSet RpmHeader::tag_requires( set<string> * freq_r ) const
- {
- return PkgRelList_val( RPMTAG_REQUIRENAME, false, freq_r );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_requires
- // METHOD TYPE : CapSet
- //
- // DESCRIPTION :
- //
- CapSet RpmHeader::tag_prerequires( set<string> * freq_r ) const
- {
- return PkgRelList_val( RPMTAG_REQUIRENAME, true, freq_r );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_conflicts
- // METHOD TYPE : CapSet
- //
- // DESCRIPTION :
- //
- CapSet RpmHeader::tag_conflicts( set<string> * freq_r ) const
- {
- return PkgRelList_val( RPMTAG_CONFLICTNAME, false, freq_r );
}
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_obsoletes
- // METHOD TYPE : CapSet
- //
- // DESCRIPTION :
- //
- CapSet RpmHeader::tag_obsoletes( set<string> * freq_r ) const
+ if ((pre && (f & RPMSENSE_PREREQ))
+ || ((! pre) && !(f & RPMSENSE_PREREQ)))
{
- return PkgRelList_val( RPMTAG_OBSOLETENAME, false, freq_r );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_size
- // METHOD TYPE : ByteCount
- //
- // DESCRIPTION :
- //
- ByteCount RpmHeader::tag_size() const
- {
- return int_val( RPMTAG_SIZE );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_archivesize
- // METHOD TYPE : ByteCount
- //
- // DESCRIPTION :
- //
- ByteCount RpmHeader::tag_archivesize() const
- {
- return int_val( RPMTAG_ARCHIVESIZE );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_summary
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_summary() const
- {
- return string_val( RPMTAG_SUMMARY );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_description
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_description() const
- {
- return string_val( RPMTAG_DESCRIPTION );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_group
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_group() const
- {
- return string_val( RPMTAG_GROUP );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_vendor
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_vendor() const
- {
- return string_val( RPMTAG_VENDOR );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_distribution
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_distribution() const
- {
- return string_val( RPMTAG_DISTRIBUTION );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_license
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_license() const
- {
- return string_val( RPMTAG_LICENSE );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_buildhost
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_buildhost() const
- {
- return string_val( RPMTAG_BUILDHOST );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_packager
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_packager() const
- {
- return string_val( RPMTAG_PACKAGER );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_url
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_url() const
- {
- return string_val( RPMTAG_URL );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_os
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_os() const
- {
- return string_val( RPMTAG_OS );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_prein
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_prein() const
- {
- return string_val( RPMTAG_PREIN );
+ try
+ {
+ ret.insert( Capability( n, op, Edition(v) ) );
+ }
+ catch (Exception & excpt_r)
+ {
+ ZYPP_CAUGHT(excpt_r);
+ WAR << "Invalid capability: " << n << " " << op << " "
+ << v << endl;
+ }
}
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_postin
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_postin() const
+ }
+
+ return ret;
+ }
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_provides
+// METHOD TYPE : CapabilitySet
+//
+// DESCRIPTION :
+//
+CapabilitySet RpmHeader::tag_provides( std::set<std::string> * freq_r ) const
+ {
+ return PkgRelList_val( RPMTAG_PROVIDENAME, false, freq_r );
+ }
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_requires
+// METHOD TYPE : CapabilitySet
+//
+// DESCRIPTION :
+//
+CapabilitySet RpmHeader::tag_requires( std::set<std::string> * freq_r ) const
+ {
+ return PkgRelList_val( RPMTAG_REQUIRENAME, false, freq_r );
+ }
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_requires
+// METHOD TYPE : CapabilitySet
+//
+// DESCRIPTION :
+//
+CapabilitySet RpmHeader::tag_prerequires( std::set<std::string> * freq_r ) const
+ {
+ return PkgRelList_val( RPMTAG_REQUIRENAME, true, freq_r );
+ }
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_conflicts
+// METHOD TYPE : CapabilitySet
+//
+// DESCRIPTION :
+//
+CapabilitySet RpmHeader::tag_conflicts( std::set<std::string> * freq_r ) const
+ {
+ return PkgRelList_val( RPMTAG_CONFLICTNAME, false, freq_r );
+ }
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_obsoletes
+// METHOD TYPE : CapabilitySet
+//
+// DESCRIPTION :
+//
+CapabilitySet RpmHeader::tag_obsoletes( std::set<std::string> * freq_r ) const
+ {
+ return PkgRelList_val( RPMTAG_OBSOLETENAME, false, freq_r );
+ }
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_enhances
+// METHOD TYPE : CapabilitySet
+//
+// DESCRIPTION :
+//
+CapabilitySet RpmHeader::tag_enhances( std::set<std::string> * freq_r ) const
+ {
+ return PkgRelList_val( RPMTAG_ENHANCESNAME, false, freq_r );
+ }
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_suggests
+// METHOD TYPE : CapabilitySet
+//
+// DESCRIPTION :
+//
+CapabilitySet RpmHeader::tag_suggests( std::set<std::string> * freq_r ) const
+ {
+ return PkgRelList_val( RPMTAG_SUGGESTSNAME, false, freq_r );
+ }
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_size
+// METHOD TYPE : ByteCount
+//
+// DESCRIPTION :
+//
+ByteCount RpmHeader::tag_size() const
+{
+ return int_val( RPMTAG_SIZE );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_archivesize
+// METHOD TYPE : ByteCount
+//
+// DESCRIPTION :
+//
+ByteCount RpmHeader::tag_archivesize() const
+{
+ return int_val( RPMTAG_ARCHIVESIZE );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_summary
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_summary() const
+{
+ return string_val( RPMTAG_SUMMARY );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_description
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_description() const
+{
+ return string_val( RPMTAG_DESCRIPTION );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_group
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_group() const
+{
+ return string_val( RPMTAG_GROUP );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_vendor
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_vendor() const
+{
+ return string_val( RPMTAG_VENDOR );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_distribution
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_distribution() const
+{
+ return string_val( RPMTAG_DISTRIBUTION );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_license
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_license() const
+{
+ return string_val( RPMTAG_LICENSE );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_buildhost
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_buildhost() const
+{
+ return string_val( RPMTAG_BUILDHOST );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_packager
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_packager() const
+{
+ return string_val( RPMTAG_PACKAGER );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_url
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_url() const
+{
+ return string_val( RPMTAG_URL );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_os
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_os() const
+{
+ return string_val( RPMTAG_OS );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_prein
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_prein() const
+{
+ return string_val( RPMTAG_PREIN );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_postin
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_postin() const
+{
+ return string_val( RPMTAG_POSTIN );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_preun
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_preun() const
+{
+ return string_val( RPMTAG_PREUN );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_postun
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_postun() const
+{
+ return string_val( RPMTAG_POSTUN );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_sourcerpm
+// METHOD TYPE : std::string
+//
+// DESCRIPTION :
+//
+std::string RpmHeader::tag_sourcerpm() const
+{
+ return string_val( RPMTAG_SOURCERPM );
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_filenames
+// METHOD TYPE : std::list<std::string>
+//
+// DESCRIPTION :
+//
+std::list<std::string> RpmHeader::tag_filenames() const
+{
+ std::list<std::string> ret;
+
+ stringList basenames;
+ if ( string_list( RPMTAG_BASENAMES, basenames ) )
+ {
+ stringList dirnames;
+ string_list( RPMTAG_DIRNAMES, dirnames );
+ intList dirindexes;
+ int_list( RPMTAG_DIRINDEXES, dirindexes );
+ for ( unsigned i = 0; i < basenames.size(); ++ i )
+ {
+ ret.push_back( dirnames[dirindexes[i]] + basenames[i] );
+ }
+ }
+
+ return ret;
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_fileinfos
+// METHOD TYPE : std::list<FileInfo>
+//
+// DESCRIPTION :
+//
+std::list<FileInfo> RpmHeader::tag_fileinfos() const
+{
+ std::list<FileInfo> ret;
+
+ stringList basenames;
+ if ( string_list( RPMTAG_BASENAMES, basenames ) )
+ {
+ stringList dirnames;
+ string_list( RPMTAG_DIRNAMES, dirnames );
+ intList dirindexes;
+ int_list( RPMTAG_DIRINDEXES, dirindexes );
+ intList filesizes;
+ int_list( RPMTAG_FILESIZES, filesizes );
+ stringList md5sums;
+ string_list( RPMTAG_FILEMD5S, md5sums );
+ stringList usernames;
+ string_list( RPMTAG_FILEUSERNAME, usernames );
+ stringList groupnames;
+ string_list( RPMTAG_FILEGROUPNAME, groupnames );
+ intList uids;
+ int_list( RPMTAG_FILEUIDS, uids );
+ intList gids;
+ int_list( RPMTAG_FILEGIDS, gids );
+ intList filemodes;
+ int_list( RPMTAG_FILEMODES, filemodes );
+ intList filemtimes;
+ int_list( RPMTAG_FILEMTIMES, filemtimes );
+ intList fileflags;
+ int_list( RPMTAG_FILEFLAGS, fileflags );
+ stringList filelinks;
+ string_list( RPMTAG_FILELINKTOS, filelinks );
+
+ for ( unsigned i = 0; i < basenames.size(); ++ i )
+ {
+ uid_t uid;
+ if (uids.empty())
{
- return string_val( RPMTAG_POSTIN );
+ uid = unameToUid( usernames[i].c_str(), &uid );
}
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_preun
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_preun() const
+ else
{
- return string_val( RPMTAG_PREUN );
+ uid =uids[i];
}
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_postun
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_postun() const
+
+ gid_t gid;
+ if (gids.empty())
{
- return string_val( RPMTAG_POSTUN );
+ gid = gnameToGid( groupnames[i].c_str(), &gid );
}
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_sourcerpm
- // METHOD TYPE : std::string
- //
- // DESCRIPTION :
- //
- std::string RpmHeader::tag_sourcerpm() const
+ else
{
- return string_val( RPMTAG_SOURCERPM );
+ gid = gids[i];
}
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_filenames
- // METHOD TYPE : std::list<std::string>
- //
- // DESCRIPTION :
- //
- std::list<std::string> RpmHeader::tag_filenames() const
+
+ FileInfo info = {
+ dirnames[dirindexes[i]] + basenames[i],
+ filesizes[i],
+ md5sums[i],
+ uid,
+ gid,
+ filemodes[i],
+ filemtimes[i],
+ fileflags[i] & RPMFILE_GHOST,
+ filelinks[i]
+ };
+
+ ret.push_back( info );
+ }
+ }
+
+ return ret;
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_changelog
+// METHOD TYPE : Changelog
+//
+// DESCRIPTION :
+//
+Changelog RpmHeader::tag_changelog() const
+{
+ Changelog ret;
+
+ intList times;
+ if ( int_list( RPMTAG_CHANGELOGTIME, times ) )
+ {
+ stringList names;
+ string_list( RPMTAG_CHANGELOGNAME, names );
+ stringList texts;
+ string_list( RPMTAG_CHANGELOGTEXT, texts );
+ for ( unsigned i = 0; i < times.size(); ++ i )
+ {
+ ret.push_back( ChangelogEntry( times[i], names[i], texts[i] ) );
+ }
+ }
+
+ return ret;
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : RpmHeader::tag_du
+// METHOD TYPE : PkgDu &
+//
+// DESCRIPTION :
+//
+DiskUsage & RpmHeader::tag_du( DiskUsage & dudata_r ) const
+{
+ dudata_r.clear();
+ stringList basenames;
+ if ( string_list( RPMTAG_BASENAMES, basenames ) )
+ {
+ stringList dirnames;
+ string_list( RPMTAG_DIRNAMES, dirnames );
+ intList dirindexes;
+ int_list( RPMTAG_DIRINDEXES, dirindexes );
+
+ intList filedevices;
+ int_list( RPMTAG_FILEDEVICES, filedevices );
+ intList fileinodes;
+ int_list( RPMTAG_FILEINODES, fileinodes );
+ intList filesizes;
+ int_list( RPMTAG_FILESIZES, filesizes );
+ intList filemodes;
+ int_list( RPMTAG_FILEMODES, filemodes );
+
+ ///////////////////////////////////////////////////////////////////
+ // Create and collect Entries by index. devino_cache is used to
+ // filter out hardliks ( different name but same device and inode ).
+ ///////////////////////////////////////////////////////////////////
+ filesystem::DevInoCache trace;
+ std::vector<DiskUsage::Entry> entries;
+ entries.resize( dirnames.size() );
+ for ( unsigned i = 0; i < dirnames.size(); ++i )
+ {
+ entries[i] = DiskUsage::Entry( dirnames[i] );
+
+ // cut off deeper directory levels in DiskUsage::Entry
+ unsigned level = 3; // number of '/' incl. a trailing one
+ std::string::size_type pos = 0; // we know rpm stores absolute pathnames
+ while ( --level && pos != std::string::npos )
{
- std::list<std::string> ret;
-
- stringList basenames;
- if ( string_list( RPMTAG_BASENAMES, basenames ) ) {
- stringList dirnames;
- string_list( RPMTAG_DIRNAMES, dirnames );
- intList dirindexes;
- int_list( RPMTAG_DIRINDEXES, dirindexes );
- for ( unsigned i = 0; i < basenames.size(); ++ i ) {
- ret.push_back( dirnames[dirindexes[i]] + basenames[i] );
- }
- }
-
- return ret;
+ pos = entries[i].path.find( "/", pos+1 );
}
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_changelog
- // METHOD TYPE : Changelog
- //
- // DESCRIPTION :
- //
- Changelog RpmHeader::tag_changelog() const
+ if ( pos != std::string::npos )
{
- Changelog ret;
-
- intList times;
- if ( int_list( RPMTAG_CHANGELOGTIME, times ) ) {
- stringList names;
- string_list( RPMTAG_CHANGELOGNAME, names );
- stringList texts;
- string_list( RPMTAG_CHANGELOGTEXT, texts );
- for ( unsigned i = 0; i < times.size(); ++ i ) {
- ret.push_back( ChangelogEntry( times[i], names[i], texts[i] ) );
- }
- }
-
- return ret;
+ entries[i].path.erase( pos+1 );
}
-
-#warning FIXME disk usage data
-#if 0
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : RpmHeader::tag_du
- // METHOD TYPE : PkgDu &
- //
- // DESCRIPTION :
- //
- PkgDu & RpmHeader::tag_du( PkgDu & dudata_r ) const
+ }
+
+ for ( unsigned i = 0; i < basenames.size(); ++ i )
+ {
+ filesystem::StatMode mode( filemodes[i] );
+ if ( mode.isFile() )
{
- dudata_r.clear();
- stringList basenames;
- if ( string_list( RPMTAG_BASENAMES, basenames ) ) {
- stringList dirnames;
- string_list( RPMTAG_DIRNAMES, dirnames );
- intList dirindexes;
- int_list( RPMTAG_DIRINDEXES, dirindexes );
-
- intList filedevices;
- int_list( RPMTAG_FILEDEVICES, filedevices );
- intList fileinodes;
- int_list( RPMTAG_FILEINODES, fileinodes );
- intList filesizes;
- int_list( RPMTAG_FILESIZES, filesizes );
- intList filemodes;
- int_list( RPMTAG_FILEMODES, filemodes );
-
- ///////////////////////////////////////////////////////////////////
- // Create and collect Entries by index. devino_cache is used to
- // filter out hardliks ( different name but same device and inode ).
- ///////////////////////////////////////////////////////////////////
- PathInfo::devino_cache trace;
- vector<PkgDu::Entry> entries;
- entries.resize( dirnames.size() );
- for ( unsigned i = 0; i < dirnames.size(); ++i ) {
- entries[i] = dirnames[i];
- }
-
- for ( unsigned i = 0; i < basenames.size(); ++ i ) {
- PathInfo::stat_mode mode( filemodes[i] );
- if ( mode.isFile() ) {
- if ( trace.insert( filedevices[i], fileinodes[i] ) ) {
- // Count full 1K blocks
- entries[dirindexes[i]]._size += ByteCount( filesizes[i] ).fillBlock();
- ++(entries[dirindexes[i]]._files);
- }
- // else: hardlink; already counted this device/inode
- }
- }
-
- ///////////////////////////////////////////////////////////////////
- // Crreate and collect by index Entries. DevInoTrace is used to
- // filter out hardliks ( different name but same device and inode ).
- ///////////////////////////////////////////////////////////////////
- for ( unsigned i = 0; i < entries.size(); ++i ) {
- if ( entries[i]._size ) {
- dudata_r.add( entries[i] );
- }
- }
+ if ( trace.insert( filedevices[i], fileinodes[i] ) )
+ {
+ // Count full 1K blocks
+ entries[dirindexes[i]]._size += ByteCount( filesizes[i] ).blocks( ByteCount::K );
+ ++(entries[dirindexes[i]]._files);
}
- return dudata_r;
+ // else: hardlink; already counted this device/inode
}
-#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ // Collect all enties. We first unify the duplicate entries that
+ // were created by cutting off deeper levels. Then the size of each
+ // directory must also be added to each of it's parent directories.
+ ///////////////////////////////////////////////////////////////////
+ DiskUsage tmpdata;
+ for ( unsigned i = 0; i < entries.size(); ++i )
+ {
+ if ( entries[i]._size )
+ tmpdata.add( entries[i] );
+ }
+
+ for_( it, tmpdata.begin(), tmpdata.end() )
+ {
+ DiskUsage::Entry ent( *it );
+
+ do {
+ dudata_r.add( ent );
+ if ( ent.path.size() <= 1 ) // "" or "/"
+ break;
+
+ // set path to parent dir. Note that DiskUsage::Entry
+ // has leading and trailing '/' on pathnmes.
+ std::string::size_type rstart = ent.path.size() - 2; // trailing '/' !
+ std::string::size_type lpos = ent.path.rfind( '/', rstart ); // one but last '/'
+ if ( lpos == std::string::npos )
+ break;
+
+ ent.path.erase( lpos + 1 );
+ } while( true );
+ }
+ }
+ return dudata_r;
+}
- } // namespace rpm
- } // namespace target
+} // namespace rpm
+} // namespace target
} // namespace zypp