2002-03-25 23:16:26 +03:00
/** \ingroup python
* \ file python / rpmmodule . c
*/
# include <alloca.h>
# include <errno.h>
# include <fcntl.h>
# include <time.h>
# include <sys/stat.h>
# include <sys/time.h>
# include <unistd.h>
# include <glob.h> /* XXX rpmio.h */
# include <dirent.h> /* XXX rpmio.h */
# include <locale.h>
# include <time.h>
# include "Python.h"
# include "rpmio_internal.h"
# include "rpmcli.h" /* XXX for rpmCheckSig */
# include "misc.h"
# include "header_internal.h"
# include "upgrade.h"
# include "db-py.h"
# include "header-py.h"
extern int _rpmio_debug ;
# ifdef __LCLINT__
# undef PyObject_HEAD
# define PyObject_HEAD int _PyObjectHead
# endif
void initrpm ( void ) ;
/* from lib/misc.c */
int rpmvercmp ( const char * one , const char * two ) ;
/** \ingroup python
*/
typedef struct rpmtransObject_s rpmtransObject ;
/** \ingroup python
* \ class header
* \ brief A python header object represents an RPM package header .
*
* All RPM packages have headers that provide metadata for the package .
* Header objects can be returned by database queries or loaded from a
* binary package on disk .
*
* The headerFromPackage function loads the package header from a
* package on disk . It returns a tuple of a " isSource " flag and the
* header object . The " isSource " flag is set to 1 if the package
* header was read from a source rpm or to 0 if the package header was
* read from a binary rpm .
*
* For example :
* \ code
* import os , rpm
*
* fd = os . open ( " /tmp/foo-1.0-1.i386.rpm " , os . O_RDONLY )
* ( header , isSource ) = rpm . headerFromPackage ( fd )
* fd . close ( )
* \ endcode
* The Python interface to the header data is quite elegant . It
* presents the data in a dictionary form . We ' ll take the header we
* just loaded and access the data within it :
* \ code
* print header [ rpm . RPMTAG_NAME ]
* print header [ rpm . RPMTAG_VERSION ]
* print header [ rpm . RPMTAG_RELEASE ]
* \ endcode
* in the case of our " foor-1.0-1.i386.rpm " package , this code would
* output :
\ verbatim
foo
1.0
1
\ endverbatim
* You make also access the header data by string name :
* \ code
* print header [ ' name ' ]
* \ endcode
* This method of access is a bit slower because the name must be
* translated into the tag number dynamically . You also must make sure
* the strings in header lookups don ' t get translated , or the lookups
* will fail .
*/
/** \ingroup python
* \ name Class : rpmtrans
* \ class rpmtrans
* \ brief A python rpmtrans object represents an RPM transaction set .
*
* The transaction set is the workhorse of RPM . It performs the
* installation and upgrade of packages . The rpmtrans object is
* instantiated by the TransactionSet function in the rpm module .
*
* The TransactionSet function takes two optional arguments . The first
* argument is the root path , the second is an open database to perform
* the transaction set upon .
*
* A rpmtrans object has the following methods :
*
* - add ( header , data , mode ) Add a binary package to a transaction set .
* @ param header the header to be added
* @ param data user data that will be passed to the transaction callback
* during transaction execution
* @ param mode optional argument that specifies if this package should
* be installed ( ' i ' ) , upgraded ( ' u ' ) , or if it is just
* available to the transaction when computing
* dependencies but no action should be performed with it
* ( ' a ' ) .
*
* - remove
*
* - depcheck ( ) Perform a dependency and conflict check on the
* transaction set . After headers have been added to a
* transaction set , a dependency check can be performed
* to make sure that all package dependencies are
* satisfied .
* @ return None If there are no unresolved dependencies
* Otherwise a list of complex tuples is returned , one tuple per
* unresolved dependency , with
* The format of the dependency tuple is :
* ( ( packageName , packageVersion , packageRelease ) ,
* ( reqName , reqVersion ) ,
* needsFlags ,
* suggestedPackage ,
* sense )
* packageName , packageVersion , packageRelease are the name ,
* version , and release of the package that has the unresolved
* dependency or conflict .
* The reqName and reqVersion are the name and version of the
* requirement or conflict .
* The needsFlags is a bitfield that describes the versioned
* nature of a requirement or conflict . The constants
* rpm . RPMDEP_SENSE_LESS , rpm . RPMDEP_SENSE_GREATER , and
* rpm . RPMDEP_SENSE_EQUAL can be logical ANDed with the needsFlags
* to get versioned dependency information .
* suggestedPackage is a tuple if the dependency check was aware
* of a package that solves this dependency problem when the
* dependency check was run . Packages that are added to the
* transaction set as " available " are examined during the
* dependency check as possible dependency solvers . The tuple
* contains two values , ( header , suggestedName ) . These are set to
* the header of the suggested package and its name , respectively .
* If there is no known package to solve the dependency problem ,
* suggestedPackage is None .
* The constants rpm . RPMDEP_SENSE_CONFLICTS and
* rpm . RPMDEP_SENSE_REQUIRES are set to show a dependency as a
* requirement or a conflict .
*
* - run ( flags , problemSetFilter , callback , data ) Attempt to execute a
* transaction set . After the transaction set has been populated
* with install and upgrade actions , it can be executed by invoking
* the run ( ) method .
* @ param flags - modifies the behavior of the transaction set as it is
* processed . The following values can be locical ORed
* together :
* - rpm . RPMTRANS_FLAG_TEST - test mode , do not modify the RPM
* database , change any files , or run any package scripts
* - rpm . RPMTRANS_FLAG_BUILD_PROBS - only build a list of
* problems encountered when attempting to run this transaction
* set
* - rpm . RPMTRANS_FLAG_NOSCRIPTS - do not execute package scripts
* - rpm . RPMTRANS_FLAG_JUSTDB - only make changes to the rpm
* database , do not modify files .
* - rpm . RPMTRANS_FLAG_NOTRIGGERS - do not run trigger scripts
* - rpm . RPMTRANS_FLAG_NODOCS - do not install files marked as % doc
* - rpm . RPMTRANS_FLAG_ALLFILES - create all files , even if a
* file is marked % config ( missingok ) and an upgrade is
* being performed .
* - rpm . RPMTRANS_FLAG_KEEPOBSOLETE - do not remove obsoleted
* packages .
* @ param problemSetFilter - control bit ( s ) to ignore classes of problems ,
* any of
* - rpm . RPMPROB_FILTER_IGNOREOS -
* - rpm . RPMPROB_FILTER_IGNOREARCH -
* - rpm . RPMPROB_FILTER_REPLACEPKG -
* - rpm . RPMPROB_FILTER_FORCERELOCATE -
* - rpm . RPMPROB_FILTER_REPLACENEWFILES -
* - rpm . RPMPROB_FILTER_REPLACEOLDFILES -
* - rpm . RPMPROB_FILTER_OLDPACKAGE -
* - rpm . RPMPROB_FILTER_DISKSPACE -
*/
/** \ingroup python
* \ name Class : rpmtrans
*/
/*@{*/
/** \ingroup python
*/
struct rpmtransObject_s {
PyObject_HEAD ;
rpmdbObject * dbo ;
rpmTransactionSet ts ;
PyObject * keyList ; /* keeps reference counts correct */
FD_t scriptFd ;
} ;
/** \ingroup python
*/
static PyObject * rpmtransAdd ( rpmtransObject * s , PyObject * args ) {
hdrObject * h ;
PyObject * key ;
char * how = NULL ;
int isUpgrade = 0 ;
PyObject * hObj ;
if ( ! PyArg_ParseTuple ( args , " OO|s " , & h , & key , & how ) ) return NULL ;
hObj = ( PyObject * ) h ;
if ( hObj - > ob_type ! = & hdrType ) {
PyErr_SetString ( PyExc_TypeError , " bad type for header argument " ) ;
return NULL ;
}
2009-09-30 16:11:11 +04:00
if ( how & & strcmp ( how , " u " ) & & strcmp ( how , " i " ) ) {
PyErr_SetString ( PyExc_TypeError , " how argument must be \" u \" or \" i \" " ) ;
2002-03-25 23:16:26 +03:00
return NULL ;
} else if ( how & & ! strcmp ( how , " u " ) )
isUpgrade = 1 ;
2009-09-30 16:11:11 +04:00
rpmtransAddPackage ( s - > ts , hdrGetHeader ( h ) , NULL , key , isUpgrade , NULL ) ;
2002-03-25 23:16:26 +03:00
/* This should increment the usage count for me */
2009-09-30 16:11:11 +04:00
if ( key )
2002-03-25 23:16:26 +03:00
PyList_Append ( s - > keyList , key ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
}
/** \ingroup python
*/
static PyObject * rpmtransRemove ( rpmtransObject * s , PyObject * args ) {
char * name ;
int count ;
rpmdbMatchIterator mi ;
if ( ! PyArg_ParseTuple ( args , " s " , & name ) )
return NULL ;
/* XXX: Copied hack from ../lib/rpminstall.c, rpmErase() */
mi = rpmdbInitIterator ( dbFromDb ( s - > dbo ) , RPMDBI_LABEL , name , 0 ) ;
count = rpmdbGetIteratorCount ( mi ) ;
if ( count < = 0 ) {
PyErr_SetString ( pyrpmError , " package not installed " ) ;
return NULL ;
} else { /* XXX: Note that we automatically choose to remove all matches */
Header h ;
while ( ( h = rpmdbNextIterator ( mi ) ) ! = NULL ) {
unsigned int recOffset = rpmdbGetIteratorOffset ( mi ) ;
if ( recOffset ) {
rpmtransRemovePackage ( s - > ts , recOffset ) ;
}
}
}
rpmdbFreeIterator ( mi ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
}
/** \ingroup python
*/
static PyObject * rpmtransDepCheck ( rpmtransObject * s , PyObject * args ) {
rpmDependencyConflict conflicts ;
int numConflicts ;
2009-09-30 16:11:11 +04:00
PyObject * list , * cf ;
2002-03-25 23:16:26 +03:00
int i , j ;
int allSuggestions = 0 ;
if ( ! PyArg_ParseTuple ( args , " |i " , & allSuggestions ) ) return NULL ;
rpmdepCheck ( s - > ts , & conflicts , & numConflicts ) ;
if ( numConflicts ) {
list = PyList_New ( 0 ) ;
for ( i = 0 ; i < numConflicts ; i + + ) {
cf = Py_BuildValue ( " ((sss)(ss)iOi) " , conflicts [ i ] . byName ,
conflicts [ i ] . byVersion , conflicts [ i ] . byRelease ,
conflicts [ i ] . needsName ,
conflicts [ i ] . needsVersion ,
conflicts [ i ] . needsFlags ,
2009-09-30 16:11:11 +04:00
/* suggestions */ Py_None ,
2002-03-25 23:16:26 +03:00
conflicts [ i ] . sense ) ;
PyList_Append ( list , ( PyObject * ) cf ) ;
Py_DECREF ( cf ) ;
}
conflicts = rpmdepFreeConflicts ( conflicts , numConflicts ) ;
return list ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
/** \ingroup python
*/
static PyObject * rpmtransOrder ( rpmtransObject * s , PyObject * args ) {
if ( ! PyArg_ParseTuple ( args , " " ) ) return NULL ;
rpmdepOrder ( s - > ts ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
}
/** \ingroup python
*/
static PyObject * py_rpmtransGetKeys ( rpmtransObject * s , PyObject * args ) {
const void * * data = NULL ;
int num , i ;
PyObject * tuple ;
rpmtransGetKeys ( s - > ts , & data , & num ) ;
2002-08-03 20:35:14 +04:00
if ( data = = NULL | | num < = 0 ) {
data = _free ( data ) ;
2002-03-25 23:16:26 +03:00
Py_INCREF ( Py_None ) ;
return Py_None ;
}
tuple = PyTuple_New ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
2002-08-03 20:35:14 +04:00
PyObject * obj ;
obj = ( data [ i ] ? ( PyObject * ) data [ i ] : Py_None ) ;
2002-03-25 23:16:26 +03:00
Py_INCREF ( obj ) ;
PyTuple_SetItem ( tuple , i , obj ) ;
}
2002-08-03 20:35:14 +04:00
data = _free ( data ) ;
2002-03-25 23:16:26 +03:00
return tuple ;
}
/** \ingroup python
*/
struct tsCallbackType {
PyObject * cb ;
PyObject * data ;
int pythonError ;
} ;
/** \ingroup python
* @ todo Remove , there ' s no headerLink refcount on the pointer .
*/
static Header transactionSetHeader = NULL ;
/** \ingroup python
*/
static void * tsCallback ( const void * hd , const rpmCallbackType what ,
const unsigned long amount , const unsigned long total ,
const void * pkgKey , rpmCallbackData data ) {
struct tsCallbackType * cbInfo = data ;
PyObject * args , * result ;
int fd ;
static FD_t fdt ;
const Header h = ( Header ) hd ;
if ( cbInfo - > pythonError ) return NULL ;
if ( cbInfo - > cb = = Py_None ) return NULL ;
if ( ! pkgKey ) pkgKey = Py_None ;
transactionSetHeader = h ;
args = Py_BuildValue ( " (illOO) " , what , amount , total , pkgKey , cbInfo - > data ) ;
result = PyEval_CallObject ( cbInfo - > cb , args ) ;
Py_DECREF ( args ) ;
if ( ! result ) {
cbInfo - > pythonError = 1 ;
return NULL ;
}
if ( what = = RPMCALLBACK_INST_OPEN_FILE ) {
if ( ! PyArg_Parse ( result , " i " , & fd ) ) {
cbInfo - > pythonError = 1 ;
return NULL ;
}
fdt = fdDup ( fd ) ;
Py_DECREF ( result ) ;
return fdt ;
}
if ( what = = RPMCALLBACK_INST_CLOSE_FILE ) {
Fclose ( fdt ) ;
}
Py_DECREF ( result ) ;
return NULL ;
}
/** \ingroup python
*/
static PyObject * rpmtransRun ( rpmtransObject * s , PyObject * args ) {
int flags , ignoreSet ;
int rc , i ;
PyObject * list , * prob ;
rpmProblemSet probs ;
struct tsCallbackType cbInfo ;
if ( ! PyArg_ParseTuple ( args , " iiOO " , & flags , & ignoreSet , & cbInfo . cb ,
& cbInfo . data ) )
return NULL ;
cbInfo . pythonError = 0 ;
rc = rpmRunTransactions ( s - > ts , tsCallback , & cbInfo , NULL , & probs , flags ,
ignoreSet ) ;
if ( cbInfo . pythonError ) {
if ( rc > 0 )
rpmProblemSetFree ( probs ) ;
return NULL ;
}
if ( rc < 0 ) {
list = PyList_New ( 0 ) ;
return list ;
} else if ( ! rc ) {
Py_INCREF ( Py_None ) ;
return Py_None ;
}
list = PyList_New ( 0 ) ;
for ( i = 0 ; i < probs - > numProblems ; i + + ) {
rpmProblem myprob = probs - > probs + i ;
2002-04-05 12:04:32 +04:00
prob = Py_BuildValue ( " s(isN) " , rpmProblemString ( myprob ) ,
2002-03-25 23:16:26 +03:00
myprob - > type ,
myprob - > str1 ,
2002-04-05 12:04:32 +04:00
PyLong_FromLongLong ( myprob - > ulong1 ) ) ;
2002-03-25 23:16:26 +03:00
PyList_Append ( list , prob ) ;
Py_DECREF ( prob ) ;
}
rpmProblemSetFree ( probs ) ;
return list ;
}
/** \ingroup python
*/
static struct PyMethodDef rpmtransMethods [ ] = {
{ " add " , ( PyCFunction ) rpmtransAdd , 1 } ,
{ " remove " , ( PyCFunction ) rpmtransRemove , 1 } ,
{ " depcheck " , ( PyCFunction ) rpmtransDepCheck , 1 } ,
{ " order " , ( PyCFunction ) rpmtransOrder , 1 } ,
{ " getKeys " , ( PyCFunction ) py_rpmtransGetKeys , 1 } ,
{ " run " , ( PyCFunction ) rpmtransRun , 1 } ,
{ NULL , NULL } /* sentinel */
} ;
/** \ingroup python
*/
static PyObject * rpmtransGetAttr ( rpmtransObject * o , char * name ) {
return Py_FindMethod ( rpmtransMethods , ( PyObject * ) o , name ) ;
}
/** \ingroup python
*/
static void rpmtransDealloc ( PyObject * o ) {
rpmtransObject * trans = ( void * ) o ;
rpmtransFree ( trans - > ts ) ;
if ( trans - > dbo ) {
Py_DECREF ( trans - > dbo ) ;
}
if ( trans - > scriptFd ) Fclose ( trans - > scriptFd ) ;
/* this will free the keyList, and decrement the ref count of all
the items on the list as well : - ) */
Py_DECREF ( trans - > keyList ) ;
2008-02-22 21:07:07 +03:00
PyObject_Del ( o ) ;
2002-03-25 23:16:26 +03:00
}
/** \ingroup python
*/
static int rpmtransSetAttr ( rpmtransObject * o , char * name ,
PyObject * val ) {
int i ;
if ( ! strcmp ( name , " scriptFd " ) ) {
if ( ! PyArg_Parse ( val , " i " , & i ) ) return 0 ;
if ( i < 0 ) {
PyErr_SetString ( PyExc_TypeError , " bad file descriptor " ) ;
return - 1 ;
} else {
o - > scriptFd = fdDup ( i ) ;
rpmtransSetScriptFd ( o - > ts , o - > scriptFd ) ;
}
} else {
PyErr_SetString ( PyExc_AttributeError , name ) ;
return - 1 ;
}
return 0 ;
}
/** \ingroup python
*/
static PyTypeObject rpmtransType = {
PyObject_HEAD_INIT ( NULL )
0 , /* ob_size */
" rpmtrans " , /* tp_name */
sizeof ( rpmtransObject ) , /* tp_size */
0 , /* tp_itemsize */
( destructor ) rpmtransDealloc , /* tp_dealloc */
0 , /* tp_print */
( getattrfunc ) rpmtransGetAttr , /* tp_getattr */
( setattrfunc ) rpmtransSetAttr , /* tp_setattr */
0 , /* tp_compare */
0 , /* tp_repr */
0 , /* tp_as_number */
0 , /* tp_as_sequence */
0 , /* tp_as_mapping */
} ;
/*@}*/
/** \ingroup python
* \ name Module : rpm
*/
/*@{*/
/**
*/
static PyObject * rpmtransCreate ( PyObject * self , PyObject * args ) {
rpmtransObject * o ;
rpmdbObject * db = NULL ;
char * rootPath = " / " ;
if ( ! PyArg_ParseTuple ( args , " |sO " , & rootPath , & db ) ) return NULL ;
if ( db & & ( ( PyObject * ) db ) - > ob_type ! = & rpmdbType ) {
PyErr_SetString ( PyExc_TypeError , " bad type for database argument " ) ;
return NULL ;
}
2008-02-22 21:07:07 +03:00
o = ( void * ) PyObject_New ( rpmtransObject , & rpmtransType ) ;
2002-03-25 23:16:26 +03:00
Py_XINCREF ( db ) ;
o - > dbo = db ;
o - > scriptFd = NULL ;
o - > ts = rpmtransCreateSet ( db ? dbFromDb ( db ) : NULL , rootPath ) ;
o - > keyList = PyList_New ( 0 ) ;
return ( void * ) o ;
}
/**
*/
static PyObject * doAddMacro ( PyObject * self , PyObject * args ) {
char * name , * val ;
if ( ! PyArg_ParseTuple ( args , " ss " , & name , & val ) )
return NULL ;
addMacro ( NULL , name , NULL , val , RMIL_DEFAULT ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
}
/**
*/
static PyObject * doDelMacro ( PyObject * self , PyObject * args ) {
char * name ;
if ( ! PyArg_ParseTuple ( args , " s " , & name ) )
return NULL ;
delMacro ( NULL , name ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
}
/**
*/
static PyObject * archScore ( PyObject * self , PyObject * args ) {
char * arch ;
int score ;
if ( ! PyArg_ParseTuple ( args , " s " , & arch ) )
return NULL ;
score = rpmMachineScore ( RPM_MACHTABLE_INSTARCH , arch ) ;
return Py_BuildValue ( " i " , score ) ;
}
/**
*/
static int psGetArchScore ( Header h ) {
void * pkgArch ;
int type , count ;
if ( ! headerGetEntry ( h , RPMTAG_ARCH , & type , ( void * * ) & pkgArch , & count ) | |
type = = RPM_INT8_TYPE )
return 150 ;
else
return rpmMachineScore ( RPM_MACHTABLE_INSTARCH , pkgArch ) ;
}
/**
*/
static int pkgCompareVer ( void * first , void * second ) {
struct packageInfo * * a = first ;
struct packageInfo * * b = second ;
int ret , score1 , score2 ;
/* put packages w/o names at the end */
if ( ! ( * a ) - > name ) return 1 ;
if ( ! ( * b ) - > name ) return - 1 ;
ret = xstrcasecmp ( ( * a ) - > name , ( * b ) - > name ) ;
if ( ret ) return ret ;
score1 = psGetArchScore ( ( * a ) - > h ) ;
if ( ! score1 ) return 1 ;
score2 = psGetArchScore ( ( * b ) - > h ) ;
if ( ! score2 ) return - 1 ;
if ( score1 < score2 ) return - 1 ;
if ( score1 > score2 ) return 1 ;
return rpmVersionCompare ( ( * b ) - > h , ( * a ) - > h ) ;
}
/**
*/
static void pkgSort ( struct pkgSet * psp ) {
int i ;
char * name ;
if ( psp - > numPackages < = 0 )
return ;
qsort ( psp - > packages , psp - > numPackages , sizeof ( * psp - > packages ) ,
( void * ) pkgCompareVer ) ;
name = psp - > packages [ 0 ] - > name ;
if ( ! name ) {
psp - > numPackages = 0 ;
return ;
}
for ( i = 1 ; i < psp - > numPackages ; i + + ) {
if ( ! psp - > packages [ i ] - > name ) break ;
if ( ! strcmp ( psp - > packages [ i ] - > name , name ) )
psp - > packages [ i ] - > name = NULL ;
else
name = psp - > packages [ i ] - > name ;
}
qsort ( psp - > packages , psp - > numPackages , sizeof ( * psp - > packages ) ,
( void * ) pkgCompareVer ) ;
for ( i = 0 ; i < psp - > numPackages ; i + + )
if ( ! psp - > packages [ i ] - > name ) break ;
psp - > numPackages = i ;
}
/**
*/
static PyObject * findUpgradeSet ( PyObject * self , PyObject * args ) {
PyObject * hdrList , * result ;
char * root = " / " ;
int i ;
struct pkgSet list ;
hdrObject * hdr ;
if ( ! PyArg_ParseTuple ( args , " O|s " , & hdrList , & root ) ) return NULL ;
if ( ! PyList_Check ( hdrList ) ) {
PyErr_SetString ( PyExc_TypeError , " list of headers expected " ) ;
return NULL ;
}
list . numPackages = PyList_Size ( hdrList ) ;
list . packages = alloca ( sizeof ( list . packages ) * list . numPackages ) ;
for ( i = 0 ; i < list . numPackages ; i + + ) {
hdr = ( hdrObject * ) PyList_GetItem ( hdrList , i ) ;
if ( ( ( PyObject * ) hdr ) - > ob_type ! = & hdrType ) {
PyErr_SetString ( PyExc_TypeError , " list of headers expected " ) ;
return NULL ;
}
list . packages [ i ] = alloca ( sizeof ( struct packageInfo ) ) ;
list . packages [ i ] - > h = hdrGetHeader ( hdr ) ;
list . packages [ i ] - > selected = 0 ;
list . packages [ i ] - > data = hdr ;
headerGetEntry ( list . packages [ i ] - > h , RPMTAG_NAME , NULL ,
( void * * ) & list . packages [ i ] - > name , NULL ) ;
}
pkgSort ( & list ) ;
if ( ugFindUpgradePackages ( & list , root ) ) {
PyErr_SetString ( pyrpmError , " error during upgrade check " ) ;
return NULL ;
}
result = PyList_New ( 0 ) ;
for ( i = 0 ; i < list . numPackages ; i + + ) {
if ( list . packages [ i ] - > selected ) {
PyList_Append ( result , list . packages [ i ] - > data ) ;
/* Py_DECREF(list.packages[i]->data); */
}
}
return result ;
}
/**
*/
static PyObject * rpmInitDB ( PyObject * self , PyObject * args ) {
char * root ;
int forWrite = 0 ;
if ( ! PyArg_ParseTuple ( args , " i|s " , & forWrite , & root ) ) return NULL ;
if ( rpmdbInit ( root , forWrite ? O_RDWR | O_CREAT : O_RDONLY ) ) {
char * errmsg = " cannot initialize database in %s " ;
char * errstr = NULL ;
int errsize ;
errsize = strlen ( errmsg ) + strlen ( root ) ;
errstr = alloca ( errsize ) ;
snprintf ( errstr , errsize , errmsg , root ) ;
PyErr_SetString ( pyrpmError , errstr ) ;
return NULL ;
}
Py_INCREF ( Py_None ) ;
return ( Py_None ) ;
}
/**
*/
static PyObject * errorCB = NULL , * errorData = NULL ;
/**
*/
static void errorcb ( void )
{
PyObject * result , * args = NULL ;
if ( errorData )
args = Py_BuildValue ( " (O) " , errorData ) ;
result = PyEval_CallObject ( errorCB , args ) ;
Py_XDECREF ( args ) ;
if ( result = = NULL ) {
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
}
Py_DECREF ( result ) ;
}
/**
*/
static PyObject * errorSetCallback ( PyObject * self , PyObject * args ) {
PyObject * newCB = NULL , * newData = NULL ;
if ( ! PyArg_ParseTuple ( args , " O|O " , & newCB , & newData ) ) return NULL ;
/* if we're getting a void*, set the error callback to this. */
/* also, we can possibly decref any python callbacks we had */
/* and set them to NULL. */
if ( PyCObject_Check ( newCB ) ) {
rpmErrorSetCallback ( PyCObject_AsVoidPtr ( newCB ) ) ;
Py_XDECREF ( errorCB ) ;
Py_XDECREF ( errorData ) ;
errorCB = NULL ;
errorData = NULL ;
Py_INCREF ( Py_None ) ;
return Py_None ;
}
if ( ! PyCallable_Check ( newCB ) ) {
PyErr_SetString ( PyExc_TypeError , " parameter must be callable " ) ;
return NULL ;
}
Py_XDECREF ( errorCB ) ;
Py_XDECREF ( errorData ) ;
errorCB = newCB ;
errorData = newData ;
Py_INCREF ( errorCB ) ;
Py_XINCREF ( errorData ) ;
return PyCObject_FromVoidPtr ( rpmErrorSetCallback ( errorcb ) , NULL ) ;
}
/**
*/
static PyObject * errorString ( PyObject * self , PyObject * args ) {
return PyString_FromString ( rpmErrorString ( ) ) ;
}
/**
*/
static PyObject * checkSig ( PyObject * self , PyObject * args ) {
char * filename ;
int flags ;
int rc = 255 ;
if ( PyArg_ParseTuple ( args , " si " , & filename , & flags ) ) {
const char * av [ 2 ] ;
av [ 0 ] = filename ;
av [ 1 ] = NULL ;
rc = rpmCheckSig ( flags , av ) ;
}
return Py_BuildValue ( " i " , rc ) ;
}
/* hack to get the current header that's in the transaction set */
/**
*/
static PyObject * getTsHeader ( PyObject * self , PyObject * args ) {
if ( ! PyArg_ParseTuple ( args , " " ) )
return NULL ;
if ( transactionSetHeader ) {
return ( PyObject * ) createHeaderObject ( transactionSetHeader ) ; ;
}
Py_INCREF ( Py_None ) ;
return ( PyObject * ) Py_None ;
}
static PyObject * setVerbosity ( PyObject * self , PyObject * args ) {
int level ;
if ( ! PyArg_ParseTuple ( args , " i " , & level ) )
return NULL ;
rpmSetVerbosity ( level ) ;
Py_INCREF ( Py_None ) ;
return ( PyObject * ) Py_None ;
}
/**
*/
static PyMethodDef rpmModuleMethods [ ] = {
{ " TransactionSet " , ( PyCFunction ) rpmtransCreate , METH_VARARGS , NULL } ,
{ " addMacro " , ( PyCFunction ) doAddMacro , METH_VARARGS , NULL } ,
{ " delMacro " , ( PyCFunction ) doDelMacro , METH_VARARGS , NULL } ,
{ " archscore " , ( PyCFunction ) archScore , METH_VARARGS , NULL } ,
{ " findUpgradeSet " , ( PyCFunction ) findUpgradeSet , METH_VARARGS , NULL } ,
{ " headerFromPackage " , ( PyCFunction ) rpmHeaderFromPackage , METH_VARARGS , NULL } ,
{ " headerLoad " , ( PyCFunction ) hdrLoad , METH_VARARGS , NULL } ,
{ " rhnLoad " , ( PyCFunction ) rhnLoad , METH_VARARGS , NULL } ,
{ " initdb " , ( PyCFunction ) rpmInitDB , METH_VARARGS , NULL } ,
{ " opendb " , ( PyCFunction ) rpmOpenDB , METH_VARARGS , NULL } ,
{ " rebuilddb " , ( PyCFunction ) rebuildDB , METH_VARARGS , NULL } ,
{ " mergeHeaderListFromFD " , ( PyCFunction ) rpmMergeHeadersFromFD , METH_VARARGS , NULL } ,
{ " readHeaderListFromFD " , ( PyCFunction ) rpmHeaderFromFD , METH_VARARGS , NULL } ,
{ " readHeaderListFromFile " , ( PyCFunction ) rpmHeaderFromFile , METH_VARARGS , NULL } ,
{ " errorSetCallback " , ( PyCFunction ) errorSetCallback , METH_VARARGS , NULL } ,
{ " errorString " , ( PyCFunction ) errorString , METH_VARARGS , NULL } ,
{ " versionCompare " , ( PyCFunction ) versionCompare , METH_VARARGS , NULL } ,
{ " labelCompare " , ( PyCFunction ) labelCompare , METH_VARARGS , NULL } ,
{ " checksig " , ( PyCFunction ) checkSig , METH_VARARGS , NULL } ,
{ " getTransactionCallbackHeader " , ( PyCFunction ) getTsHeader , METH_VARARGS , NULL } ,
{ " setVerbosity " , ( PyCFunction ) setVerbosity , METH_VARARGS , NULL } ,
{ NULL }
} ;
/**
*/
void initrpm ( void ) {
PyObject * m , * d , * o , * tag = NULL , * dict ;
int i ;
const struct headerSprintfExtension_s * extensions = rpmHeaderFormats ;
m = Py_InitModule ( " rpm " , rpmModuleMethods ) ;
hdrType . ob_type = & PyType_Type ;
rpmdbMIType . ob_type = & PyType_Type ;
rpmdbType . ob_type = & PyType_Type ;
rpmtransType . ob_type = & PyType_Type ;
if ( ! m )
return ;
/* _rpmio_debug = -1; */
rpmReadConfigFiles ( NULL , NULL ) ;
d = PyModule_GetDict ( m ) ;
pyrpmError = PyString_FromString ( " rpm.error " ) ;
PyDict_SetItemString ( d , " error " , pyrpmError ) ;
Py_DECREF ( pyrpmError ) ;
dict = PyDict_New ( ) ;
for ( i = 0 ; i < rpmTagTableSize ; i + + ) {
tag = PyInt_FromLong ( rpmTagTable [ i ] . val ) ;
PyDict_SetItemString ( d , ( char * ) rpmTagTable [ i ] . name , tag ) ;
Py_DECREF ( tag ) ;
PyDict_SetItem ( dict , tag , o = PyString_FromString ( rpmTagTable [ i ] . name + 7 ) ) ;
Py_DECREF ( o ) ;
}
while ( extensions - > name ) {
if ( extensions - > type = = HEADER_EXT_TAG ) {
2008-02-22 21:48:29 +03:00
const struct headerSprintfExtension_s * ext ;
2006-05-14 17:06:45 +04:00
ext = extensions ;
2002-03-25 23:16:26 +03:00
PyDict_SetItemString ( d , extensions - > name , o = PyCObject_FromVoidPtr ( ext , NULL ) ) ;
Py_DECREF ( o ) ;
PyDict_SetItem ( dict , tag , o = PyString_FromString ( ext - > name + 7 ) ) ;
Py_DECREF ( o ) ;
}
extensions + + ;
}
PyDict_SetItemString ( d , " tagnames " , dict ) ;
Py_DECREF ( dict ) ;
# define REGISTER_ENUM(val) \
PyDict_SetItemString ( d , # val , o = PyInt_FromLong ( val ) ) ; \
Py_DECREF ( o ) ;
REGISTER_ENUM ( RPMFILE_STATE_NORMAL ) ;
REGISTER_ENUM ( RPMFILE_STATE_REPLACED ) ;
REGISTER_ENUM ( RPMFILE_STATE_NOTINSTALLED ) ;
REGISTER_ENUM ( RPMFILE_STATE_NETSHARED ) ;
REGISTER_ENUM ( RPMFILE_CONFIG ) ;
REGISTER_ENUM ( RPMFILE_DOC ) ;
REGISTER_ENUM ( RPMFILE_MISSINGOK ) ;
REGISTER_ENUM ( RPMFILE_NOREPLACE ) ;
REGISTER_ENUM ( RPMFILE_GHOST ) ;
REGISTER_ENUM ( RPMFILE_LICENSE ) ;
REGISTER_ENUM ( RPMFILE_README ) ;
REGISTER_ENUM ( RPMDEP_SENSE_REQUIRES ) ;
REGISTER_ENUM ( RPMDEP_SENSE_CONFLICTS ) ;
REGISTER_ENUM ( RPMSENSE_SERIAL ) ;
REGISTER_ENUM ( RPMSENSE_LESS ) ;
REGISTER_ENUM ( RPMSENSE_GREATER ) ;
REGISTER_ENUM ( RPMSENSE_EQUAL ) ;
REGISTER_ENUM ( RPMSENSE_PREREQ ) ;
REGISTER_ENUM ( RPMSENSE_INTERP ) ;
REGISTER_ENUM ( RPMSENSE_SCRIPT_PRE ) ;
REGISTER_ENUM ( RPMSENSE_SCRIPT_POST ) ;
REGISTER_ENUM ( RPMSENSE_SCRIPT_PREUN ) ;
REGISTER_ENUM ( RPMSENSE_SCRIPT_POSTUN ) ;
REGISTER_ENUM ( RPMSENSE_SCRIPT_VERIFY ) ;
REGISTER_ENUM ( RPMSENSE_FIND_REQUIRES ) ;
REGISTER_ENUM ( RPMSENSE_FIND_PROVIDES ) ;
REGISTER_ENUM ( RPMSENSE_TRIGGERIN ) ;
REGISTER_ENUM ( RPMSENSE_TRIGGERUN ) ;
REGISTER_ENUM ( RPMSENSE_TRIGGERPOSTUN ) ;
REGISTER_ENUM ( RPMSENSE_SCRIPT_PREP ) ;
REGISTER_ENUM ( RPMSENSE_SCRIPT_BUILD ) ;
REGISTER_ENUM ( RPMSENSE_SCRIPT_INSTALL ) ;
REGISTER_ENUM ( RPMSENSE_SCRIPT_CLEAN ) ;
REGISTER_ENUM ( RPMSENSE_RPMLIB ) ;
REGISTER_ENUM ( RPMSENSE_TRIGGERPREIN ) ;
REGISTER_ENUM ( RPMTRANS_FLAG_TEST ) ;
REGISTER_ENUM ( RPMTRANS_FLAG_BUILD_PROBS ) ;
REGISTER_ENUM ( RPMTRANS_FLAG_NOSCRIPTS ) ;
REGISTER_ENUM ( RPMTRANS_FLAG_JUSTDB ) ;
REGISTER_ENUM ( RPMTRANS_FLAG_NOTRIGGERS ) ;
REGISTER_ENUM ( RPMTRANS_FLAG_NODOCS ) ;
REGISTER_ENUM ( RPMTRANS_FLAG_ALLFILES ) ;
REGISTER_ENUM ( RPMTRANS_FLAG_KEEPOBSOLETE ) ;
2010-03-31 19:36:41 +04:00
REGISTER_ENUM ( RPMTRANS_FLAG_NOCONTEXTS ) ;
2002-03-25 23:16:26 +03:00
REGISTER_ENUM ( RPMPROB_FILTER_IGNOREOS ) ;
REGISTER_ENUM ( RPMPROB_FILTER_IGNOREARCH ) ;
REGISTER_ENUM ( RPMPROB_FILTER_REPLACEPKG ) ;
REGISTER_ENUM ( RPMPROB_FILTER_FORCERELOCATE ) ;
REGISTER_ENUM ( RPMPROB_FILTER_REPLACENEWFILES ) ;
REGISTER_ENUM ( RPMPROB_FILTER_REPLACEOLDFILES ) ;
REGISTER_ENUM ( RPMPROB_FILTER_OLDPACKAGE ) ;
REGISTER_ENUM ( RPMPROB_FILTER_DISKSPACE ) ;
REGISTER_ENUM ( RPMPROB_FILTER_DISKNODES ) ;
REGISTER_ENUM ( RPMCALLBACK_INST_PROGRESS ) ;
REGISTER_ENUM ( RPMCALLBACK_INST_START ) ;
REGISTER_ENUM ( RPMCALLBACK_INST_OPEN_FILE ) ;
REGISTER_ENUM ( RPMCALLBACK_INST_CLOSE_FILE ) ;
REGISTER_ENUM ( RPMCALLBACK_TRANS_PROGRESS ) ;
REGISTER_ENUM ( RPMCALLBACK_TRANS_START ) ;
REGISTER_ENUM ( RPMCALLBACK_TRANS_STOP ) ;
REGISTER_ENUM ( RPMCALLBACK_UNINST_PROGRESS ) ;
REGISTER_ENUM ( RPMCALLBACK_UNINST_START ) ;
REGISTER_ENUM ( RPMCALLBACK_UNINST_STOP ) ;
REGISTER_ENUM ( RPMCALLBACK_UNPACK_ERROR ) ;
REGISTER_ENUM ( RPMCALLBACK_CPIO_ERROR ) ;
REGISTER_ENUM ( RPMPROB_BADARCH ) ;
REGISTER_ENUM ( RPMPROB_BADOS ) ;
REGISTER_ENUM ( RPMPROB_PKG_INSTALLED ) ;
REGISTER_ENUM ( RPMPROB_BADRELOCATE ) ;
REGISTER_ENUM ( RPMPROB_REQUIRES ) ;
REGISTER_ENUM ( RPMPROB_CONFLICT ) ;
REGISTER_ENUM ( RPMPROB_NEW_FILE_CONFLICT ) ;
REGISTER_ENUM ( RPMPROB_FILE_CONFLICT ) ;
REGISTER_ENUM ( RPMPROB_OLDPACKAGE ) ;
REGISTER_ENUM ( RPMPROB_DISKSPACE ) ;
REGISTER_ENUM ( RPMPROB_DISKNODES ) ;
REGISTER_ENUM ( RPMPROB_BADPRETRANS ) ;
REGISTER_ENUM ( CHECKSIG_PGP ) ;
REGISTER_ENUM ( CHECKSIG_GPG ) ;
REGISTER_ENUM ( CHECKSIG_MD5 ) ;
REGISTER_ENUM ( RPMLOG_EMERG ) ;
REGISTER_ENUM ( RPMLOG_ALERT ) ;
REGISTER_ENUM ( RPMLOG_CRIT ) ;
REGISTER_ENUM ( RPMLOG_ERR ) ;
REGISTER_ENUM ( RPMLOG_WARNING ) ;
REGISTER_ENUM ( RPMLOG_NOTICE ) ;
REGISTER_ENUM ( RPMLOG_INFO ) ;
REGISTER_ENUM ( RPMLOG_DEBUG ) ;
REGISTER_ENUM ( RPMMIRE_DEFAULT ) ;
REGISTER_ENUM ( RPMMIRE_STRCMP ) ;
REGISTER_ENUM ( RPMMIRE_REGEX ) ;
REGISTER_ENUM ( RPMMIRE_GLOB ) ;
}
/*@}*/