rpm/python/rpmfd-py.c

236 lines
4.6 KiB
C

/** \ingroup python
* \file python/rpmfd-py.c
*/
#include "system.h"
#include "Python.h"
#ifdef __LCLINT__
#undef PyObject_HEAD
#define PyObject_HEAD int _PyObjectHead;
#endif
#include <glob.h> /* XXX rpmio.h */
#include <dirent.h> /* XXX rpmio.h */
#include <rpmio_internal.h>
#include <rpmlib.h> /* XXX _free */
#include "header-py.h" /* XXX pyrpmError */
#include "rpmfd-py.h"
#include "debug.h"
/*@access FD_t @*/
extern int _rpmio_debug;
/** \ingroup python
* \name Class: Rpmfd
* \class Rpmfd
* \brief An python rpm.fd object represents an rpm I/O handle.
*/
static PyObject *
rpmfd_Debug(/*@unused@*/ rpmfdObject * s, PyObject * args)
/*@globals _Py_NoneStruct @*/
/*@modifies _Py_NoneStruct @*/
{
if (!PyArg_ParseTuple(args, "i", &_rpmio_debug)) return NULL;
Py_INCREF(Py_None);
return Py_None;
}
/**
*/
typedef struct FDlist_t FDlist;
/**
*/
struct FDlist_t {
FILE * f;
FD_t fd;
const char * note;
FDlist * next;
} ;
/**
*/
static FDlist *fdhead = NULL;
/**
*/
static FDlist *fdtail = NULL;
/**
*/
static int closeCallback(FILE * f)
/*@globals fdhead @*/
/*@modifies fdhead @*/
{
FDlist *node, *last;
node = fdhead;
last = NULL;
while (node) {
if (node->f == f)
break;
last = node;
node = node->next;
}
if (node) {
if (last)
last->next = node->next;
else
fdhead = node->next;
node->note = _free (node->note);
node->fd = fdLink(node->fd, "closeCallback");
Fclose (node->fd);
while (node->fd)
node->fd = fdFree(node->fd, "closeCallback");
node = _free (node);
}
return 0;
}
/**
*/
static PyObject *
rpmfd_Fopen(/*@unused@*/ PyObject * self, PyObject * args)
/*@globals fdhead, fdtail @*/
/*@modifies fdhead, fdtail @*/
{
char * path, * mode;
FDlist *node;
if (!PyArg_ParseTuple(args, "ss", &path, &mode))
return NULL;
node = xmalloc (sizeof(FDlist));
node->fd = Fopen(path, mode);
node->fd = fdLink(node->fd, "doFopen");
node->note = xstrdup (path);
if (!node->fd) {
PyErr_SetFromErrno(pyrpmError);
node = _free (node);
return NULL;
}
if (Ferror(node->fd)) {
const char *err = Fstrerror(node->fd);
node = _free(node);
if (err) {
PyErr_SetString(pyrpmError, err);
return NULL;
}
}
node->f = fdGetFp(node->fd);
if (!node->f) {
PyErr_SetString(pyrpmError, "FD_t has no FILE*");
free(node);
return NULL;
}
node->next = NULL;
if (!fdhead) {
fdhead = fdtail = node;
} else if (fdtail) {
fdtail->next = node;
} else {
fdhead = node;
}
fdtail = node;
return PyFile_FromFile (node->f, path, mode, closeCallback);
}
/** \ingroup python
*/
/*@-fullinitblock@*/
/*@unchecked@*/ /*@observer@*/
static struct PyMethodDef rpmfd_methods[] = {
{"Debug", (PyCFunction)rpmfd_Debug, METH_VARARGS,
NULL},
{"Fopen", (PyCFunction)rpmfd_Fopen, METH_VARARGS,
NULL},
{NULL, NULL} /* sentinel */
};
/*@=fullinitblock@*/
/* ---------- */
/** \ingroup python
*/
static PyObject * rpmfd_getattr(rpmfdObject * o, char * name)
/*@*/
{
return Py_FindMethod(rpmfd_methods, (PyObject *) o, name);
}
/**
*/
/*@unchecked@*/ /*@observer@*/
static char rpmfd_doc[] =
"";
/** \ingroup python
*/
/*@-fullinitblock@*/
PyTypeObject rpmfd_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0, /* ob_size */
"rpm.fd", /* tp_name */
sizeof(rpmfdObject), /* tp_size */
0, /* tp_itemsize */
(destructor)0, /* tp_dealloc */
0, /* tp_print */
(getattrfunc) rpmfd_getattr, /* tp_getattr */
(setattrfunc)0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
rpmfd_doc, /* tp_doc */
#if Py_TPFLAGS_HAVE_ITER
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
rpmfd_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
#endif
};
/*@=fullinitblock@*/
rpmfdObject * rpmfd_Wrap(FD_t fd)
{
rpmfdObject *s = PyObject_NEW(rpmfdObject, &rpmfd_Type);
if (s == NULL)
return NULL;
s->fd = fd;
return s;
}