MESSAGE( STATUS "rpm found: enable rpm-4 compat interface." )
ADD_DEFINITIONS(-D_RPM_5)
elseif ( RPM_SUSPECT_VERSION STREQUAL "4.x" )
+ MESSAGE( STATUS "rpm found: use rpm-4.x interface." )
+ ADD_DEFINITIONS(-D_RPM_4_X)
+ elseif ( RPM_SUSPECT_VERSION STREQUAL "4.4" )
MESSAGE( STATUS "rpm found: enable rpm-4.4 legacy interface." )
- ADD_DEFINITIONS(-D_RPM_4_4_COMPAT)
+ ADD_DEFINITIONS(-D_RPM_4_4)
endif ( RPM_SUSPECT_VERSION STREQUAL "5.x" )
ENDIF( NOT RPM_FOUND)
#ifdef _RPM_5
#undef RPM_NULL_TYPE
#define RPM_NULL_TYPE rpmTagType(0)
-#endif
-
-#ifndef _RPM_4_4_COMPAT
-#ifdef _RPM_5
typedef rpmuint32_t rpm_count_t;
-#else
+#elifdef _RPM_4_4
typedef int32_t rpm_count_t;
#endif
-#endif
}
#include <iostream>
#include "zypp/base/Logger.h"
+#include "zypp/base/NonCopyable.h"
#include "zypp/target/rpm/BinHeader.h"
namespace rpm
{
+ /** Helper for header data retieval.
+ * With \c _RPM_4_X use \c ::headerGet; with older \c _RPM_4_4
+ * use the meanwhile deprecated \c ::headerGetEntry.
+ * \ingroup g_RAII
+ */
+ struct HeaderEntryGetter : private base::NonCopyable
+ {
+ public:
+ HeaderEntryGetter( const Header & h_r, rpmTag & tag_r );
+ ~HeaderEntryGetter();
+ rpmTagType type();
+ rpm_count_t cnt();
+ void * val();
+ private:
+#ifdef _RPM_4_X
+ ::rpmtd _rpmtd;
+#else
+ rpmTagType _type;
+ rpm_count_t _cnt;
+ void * _val;
+#endif //_RPM_4_X
+ };
+
+#ifdef _RPM_4_X
+ inline HeaderEntryGetter::HeaderEntryGetter( const Header & h_r, rpmTag & tag_r )
+ : _rpmtd( ::rpmtdNew() )
+ { ::headerGet( h_r, tag_r, _rpmtd, HEADERGET_DEFAULT ); }
+ inline HeaderEntryGetter::~HeaderEntryGetter()
+ { ::rpmtdFreeData( _rpmtd ); ::rpmtdFree( _rpmtd ); }
+ inline rpmTagType HeaderEntryGetter::type() { return _rpmtd->type; }
+ inline rpm_count_t HeaderEntryGetter::cnt() { return _rpmtd->count; }
+ inline void * HeaderEntryGetter::val() { return _rpmtd->data; }
+#else
+ inline HeaderEntryGetter::HeaderEntryGetter( const Header & h_r, rpmTag & tag_r )
+ : _type( RPM_NULL_TYPE )
+ , _cnt( 0 )
+ , _val( 0 )
+ { ::headerGetEntry( h_r, tag_r, hTYP_t(&_type), &_val, &_cnt ); }
+ inline HeaderEntryGetter::~HeaderEntryGetter()
+ { if ( _val && _type == RPM_STRING_ARRAY_TYPE ) free( _val ); }
+ inline rpmTagType HeaderEntryGetter::type() { return _type; }
+ inline rpm_count_t HeaderEntryGetter::cnt() { return _cnt; }
+ inline void * HeaderEntryGetter::val( int i ) { return _val; }
+#endif //_RPM_4_X
+
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : BinHeader::intList
//
///////////////////////////////////////////////////////////////////
-BinHeader::intList::intList()
- : cnt( 0 ), val( 0 ), type( RPM_NULL_TYPE )
-{}
-
unsigned BinHeader::intList::set( void * val_r, unsigned cnt_r, rpmTagType type_r )
{
- val = val_r;
- cnt = val ? cnt_r : 0;
- type = type_r;
- return cnt;
-}
-
-int BinHeader::intList::operator[]( const unsigned idx_r ) const
-{
- if ( idx_r < cnt )
- {
- switch ( type )
+ if ( val_r )
+ switch ( _type )
{
#if RPM_CHAR_TYPE != RPM_INT8_TYPE
- case RPM_CHAR_TYPE:
- return ((char*)val)[idx_r];
+ case RPM_CHAR_TYPE:
+ std::vector<long>( (char*)val_r, ((char*)val_r)+cnt_r ).swap( _data );
+ break;
#endif
- case RPM_INT8_TYPE:
- return ((int8_t*)val)[idx_r];
- case RPM_INT16_TYPE:
- return ((int16_t*)val)[idx_r];
- case RPM_INT32_TYPE:
- return ((int32_t*)val)[idx_r];
+ case RPM_INT8_TYPE:
+ std::vector<long>( (int8_t*)val_r, ((int8_t*)val_r)+cnt_r ).swap( _data );
+ break;
+ case RPM_INT16_TYPE:
+ std::vector<long>( (int16_t*)val_r, ((int16_t*)val_r)+cnt_r ).swap( _data );
+ break;
+ case RPM_INT32_TYPE:
+ std::vector<long>( (int32_t*)val_r, ((int32_t*)val_r)+cnt_r ).swap( _data );
+ break;
+ #ifdef _RPM_4_X
+ case RPM_INT64_TYPE:
+ std::vector<long>( (int64_t*)val_r, ((int64_t*)val_r)+cnt_r ).swap( _data );
+ break;
+ #endif
+ default:
+ std::vector<long>( cnt_r, 0L ).swap( _data );
+ break;
}
- }
- return 0;
+ else
+ _data.clear();
+ return _data.size();
}
///////////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////////
-void BinHeader::stringList::clear()
-{
- if ( val )
- free( val );
- val = 0;
- cnt = 0;
-}
-
-BinHeader::stringList::stringList()
- : cnt( 0 ), val( 0 )
-{}
-
unsigned BinHeader::stringList::set( char ** val_r, unsigned cnt_r )
{
- clear();
- val = val_r;
- cnt = val ? cnt_r : 0;
- return cnt;
-}
-
-std::string BinHeader::stringList::operator[]( const unsigned idx_r ) const
-{
- return( idx_r < cnt ? val[idx_r] : "" );
+ if ( val_r )
+ std::vector<std::string>( val_r, val_r+cnt_r ).swap( _data );
+ else
+ _data.clear();
+ return _data.size();
}
///////////////////////////////////////////////////////////////////
{
if ( !empty() )
{
- rpmTagType type = RPM_NULL_TYPE;
- rpm_count_t cnt = 0;
- void * val = 0;
- ::headerGetEntry( _h, tag_r, hTYP_t(&type), &val, &cnt );
+ HeaderEntryGetter headerget( _h, tag_r );
- if ( val )
+ if ( headerget.val() )
{
- switch ( type )
+ switch ( headerget.type() )
{
case RPM_NULL_TYPE:
- return lst_r.set( 0, 0, type );
+ return lst_r.set( 0, 0, headerget.type() );
#if RPM_CHAR_TYPE != RPM_INT8_TYPE
case RPM_CHAR_TYPE:
#endif
case RPM_INT8_TYPE:
case RPM_INT16_TYPE:
case RPM_INT32_TYPE:
- return lst_r.set( val, cnt, type );
+ return lst_r.set( headerget.val(), headerget.cnt(), headerget.type() );
- case RPM_STRING_ARRAY_TYPE:
- free( val );
- // fall through
default:
- INT << "RPM_TAG MISSMATCH: RPM_INT32_TYPE " << tag_r << " got type " << type << endl;
+ INT << "RPM_TAG MISSMATCH: RPM_INT32_TYPE " << tag_r << " got type " << headerget.type() << endl;
}
}
}
{
if ( !empty() )
{
- rpmTagType type = RPM_NULL_TYPE;
- rpm_count_t cnt = 0;
- void * val = 0;
- ::headerGetEntry( _h, tag_r, hTYP_t(&type), &val, &cnt );
+ HeaderEntryGetter headerget( _h, tag_r );
- if ( val )
+ if ( headerget.val() )
{
- switch ( type )
+ switch ( headerget.type() )
{
case RPM_NULL_TYPE:
return lst_r.set( 0, 0 );
case RPM_STRING_ARRAY_TYPE:
- return lst_r.set( (char**)val, cnt );
+ return lst_r.set( (char**)headerget.val(), headerget.cnt() );
default:
- INT << "RPM_TAG MISSMATCH: RPM_STRING_ARRAY_TYPE " << tag_r << " got type " << type << endl;
+ INT << "RPM_TAG MISSMATCH: RPM_STRING_ARRAY_TYPE " << tag_r << " got type " << headerget.type() << endl;
}
}
}
{
if ( !empty() )
{
- rpmTagType type = RPM_NULL_TYPE;
- rpm_count_t cnt = 0;
- void * val = 0;
- ::headerGetEntry( _h, tag_r, hTYP_t(&type), &val, &cnt );
+ HeaderEntryGetter headerget( _h, tag_r );
- if ( val )
+ if ( headerget.val() )
{
- switch ( type )
+ switch ( headerget.type() )
{
case RPM_NULL_TYPE:
return 0;
#if RPM_CHAR_TYPE != RPM_INT8_TYPE
case RPM_CHAR_TYPE:
- return *((char*)val);
+ return *((char*)headerget.val());
#endif
case RPM_INT8_TYPE:
- return *((int8_t*)val);
+ return *((int8_t*)headerget.val());
case RPM_INT16_TYPE:
- return *((int16_t*)val);
+ return *((int16_t*)headerget.val());
case RPM_INT32_TYPE:
- return *((int32_t*)val);
+ return *((int32_t*)headerget.val());
- case RPM_STRING_ARRAY_TYPE:
- free( val );
- // fall through
default:
- INT << "RPM_TAG MISSMATCH: RPM_INT32_TYPE " << tag_r << " got type " << type << endl;
+ INT << "RPM_TAG MISSMATCH: RPM_INT32_TYPE " << tag_r << " got type " << headerget.type() << endl;
}
}
}
{
if ( !empty() )
{
- rpmTagType type = RPM_NULL_TYPE;
- rpm_count_t cnt = 0;
- void * val = 0;
- ::headerGetEntry( _h, tag_r, hTYP_t(&type), &val, &cnt );
+ HeaderEntryGetter headerget( _h, tag_r );
- if ( val )
+ if ( headerget.val() )
{
- switch ( type )
+ switch ( headerget.type() )
{
case RPM_NULL_TYPE:
return "";
case RPM_STRING_TYPE:
- return (char*)val;
+ return (char*)headerget.val();
- case RPM_STRING_ARRAY_TYPE:
- free( val );
- // fall through
- default:
- INT << "RPM_TAG MISSMATCH: RPM_STRING_TYPE " << tag_r << " got type " << type << endl;
+ default:
+ INT << "RPM_TAG MISSMATCH: RPM_STRING_TYPE " << tag_r << " got type " << headerget.type() << endl;
}
}
}
#include <iosfwd>
#include <string>
+#include <vector>
#include <list>
#include "zypp/base/ReferenceCounted.h"
/**
*
**/
-class BinHeader::intList
+class BinHeader::intList : private base::NonCopyable
{
- intList ( const intList & );
- intList & operator=( const intList & );
-private:
- unsigned cnt;
- void * val;
- rpmTagType type;
-private:
- friend class BinHeader;
- unsigned set( void * val_r, unsigned cnt_r, rpmTagType type_r );
-public:
- intList();
- bool empty() const
- {
- return cnt==0;
- }
- unsigned size() const
- {
- return cnt;
- }
- int operator[]( const unsigned idx_r ) const;
+ public:
+ intList()
+ : _type( RPM_NULL_TYPE )
+ {}
+
+ bool empty() const
+ { return _data.empty(); }
+
+ unsigned size() const
+ { return _data.size(); }
+
+ long operator[]( const unsigned idx_r ) const
+ { return idx_r < _data.size() ? _data[idx_r] : 0; }
+
+ private:
+ friend class BinHeader;
+ unsigned set( void * val_r, unsigned cnt_r, rpmTagType type_r );
+
+ private:
+ std::vector<long> _data;
+ rpmTagType _type;
};
///////////////////////////////////////////////////////////////////
/**
*
**/
-class BinHeader::stringList
+class BinHeader::stringList : private base::NonCopyable
{
- stringList ( const stringList & );
- stringList & operator=( const stringList & );
-private:
- unsigned cnt;
- char ** val;
- void clear();
-private:
- friend class BinHeader;
- unsigned set( char ** val_r, unsigned cnt_r );
-public:
- stringList();
- ~stringList()
- {
- clear();
- }
- bool empty() const
- {
- return cnt==0;
- }
- unsigned size() const
- {
- return cnt;
- }
- std::string operator[]( const unsigned idx_r ) const;
+ public:
+ bool empty() const
+ { return _data.empty(); }
+
+ unsigned size() const
+ { return _data.size(); }
+
+ std::string operator[]( const unsigned idx_r ) const
+ { return idx_r < _data.size() ? _data[idx_r] : std::string(); }
+
+ private:
+ friend class BinHeader;
+ unsigned set( char ** val_r, unsigned cnt_r );
+
+ private:
+ std::vector<std::string> _data;
};
///////////////////////////////////////////////////////////////////
*
*/
#include "librpm.h"
-#if !defined(_RPM_4_4_COMPAT) && !defined(_RPM_5)
+#ifdef _RPM_4_4
#include <rpm/ugid.h>
#else
////////////////////////////////////////////////////////////////////
unsigned count = 0;
if ( valid() )
{
-#if defined(_RPM_4_4_COMPAT) || defined(_RPM_5)
+#ifndef _RPM_4_4
// looks like rpm-4.7 has no public dbi interface anymore
int dbi = ::rpmdbOpen("/", &_d._db, O_RDONLY, 0);
if (dbi == 0) {
#include "librpm.h"
extern "C"
{
-#ifndef _RPM_4_4_COMPAT
#ifdef _RPM_5
typedef rpmuint32_t rpm_count_t;
-#else
+#elifdef _RPM_4_4
typedef int32_t rpm_count_t;
#endif
-#endif
-#if defined( _RPM_5 )
+#ifdef _RPM_5
#define HGEPtr_t void *
#define headerGetEntryMinMemory headerGetEntry
#define headerNVR(h,n,v,r) headerNEVRA(h,n,NULL,v,r,NULL)
-#elif defined( _RPM_4_4_COMPAT )
-#define HGEPtr_t void *
-#else
+#elifdef _RPM_4_4
#define HGEPtr_t const void *
#endif
}
#include "zypp/target/rpm/RpmCallbacks.h"
#include "zypp/ZYppCallbacks.h"
+#define xmalloc malloc
+#define xstrdup strdup
+
extern "C"
{
#include <string.h>
{
namespace rpm
{
-
static int fadFileSize;
static ssize_t Pread(FD_t fd, void * buf, size_t count, off_t offset)
/*@=boundsread@*/
/*@-bounds@*/
+#ifndef _RPM_4_X
static void compressFilelist(Header h)
/*@*/
{
&pEVR, 1);
}
}
+#else
+static void compressFilelist(Header h)
+{
+ struct rpmtd_s fileNames;
+ char ** dirNames;
+ const char ** baseNames;
+ uint32_t * dirIndexes;
+ rpm_count_t count;
+ int xx, i;
+ int dirIndex = -1;
+
+ /*
+ * This assumes the file list is already sorted, and begins with a
+ * single '/'. That assumption isn't critical, but it makes things go
+ * a bit faster.
+ */
+
+ if (headerIsEntry(h, RPMTAG_DIRNAMES)) {
+ xx = headerDel(h, RPMTAG_OLDFILENAMES);
+ return; /* Already converted. */
+ }
+
+ if (!headerGet(h, RPMTAG_OLDFILENAMES, &fileNames, HEADERGET_MINMEM))
+ return;
+ count = rpmtdCount(&fileNames);
+ if (count < 1)
+ return;
+
+ dirNames = (char**)malloc(sizeof(*dirNames) * count); /* worst case */
+ baseNames = (const char**)malloc(sizeof(*dirNames) * count);
+ dirIndexes = (uint32_t*)malloc(sizeof(*dirIndexes) * count);
+
+ /* HACK. Source RPM, so just do things differently */
+ { const char *fn = rpmtdGetString(&fileNames);
+ if (fn && *fn != '/') {
+ dirIndex = 0;
+ dirNames[dirIndex] = xstrdup("");
+ while ((i = rpmtdNext(&fileNames)) >= 0) {
+ dirIndexes[i] = dirIndex;
+ baseNames[i] = rpmtdGetString(&fileNames);
+ }
+ goto exit;
+ }
+ }
+
+ while ((i = rpmtdNext(&fileNames)) >= 0) {
+ char ** needle;
+ char savechar;
+ char * baseName;
+ size_t len;
+ const char *filename = rpmtdGetString(&fileNames);
+
+ if (filename == NULL) /* XXX can't happen */
+ continue;
+ baseName = strrchr((char*)filename, '/') + 1;
+ len = baseName - filename;
+ needle = dirNames;
+ savechar = *baseName;
+ *baseName = '\0';
+ if (dirIndex < 0 ||
+ (needle = (char**)bsearch(&filename, dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL) {
+ char *s = (char*)malloc(len + 1);
+ rstrlcpy(s, filename, len + 1);
+ dirIndexes[i] = ++dirIndex;
+ dirNames[dirIndex] = s;
+ } else
+ dirIndexes[i] = needle - dirNames;
+
+ *baseName = savechar;
+ baseNames[i] = baseName;
+ }
+
+exit:
+ if (count > 0) {
+ headerPutUint32(h, RPMTAG_DIRINDEXES, dirIndexes, count);
+ headerPutStringArray(h, RPMTAG_BASENAMES, baseNames, count);
+ headerPutStringArray(h, RPMTAG_DIRNAMES,
+ (const char **) dirNames, dirIndex + 1);
+ }
+
+ rpmtdFreeData(&fileNames);
+ for (i = 0; i <= dirIndex; i++) {
+ free(dirNames[i]);
+ }
+ free(dirNames);
+ free(baseNames);
+ free(dirIndexes);
+
+ xx = headerDel(h, RPMTAG_OLDFILENAMES);
+}
+
+/*
+ * Up to rpm 3.0.4, packages implicitly provided their own name-version-release.
+ * Retrofit an explicit "Provides: name = epoch:version-release.
+ */
+static void providePackageNVR(Header h)
+{
+ const char *name;
+ char *pEVR;
+ rpmsenseFlags pFlags = RPMSENSE_EQUAL;
+ int bingo = 1;
+ struct rpmtd_s pnames;
+ rpmds hds, nvrds;
+
+ /* Generate provides for this package name-version-release. */
+ pEVR = headerGetEVR(h, &name);
+ if (!(name && pEVR))
+ return;
+
+ /*
+ * Rpm prior to 3.0.3 does not have versioned provides.
+ * If no provides at all are available, we can just add.
+ */
+ if (!headerGet(h, RPMTAG_PROVIDENAME, &pnames, HEADERGET_MINMEM)) {
+ goto exit;
+ }
+
+ /*
+ * Otherwise, fill in entries on legacy packages.
+ */
+ if (!headerIsEntry(h, RPMTAG_PROVIDEVERSION)) {
+ while (rpmtdNext(&pnames) >= 0) {
+ uint32_t fdummy = RPMSENSE_ANY;
+
+ headerPutString(h, RPMTAG_PROVIDEVERSION, "");
+ headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &fdummy, 1);
+ }
+ goto exit;
+ }
+
+ /* see if we already have this provide */
+ hds = rpmdsNew(h, RPMTAG_PROVIDENAME, 0);
+ nvrds = rpmdsSingle(RPMTAG_PROVIDENAME, name, pEVR, pFlags);
+ if (rpmdsFind(hds, nvrds) >= 0) {
+ bingo = 0;
+ }
+ rpmdsFree(hds);
+ rpmdsFree(nvrds);
+
+exit:
+ if (bingo) {
+ const char *evr = pEVR;
+ uint32_t fdummy = pFlags;
+ headerPutString(h, RPMTAG_PROVIDENAME, name);
+ headerPutString(h, RPMTAG_PROVIDEVERSION, evr);
+ headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &fdummy, 1);
+ }
+ rpmtdFreeData(&pnames);
+ free(pEVR);
+}
+
+#endif
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
report->start(v3db_r);
try
{
- internal_convertV3toV4( v3db_r, v4db_r, report );
+ //internal_convertV3toV4( v3db_r, v4db_r, report );
}
catch (RpmException & excpt_r)
{