2002-03-25 23:16:26 +03:00
/** \ingroup python
* \ file python / header - py . c
*/
2002-06-05 15:06:46 +04:00
# include <sys/time.h>
2002-03-25 23:16:26 +03:00
# include "Python.h"
# include "rpmio_internal.h"
# include "rpmcli.h" /* XXX for rpmCheckSig */
# include "misc.h"
# include "header_internal.h"
# include "header-py.h"
/** \ingroup python
*/
struct hdrObject_s {
PyObject_HEAD ;
Header h ;
Header sigs ; /* XXX signature tags are in header */
char * * md5list ;
char * * fileList ;
char * * linkList ;
int_32 * fileSizes ;
int_32 * mtimes ;
int_32 * uids , * gids ; /* XXX these tags are not used anymore */
unsigned short * rdevs ;
unsigned short * modes ;
} ;
/*@unused@*/ static inline Header headerAllocated ( Header h ) {
h - > flags | = HEADERFLAG_ALLOCATED ;
return 0 ;
}
/** \ingroup python
*/
2008-02-22 20:08:53 +03:00
static PyObject * hdrKeyList ( hdrObject * s ) {
2002-03-25 23:16:26 +03:00
PyObject * list , * o ;
HeaderIterator iter ;
int tag , type ;
list = PyList_New ( 0 ) ;
iter = headerInitIterator ( s - > h ) ;
while ( headerNextIterator ( iter , & tag , & type , NULL , NULL ) ) {
if ( tag = = HEADER_I18NTABLE ) continue ;
switch ( type ) {
case RPM_BIN_TYPE :
case RPM_INT32_TYPE :
case RPM_CHAR_TYPE :
case RPM_INT8_TYPE :
case RPM_INT16_TYPE :
case RPM_STRING_ARRAY_TYPE :
case RPM_STRING_TYPE :
PyList_Append ( list , o = PyInt_FromLong ( tag ) ) ;
Py_DECREF ( o ) ;
}
}
headerFreeIterator ( iter ) ;
return list ;
}
/** \ingroup python
*/
static PyObject * hdrUnload ( hdrObject * s , PyObject * args , PyObject * keywords ) {
char * buf ;
PyObject * rc ;
int len , legacy = 0 ;
Header h ;
static char * kwlist [ ] = { " legacyHeader " , NULL } ;
if ( ! PyArg_ParseTupleAndKeywords ( args , keywords , " |i " , kwlist , & legacy ) )
return NULL ;
h = headerLink ( s - > h ) ;
/* XXX this legacy switch is a hack, needs to be removed. */
if ( legacy ) {
h = headerCopy ( s - > h ) ; /* XXX strip region tags, etc */
headerFree ( s - > h ) ;
}
len = headerSizeof ( h , 0 ) ;
buf = headerUnload ( h ) ;
h = headerFree ( h ) ;
if ( buf = = NULL | | len = = 0 ) {
PyErr_SetString ( pyrpmError , " can't unload bad header \n " ) ;
return NULL ;
}
rc = PyString_FromStringAndSize ( buf , len ) ;
free ( buf ) ;
return rc ;
}
/** \ingroup python
* Returns a list of these tuples for each item that failed :
* ( attr_name , correctValue , currentValue )
* It should be passed the file number to verify .
*/
static PyObject * hdrVerifyFile ( hdrObject * s , PyObject * args ) {
int fileNumber ;
rpmVerifyAttrs verifyResult = 0 ;
PyObject * list , * tuple , * attrName ;
int type , count ;
struct stat sb ;
int i ;
time_t timeInt ;
struct tm * timeStruct ;
if ( ! PyInt_Check ( args ) ) {
PyErr_SetString ( PyExc_TypeError , " integer expected " ) ;
return NULL ;
}
fileNumber = ( int ) PyInt_AsLong ( args ) ;
/* XXX this routine might use callbacks intelligently. */
if ( rpmVerifyFile ( " " , s - > h , fileNumber , & verifyResult , RPMVERIFY_NONE ) ) {
Py_INCREF ( Py_None ) ;
return Py_None ;
}
list = PyList_New ( 0 ) ;
if ( ! verifyResult ) return list ;
/* XXX Legacy tag needs to go away. */
if ( ! s - > fileList ) {
headerGetEntry ( s - > h , RPMTAG_OLDFILENAMES , & type , ( void * * ) & s - > fileList ,
& count ) ;
}
lstat ( s - > fileList [ fileNumber ] , & sb ) ;
if ( verifyResult & RPMVERIFY_MD5 ) {
if ( ! s - > md5list ) {
headerGetEntry ( s - > h , RPMTAG_FILEMD5S , & type , ( void * * ) & s - > md5list ,
& count ) ;
}
2008-02-22 21:43:59 +03:00
char buf [ 2048 ] ;
if ( mdfile ( s - > fileList [ fileNumber ] , ( unsigned char * ) buf ) ) {
2002-03-25 23:16:26 +03:00
strcpy ( buf , " (unknown) " ) ;
}
tuple = PyTuple_New ( 3 ) ;
attrName = PyString_FromString ( " checksum " ) ;
PyTuple_SetItem ( tuple , 0 , attrName ) ;
PyTuple_SetItem ( tuple , 1 , PyString_FromString ( s - > md5list [ fileNumber ] ) ) ;
PyTuple_SetItem ( tuple , 2 , PyString_FromString ( buf ) ) ;
PyList_Append ( list , tuple ) ;
Py_DECREF ( tuple ) ;
}
if ( verifyResult & RPMVERIFY_FILESIZE ) {
if ( ! s - > fileSizes ) {
headerGetEntry ( s - > h , RPMTAG_FILESIZES , & type , ( void * * ) & s - > fileSizes ,
& count ) ;
}
tuple = PyTuple_New ( 3 ) ;
attrName = PyString_FromString ( " size " ) ;
PyTuple_SetItem ( tuple , 0 , attrName ) ;
2008-02-22 21:43:59 +03:00
PyTuple_SetItem ( tuple , 1 , PyString_FromString ( " 100 " ) ) ;
PyTuple_SetItem ( tuple , 2 , PyString_FromFormat ( " %ld " , ( long ) sb . st_size ) ) ;
2002-03-25 23:16:26 +03:00
PyList_Append ( list , tuple ) ;
Py_DECREF ( tuple ) ;
}
if ( verifyResult & RPMVERIFY_LINKTO ) {
if ( ! s - > linkList ) {
headerGetEntry ( s - > h , RPMTAG_FILELINKTOS , & type , ( void * * ) & s - > linkList ,
& count ) ;
}
2008-02-22 21:43:59 +03:00
char buf [ 2048 ] ;
i = readlink ( s - > fileList [ fileNumber ] , buf , sizeof ( buf ) - 1 ) ;
2002-03-25 23:16:26 +03:00
if ( i < = 0 )
strcpy ( buf , " (unknown) " ) ;
else
buf [ i ] = ' \0 ' ;
tuple = PyTuple_New ( 3 ) ;
attrName = PyString_FromString ( " link " ) ;
PyTuple_SetItem ( tuple , 0 , attrName ) ;
PyTuple_SetItem ( tuple , 1 , PyString_FromString ( s - > linkList [ fileNumber ] ) ) ;
PyTuple_SetItem ( tuple , 2 , PyString_FromString ( buf ) ) ;
PyList_Append ( list , tuple ) ;
Py_DECREF ( tuple ) ;
}
if ( verifyResult & RPMVERIFY_MTIME ) {
if ( ! s - > mtimes ) {
headerGetEntry ( s - > h , RPMTAG_FILEMTIMES , & type , ( void * * ) & s - > mtimes ,
& count ) ;
}
tuple = PyTuple_New ( 3 ) ;
attrName = PyString_FromString ( " time " ) ;
PyTuple_SetItem ( tuple , 0 , attrName ) ;
timeInt = sb . st_mtime ;
timeStruct = localtime ( & timeInt ) ;
2008-02-22 21:43:59 +03:00
char buf [ 2048 ] ;
2002-03-25 23:16:26 +03:00
strftime ( buf , sizeof ( buf ) - 1 , " %c " , timeStruct ) ;
PyTuple_SetItem ( tuple , 1 , PyString_FromString ( buf ) ) ;
timeInt = s - > mtimes [ fileNumber ] ;
timeStruct = localtime ( & timeInt ) ;
strftime ( buf , sizeof ( buf ) - 1 , " %c " , timeStruct ) ;
PyTuple_SetItem ( tuple , 2 , PyString_FromString ( buf ) ) ;
PyList_Append ( list , tuple ) ;
Py_DECREF ( tuple ) ;
}
if ( verifyResult & RPMVERIFY_RDEV ) {
if ( ! s - > rdevs ) {
headerGetEntry ( s - > h , RPMTAG_FILERDEVS , & type , ( void * * ) & s - > rdevs ,
& count ) ;
}
tuple = PyTuple_New ( 3 ) ;
attrName = PyString_FromString ( " device " ) ;
PyTuple_SetItem ( tuple , 0 , attrName ) ;
2008-02-22 21:43:59 +03:00
PyTuple_SetItem ( tuple , 1 ,
PyString_FromFormat ( " 0x%-4x " , s - > rdevs [ fileNumber ] ) ) ;
PyTuple_SetItem ( tuple , 2 ,
PyString_FromFormat ( " 0x%-4x " , ( unsigned ) sb . st_rdev ) ) ;
2002-03-25 23:16:26 +03:00
PyList_Append ( list , tuple ) ;
Py_DECREF ( tuple ) ;
}
/*
* RPMVERIFY_USER and RPM_VERIFY_GROUP are handled wrong here , but rpmlib . a
* doesn ' t do these correctly either . At least this is consistent .
*
* XXX Consistent ? rpmlib . a verifies user / group quite well , thank you .
* XXX The code below does nothing useful . FILEUSERNAME needs to be
* XXX retrieved and looked up .
*/
if ( verifyResult & RPMVERIFY_USER ) {
if ( ! s - > uids ) {
headerGetEntry ( s - > h , RPMTAG_FILEUIDS , & type , ( void * * ) & s - > uids ,
& count ) ;
}
tuple = PyTuple_New ( 3 ) ;
attrName = PyString_FromString ( " uid " ) ;
PyTuple_SetItem ( tuple , 0 , attrName ) ;
2008-02-22 21:43:59 +03:00
PyTuple_SetItem ( tuple , 1 ,
PyString_FromFormat ( " %d " , s - > uids [ fileNumber ] ) ) ;
PyTuple_SetItem ( tuple , 2 ,
PyString_FromFormat ( " %d " , sb . st_uid ) ) ;
2002-03-25 23:16:26 +03:00
PyList_Append ( list , tuple ) ;
Py_DECREF ( tuple ) ;
}
/*
* XXX The code below does nothing useful . FILEGROUPNAME needs to be
* XXX retrieved and looked up .
*/
if ( verifyResult & RPMVERIFY_GROUP ) {
if ( ! s - > gids ) {
headerGetEntry ( s - > h , RPMTAG_FILEGIDS , & type , ( void * * ) & s - > gids ,
& count ) ;
}
tuple = PyTuple_New ( 3 ) ;
attrName = PyString_FromString ( " gid " ) ;
PyTuple_SetItem ( tuple , 0 , attrName ) ;
2008-02-22 21:43:59 +03:00
PyTuple_SetItem ( tuple , 1 ,
PyString_FromFormat ( " %d " , s - > gids [ fileNumber ] ) ) ;
PyTuple_SetItem ( tuple , 2 ,
PyString_FromFormat ( " %d " , sb . st_gid ) ) ;
2002-03-25 23:16:26 +03:00
PyList_Append ( list , tuple ) ;
Py_DECREF ( tuple ) ;
}
if ( verifyResult & RPMVERIFY_MODE ) {
if ( ! s - > modes ) {
headerGetEntry ( s - > h , RPMTAG_FILEMODES , & type , ( void * * ) & s - > modes ,
& count ) ;
}
tuple = PyTuple_New ( 3 ) ;
attrName = PyString_FromString ( " permissions " ) ;
PyTuple_SetItem ( tuple , 0 , attrName ) ;
2008-02-22 21:43:59 +03:00
PyTuple_SetItem ( tuple , 1 ,
PyString_FromFormat ( " 0%-4o " , s - > modes [ fileNumber ] ) ) ;
PyTuple_SetItem ( tuple , 2 ,
PyString_FromFormat ( " 0%-4o " , sb . st_mode ) ) ;
2002-03-25 23:16:26 +03:00
PyList_Append ( list , tuple ) ;
Py_DECREF ( tuple ) ;
}
return list ;
}
/** \ingroup python
*/
2008-02-22 20:08:53 +03:00
static PyObject * hdrExpandFilelist ( hdrObject * s ) {
2002-03-25 23:16:26 +03:00
expandFilelist ( s - > h ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
}
/** \ingroup python
*/
2008-02-22 20:08:53 +03:00
static PyObject * hdrCompressFilelist ( hdrObject * s ) {
2002-03-25 23:16:26 +03:00
compressFilelist ( s - > h ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
}
/* make a header with _all_ the tags we need */
/** \ingroup python
*/
static void mungeFilelist ( Header h )
{
const char * * fileNames = NULL ;
int count = 0 ;
if ( ! headerIsEntry ( h , RPMTAG_BASENAMES )
| | ! headerIsEntry ( h , RPMTAG_DIRNAMES )
| | ! headerIsEntry ( h , RPMTAG_DIRINDEXES ) )
compressFilelist ( h ) ;
rpmBuildFileList ( h , & fileNames , & count ) ;
if ( fileNames = = NULL | | count < = 0 )
return ;
/* XXX Legacy tag needs to go away. */
headerAddEntry ( h , RPMTAG_OLDFILENAMES , RPM_STRING_ARRAY_TYPE ,
fileNames , count ) ;
free ( ( void * ) fileNames ) ;
}
/**
*/
static PyObject * rhnUnload ( hdrObject * s , PyObject * args ) {
int len ;
char * uh ;
PyObject * rc ;
Header h ;
if ( ! PyArg_ParseTuple ( args , " " ) )
return NULL ;
h = headerLink ( s - > h ) ;
/* Retrofit a RHNPlatform: tag. */
if ( ! headerIsEntry ( h , RPMTAG_RHNPLATFORM ) ) {
const char * arch ;
int_32 at ;
if ( headerGetEntry ( h , RPMTAG_ARCH , & at , ( void * * ) & arch , NULL ) )
headerAddEntry ( h , RPMTAG_RHNPLATFORM , at , arch , 1 ) ;
}
/* Legacy headers are forced into immutable region. */
if ( ! headerIsEntry ( h , RPMTAG_HEADERIMMUTABLE ) ) {
Header nh = headerReload ( h , RPMTAG_HEADERIMMUTABLE ) ;
/* XXX Another unload/load cycle to "seal" the immutable region. */
uh = headerUnload ( nh ) ;
headerFree ( nh ) ;
h = headerLoad ( uh ) ;
headerAllocated ( h ) ;
}
/* All headers have SHA1 digest, compute and add if necessary. */
if ( ! headerIsEntry ( h , RPMTAG_SHA1HEADER ) ) {
int_32 uht , uhc ;
const char * digest ;
size_t digestlen ;
DIGEST_CTX ctx ;
headerGetEntry ( h , RPMTAG_HEADERIMMUTABLE , & uht , ( void * * ) & uh , & uhc ) ;
ctx = rpmDigestInit ( PGPHASHALGO_SHA1 , RPMDIGEST_NONE ) ;
rpmDigestUpdate ( ctx , uh , uhc ) ;
rpmDigestFinal ( ctx , ( void * * ) & digest , & digestlen , 1 ) ;
headerAddEntry ( h , RPMTAG_SHA1RHN , RPM_STRING_TYPE , digest , 1 ) ;
uh = headerFreeData ( uh , uht ) ;
digest = _free ( digest ) ;
}
len = headerSizeof ( h , 0 ) ;
uh = headerUnload ( h ) ;
headerFree ( h ) ;
rc = PyString_FromStringAndSize ( uh , len ) ;
free ( uh ) ;
return rc ;
}
/** \ingroup python
*/
2008-02-22 20:08:53 +03:00
static PyObject * hdrFullFilelist ( hdrObject * s ) {
2002-03-25 23:16:26 +03:00
mungeFilelist ( s - > h ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
}
/** \ingroup python
*/
static PyObject * hdrSprintf ( hdrObject * s , PyObject * args ) {
char * fmt ;
char * r ;
errmsg_t err ;
PyObject * result ;
if ( ! PyArg_ParseTuple ( args , " s " , & fmt ) )
return NULL ;
r = headerSprintf ( s - > h , fmt , rpmTagTable , rpmHeaderFormats , & err ) ;
if ( ! r ) {
PyErr_SetString ( pyrpmError , err ) ;
return NULL ;
}
result = Py_BuildValue ( " s " , r ) ;
free ( r ) ;
return result ;
}
/** \ingroup python
*/
static struct PyMethodDef hdrMethods [ ] = {
2008-02-22 20:08:53 +03:00
{ " keys " , ( PyCFunction ) hdrKeyList , METH_NOARGS } ,
2002-03-25 23:16:26 +03:00
{ " unload " , ( PyCFunction ) hdrUnload , METH_VARARGS | METH_KEYWORDS } ,
{ " verifyFile " , ( PyCFunction ) hdrVerifyFile , 1 } ,
2008-02-22 20:08:53 +03:00
{ " expandFilelist " , ( PyCFunction ) hdrExpandFilelist , METH_NOARGS } ,
{ " compressFilelist " , ( PyCFunction ) hdrCompressFilelist , METH_NOARGS } ,
{ " fullFilelist " , ( PyCFunction ) hdrFullFilelist , METH_NOARGS } ,
2002-03-25 23:16:26 +03:00
{ " rhnUnload " , ( PyCFunction ) rhnUnload , METH_VARARGS } ,
{ " sprintf " , ( PyCFunction ) hdrSprintf , METH_VARARGS } ,
{ NULL , NULL } /* sentinel */
} ;
/** \ingroup python
*/
static PyObject * hdrGetAttr ( hdrObject * s , char * name ) {
return Py_FindMethod ( hdrMethods , ( PyObject * ) s , name ) ;
}
/** \ingroup python
*/
static void hdrDealloc ( hdrObject * s ) {
if ( s - > h ) headerFree ( s - > h ) ;
if ( s - > sigs ) headerFree ( s - > sigs ) ;
2008-02-22 21:07:07 +03:00
free ( s - > md5list ) ;
free ( s - > fileList ) ;
free ( s - > linkList ) ;
PyObject_Del ( s ) ;
2002-03-25 23:16:26 +03:00
}
/** \ingroup python
*/
long tagNumFromPyObject ( PyObject * item )
{
char * str ;
int i ;
if ( PyInt_Check ( item ) ) {
return PyInt_AsLong ( item ) ;
} else if ( PyString_Check ( item ) ) {
str = PyString_AsString ( item ) ;
for ( i = 0 ; i < rpmTagTableSize ; i + + )
if ( ! xstrcasecmp ( rpmTagTable [ i ] . name + 7 , str ) ) break ;
if ( i < rpmTagTableSize ) return rpmTagTable [ i ] . val ;
}
return - 1 ;
}
/*@}*/
/** \ingroup python
*/
static PyObject * hdrSubscript ( hdrObject * s , PyObject * item ) {
int type , count , i , tag = - 1 ;
void * data ;
PyObject * o , * metao ;
char * * stringArray ;
int forceArray = 0 ;
int freeData = 0 ;
char * str ;
struct headerSprintfExtension_s * ext = NULL ;
const struct headerSprintfExtension_s * extensions = rpmHeaderFormats ;
if ( PyCObject_Check ( item ) )
ext = PyCObject_AsVoidPtr ( item ) ;
else
tag = tagNumFromPyObject ( item ) ;
if ( tag = = - 1 & & PyString_Check ( item ) ) {
/* if we still don't have the tag, go looking for the header
extensions */
str = PyString_AsString ( item ) ;
while ( extensions - > name ) {
if ( extensions - > type = = HEADER_EXT_TAG
& & ! xstrcasecmp ( extensions - > name + 7 , str ) ) {
2006-05-14 17:06:45 +04:00
ext = extensions ;
2002-03-25 23:16:26 +03:00
}
extensions + + ;
}
}
if ( ext ) {
ext - > u . tagFunction ( s - > h , & type , ( const void * * ) & data , & count , & freeData ) ;
} else {
if ( tag = = - 1 ) {
PyErr_SetString ( PyExc_KeyError , " unknown header tag " ) ;
return NULL ;
}
/* XXX signature tags are appended to header, this API is gonna die */
if ( ! rpmPackageGetEntry ( NULL , s - > sigs , s - > h , tag , & type , & data , & count ) )
{
Py_INCREF ( Py_None ) ;
return Py_None ;
}
}
switch ( tag ) {
case RPMTAG_OLDFILENAMES :
case RPMTAG_FILESIZES :
case RPMTAG_FILESTATES :
case RPMTAG_FILEMODES :
case RPMTAG_FILEUIDS :
case RPMTAG_FILEGIDS :
case RPMTAG_FILERDEVS :
case RPMTAG_FILEMTIMES :
case RPMTAG_FILEMD5S :
case RPMTAG_FILELINKTOS :
case RPMTAG_FILEFLAGS :
case RPMTAG_FILEUSERNAME :
case RPMTAG_FILEGROUPNAME :
forceArray = 1 ;
break ;
case RPMTAG_SUMMARY :
case RPMTAG_GROUP :
case RPMTAG_DESCRIPTION :
freeData = 1 ;
break ;
default :
break ;
}
switch ( type ) {
case RPM_BIN_TYPE :
o = PyString_FromStringAndSize ( data , count ) ;
break ;
case RPM_INT32_TYPE :
if ( count ! = 1 | | forceArray ) {
metao = PyList_New ( 0 ) ;
for ( i = 0 ; i < count ; i + + ) {
o = PyInt_FromLong ( ( ( int * ) data ) [ i ] ) ;
PyList_Append ( metao , o ) ;
Py_DECREF ( o ) ;
}
o = metao ;
} else {
o = PyInt_FromLong ( * ( ( int * ) data ) ) ;
}
break ;
case RPM_CHAR_TYPE :
case RPM_INT8_TYPE :
if ( count ! = 1 | | forceArray ) {
metao = PyList_New ( 0 ) ;
for ( i = 0 ; i < count ; i + + ) {
o = PyInt_FromLong ( ( ( char * ) data ) [ i ] ) ;
PyList_Append ( metao , o ) ;
Py_DECREF ( o ) ;
}
o = metao ;
} else {
o = PyInt_FromLong ( * ( ( char * ) data ) ) ;
}
break ;
case RPM_INT16_TYPE :
if ( count ! = 1 | | forceArray ) {
metao = PyList_New ( 0 ) ;
for ( i = 0 ; i < count ; i + + ) {
o = PyInt_FromLong ( ( ( short * ) data ) [ i ] ) ;
PyList_Append ( metao , o ) ;
Py_DECREF ( o ) ;
}
o = metao ;
} else {
o = PyInt_FromLong ( * ( ( short * ) data ) ) ;
}
break ;
case RPM_STRING_ARRAY_TYPE :
stringArray = data ;
metao = PyList_New ( 0 ) ;
for ( i = 0 ; i < count ; i + + ) {
o = PyString_FromString ( stringArray [ i ] ) ;
PyList_Append ( metao , o ) ;
Py_DECREF ( o ) ;
}
free ( stringArray ) ;
o = metao ;
break ;
case RPM_STRING_TYPE :
if ( count ! = 1 | | forceArray ) {
stringArray = data ;
metao = PyList_New ( 0 ) ;
for ( i = 0 ; i < count ; i + + ) {
o = PyString_FromString ( stringArray [ i ] ) ;
PyList_Append ( metao , o ) ;
Py_DECREF ( o ) ;
}
o = metao ;
} else {
o = PyString_FromString ( data ) ;
if ( freeData )
free ( data ) ;
}
break ;
default :
PyErr_SetString ( PyExc_TypeError , " unsupported type in header " ) ;
return NULL ;
}
return o ;
}
/** \ingroup python
*/
static PyMappingMethods hdrAsMapping = {
2008-02-22 21:43:59 +03:00
( lenfunc ) 0 , /* mp_length */
2002-03-25 23:16:26 +03:00
( binaryfunc ) hdrSubscript , /* mp_subscript */
( objobjargproc ) 0 , /* mp_ass_subscript */
} ;
/** \ingroup python
*/
PyTypeObject hdrType = {
PyObject_HEAD_INIT ( NULL )
0 , /* ob_size */
" header " , /* tp_name */
sizeof ( hdrObject ) , /* tp_size */
0 , /* tp_itemsize */
( destructor ) hdrDealloc , /* tp_dealloc */
0 , /* tp_print */
( getattrfunc ) hdrGetAttr , /* tp_getattr */
0 , /* tp_setattr */
0 , /* tp_compare */
0 , /* tp_repr */
0 , /* tp_as_number */
0 , /* tp_as_sequence */
& hdrAsMapping , /* tp_as_mapping */
} ;
hdrObject * createHeaderObject ( Header h ) {
hdrObject * ho ;
2008-02-22 21:07:07 +03:00
ho = PyObject_New ( hdrObject , & hdrType ) ;
2002-03-25 23:16:26 +03:00
ho - > h = headerLink ( h ) ;
ho - > sigs = NULL ;
ho - > fileList = ho - > linkList = ho - > md5list = NULL ;
ho - > uids = ho - > gids = ho - > mtimes = ho - > fileSizes = NULL ;
ho - > modes = ho - > rdevs = NULL ;
return ho ;
}
Header hdrGetHeader ( hdrObject * h ) {
return h - > h ;
}
/**
*/
PyObject * rpmHeaderFromPackage ( PyObject * self , PyObject * args ) {
hdrObject * h ;
Header header ;
Header sigs ;
FD_t fd ;
int rawFd ;
int isSource = 0 ;
rpmRC rc ;
if ( ! PyArg_ParseTuple ( args , " i " , & rawFd ) ) return NULL ;
fd = fdDup ( rawFd ) ;
rc = rpmReadPackageInfo ( fd , & sigs , & header ) ;
Fclose ( fd ) ;
switch ( rc ) {
case RPMRC_BADSIZE :
case RPMRC_OK :
2008-02-22 21:07:07 +03:00
h = ( hdrObject * ) PyObject_New ( PyObject , & hdrType ) ;
2002-03-25 23:16:26 +03:00
h - > h = header ;
h - > sigs = sigs ;
h - > fileList = h - > linkList = h - > md5list = NULL ;
h - > uids = h - > gids = h - > mtimes = h - > fileSizes = NULL ;
h - > modes = h - > rdevs = NULL ;
if ( headerIsEntry ( header , RPMTAG_SOURCEPACKAGE ) )
isSource = 1 ;
break ;
case RPMRC_BADMAGIC :
Py_INCREF ( Py_None ) ;
h = ( hdrObject * ) Py_None ;
break ;
case RPMRC_FAIL :
case RPMRC_SHORTREAD :
default :
PyErr_SetString ( pyrpmError , " error reading package " ) ;
return NULL ;
}
return Py_BuildValue ( " (Ni) " , h, isSource) ;
}
/**
*/
PyObject * hdrLoad ( PyObject * self , PyObject * args ) {
char * obj , * copy = NULL ;
Header hdr ;
hdrObject * h ;
int len ;
if ( ! PyArg_ParseTuple ( args , " s# " , & obj , & len ) ) return NULL ;
/* malloc is needed to avoid surprises from data swab in headerLoad(). */
copy = malloc ( len ) ;
if ( copy = = NULL ) {
PyErr_SetString ( pyrpmError , " out of memory " ) ;
return NULL ;
}
memcpy ( copy , obj , len ) ;
hdr = headerLoad ( copy ) ;
if ( ! hdr ) {
PyErr_SetString ( pyrpmError , " bad header " ) ;
return NULL ;
}
headerAllocated ( hdr ) ;
compressFilelist ( hdr ) ;
providePackageNVR ( hdr ) ;
2008-02-22 21:07:07 +03:00
h = ( hdrObject * ) PyObject_New ( PyObject , & hdrType ) ;
2002-03-25 23:16:26 +03:00
h - > h = hdr ;
h - > sigs = NULL ;
h - > fileList = h - > linkList = h - > md5list = NULL ;
h - > uids = h - > gids = h - > mtimes = h - > fileSizes = NULL ;
h - > modes = h - > rdevs = NULL ;
return ( PyObject * ) h ;
}
/**
*/
PyObject * rhnLoad ( PyObject * self , PyObject * args ) {
char * obj , * copy = NULL ;
Header hdr ;
hdrObject * h ;
int len ;
if ( ! PyArg_ParseTuple ( args , " s# " , & obj , & len ) ) return NULL ;
/* malloc is needed to avoid surprises from data swab in headerLoad(). */
copy = malloc ( len ) ;
if ( copy = = NULL ) {
PyErr_SetString ( pyrpmError , " out of memory " ) ;
return NULL ;
}
memcpy ( copy , obj , len ) ;
hdr = headerLoad ( copy ) ;
if ( ! hdr ) {
PyErr_SetString ( pyrpmError , " bad header " ) ;
return NULL ;
}
headerAllocated ( hdr ) ;
/* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
if ( ! headerIsEntry ( hdr , RPMTAG_HEADERIMMUTABLE ) ) {
PyErr_SetString ( pyrpmError , " bad header, not immutable " ) ;
headerFree ( hdr ) ;
return NULL ;
}
/* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
if ( ! headerIsEntry ( hdr , RPMTAG_SHA1HEADER )
& & ! headerIsEntry ( hdr , RPMTAG_SHA1RHN ) ) {
PyErr_SetString ( pyrpmError , " bad header, no digest " ) ;
headerFree ( hdr ) ;
return NULL ;
}
if ( rpmVerifyDigest ( hdr ) ) {
PyErr_SetString ( pyrpmError , " bad header, digest check failed " ) ;
headerFree ( hdr ) ;
return NULL ;
}
/* Retrofit a RHNPlatform: tag. */
if ( ! headerIsEntry ( hdr , RPMTAG_RHNPLATFORM ) ) {
const char * arch ;
int_32 at ;
if ( headerGetEntry ( hdr , RPMTAG_ARCH , & at , ( void * * ) & arch , NULL ) )
headerAddEntry ( hdr , RPMTAG_RHNPLATFORM , at , arch , 1 ) ;
}
h = createHeaderObject ( hdr ) ;
return ( PyObject * ) h ;
}
/**
*/
PyObject * rpmReadHeaders ( FD_t fd ) {
PyObject * list ;
Header header ;
hdrObject * h ;
if ( ! fd ) {
PyErr_SetFromErrno ( pyrpmError ) ;
return NULL ;
}
list = PyList_New ( 0 ) ;
Py_BEGIN_ALLOW_THREADS
header = headerRead ( fd , HEADER_MAGIC_YES ) ;
Py_END_ALLOW_THREADS
while ( header ) {
compressFilelist ( header ) ;
providePackageNVR ( header ) ;
2008-02-22 21:07:07 +03:00
h = ( hdrObject * ) PyObject_New ( PyObject , & hdrType ) ;
2002-03-25 23:16:26 +03:00
h - > h = header ;
h - > sigs = NULL ;
h - > fileList = h - > linkList = h - > md5list = NULL ;
h - > uids = h - > gids = h - > mtimes = h - > fileSizes = NULL ;
h - > modes = h - > rdevs = NULL ;
if ( PyList_Append ( list , ( PyObject * ) h ) ) {
Py_DECREF ( list ) ;
Py_DECREF ( h ) ;
return NULL ;
}
Py_DECREF ( h ) ;
Py_BEGIN_ALLOW_THREADS
header = headerRead ( fd , HEADER_MAGIC_YES ) ;
Py_END_ALLOW_THREADS
}
return list ;
}
/**
*/
PyObject * rpmHeaderFromFD ( PyObject * self , PyObject * args ) {
FD_t fd ;
int fileno ;
PyObject * list ;
if ( ! PyArg_ParseTuple ( args , " i " , & fileno ) ) return NULL ;
fd = fdDup ( fileno ) ;
list = rpmReadHeaders ( fd ) ;
Fclose ( fd ) ;
return list ;
}
/**
*/
PyObject * rpmHeaderFromFile ( PyObject * self , PyObject * args ) {
char * filespec ;
FD_t fd ;
PyObject * list ;
if ( ! PyArg_ParseTuple ( args , " s " , & filespec ) ) return NULL ;
fd = Fopen ( filespec , " r.fdio " ) ;
if ( ! fd ) {
PyErr_SetFromErrno ( pyrpmError ) ;
return NULL ;
}
list = rpmReadHeaders ( fd ) ;
Fclose ( fd ) ;
return list ;
}
/**
* This assumes the order of list matches the order of the new headers , and
* throws an exception if that isn ' t true .
*/
int rpmMergeHeaders ( PyObject * list , FD_t fd , int matchTag ) {
Header newH ;
HeaderIterator iter ;
int_32 * newMatch , * oldMatch ;
hdrObject * ho ;
int count = 0 ;
int type , c , tag ;
void * p ;
Py_BEGIN_ALLOW_THREADS
newH = headerRead ( fd , HEADER_MAGIC_YES ) ;
Py_END_ALLOW_THREADS
while ( newH ) {
if ( ! headerGetEntry ( newH , matchTag , NULL , ( void * * ) & newMatch , NULL ) ) {
PyErr_SetString ( pyrpmError , " match tag missing in new header " ) ;
return 1 ;
}
ho = ( hdrObject * ) PyList_GetItem ( list , count + + ) ;
if ( ! ho ) return 1 ;
if ( ! headerGetEntry ( ho - > h , matchTag , NULL , ( void * * ) & oldMatch , NULL ) ) {
PyErr_SetString ( pyrpmError , " match tag missing in new header " ) ;
return 1 ;
}
if ( * newMatch ! = * oldMatch ) {
PyErr_SetString ( pyrpmError , " match tag mismatch " ) ;
return 1 ;
}
if ( ho - > sigs ) headerFree ( ho - > sigs ) ;
2008-02-22 21:07:07 +03:00
free ( ho - > md5list ) ;
free ( ho - > fileList ) ;
free ( ho - > linkList ) ;
2002-03-25 23:16:26 +03:00
ho - > sigs = NULL ;
ho - > md5list = NULL ;
ho - > fileList = NULL ;
ho - > linkList = NULL ;
iter = headerInitIterator ( newH ) ;
while ( headerNextIterator ( iter , & tag , & type , ( void * ) & p , & c ) ) {
/* could be dupes */
headerRemoveEntry ( ho - > h , tag ) ;
headerAddEntry ( ho - > h , tag , type , p , c ) ;
headerFreeData ( p , type ) ;
}
headerFreeIterator ( iter ) ;
Py_BEGIN_ALLOW_THREADS
newH = headerRead ( fd , HEADER_MAGIC_YES ) ;
Py_END_ALLOW_THREADS
}
return 0 ;
}
PyObject * rpmMergeHeadersFromFD ( PyObject * self , PyObject * args ) {
FD_t fd ;
int fileno ;
PyObject * list ;
int rc ;
int matchTag ;
if ( ! PyArg_ParseTuple ( args , " Oii " , & list , & fileno , & matchTag ) ) return NULL ;
if ( ! PyList_Check ( list ) ) {
PyErr_SetString ( PyExc_TypeError , " first parameter must be a list " ) ;
return NULL ;
}
fd = fdDup ( fileno ) ;
rc = rpmMergeHeaders ( list , fd , matchTag ) ;
Fclose ( fd ) ;
if ( rc ) {
return NULL ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
/**
*/
PyObject * versionCompare ( PyObject * self , PyObject * args ) {
hdrObject * h1 , * h2 ;
if ( ! PyArg_ParseTuple ( args , " O!O! " , & hdrType , & h1 , & hdrType , & h2 ) ) return NULL ;
return Py_BuildValue ( " i " , rpmVersionCompare ( h1 - > h , h2 - > h ) ) ;
}
/**
*/
PyObject * labelCompare ( PyObject * self , PyObject * args ) {
char * v1 , * r1 , * e1 , * v2 , * r2 , * e2 ;
int rc ;
if ( ! PyArg_ParseTuple ( args , " (zzz)(zzz) " ,
& e1 , & v1 , & r1 ,
& e2 , & v2 , & r2 ) ) return NULL ;
if ( e1 & & ! e2 )
return Py_BuildValue ( " i " , 1 ) ;
else if ( ! e1 & & e2 )
return Py_BuildValue ( " i " , - 1 ) ;
else if ( e1 & & e2 ) {
int ep1 , ep2 ;
ep1 = atoi ( e1 ) ;
ep2 = atoi ( e2 ) ;
if ( ep1 < ep2 )
return Py_BuildValue ( " i " , - 1 ) ;
else if ( ep1 > ep2 )
return Py_BuildValue ( " i " , 1 ) ;
}
rc = rpmvercmp ( v1 , v2 ) ;
if ( rc )
return Py_BuildValue ( " i " , rc ) ;
return Py_BuildValue ( " i " , rpmvercmp ( r1 , r2 ) ) ;
}