rpm  5.2.1
python/rpmfd-py.c
Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include <glob.h>       /* XXX rpmio.h */
00008 #include <dirent.h>     /* XXX rpmio.h */
00009 #include <rpmio_internal.h>
00010 #include <rpmcb.h>              /* XXX fnpyKey */
00011 #include <rpmtypes.h>
00012 #include <rpmtag.h>
00013 
00014 #include "header-py.h"  /* XXX pyrpmError */
00015 #include "rpmfd-py.h"
00016 
00017 #include "debug.h"
00018 
00019 /*@access FD_t @*/
00020 
00021 /*@unchecked@*/
00022 static int _rpmfd_debug = 1;
00023 
00032 typedef struct FDlist_t FDlist;
00033 
00036 struct FDlist_t {
00037     FILE * f;
00038     FD_t fd;
00039     const char * note;
00040     FDlist * next;
00041 } ;
00042 
00045 static FDlist *fdhead = NULL;
00046 
00049 static FDlist *fdtail = NULL;
00050 
00053 static int closeCallback(FILE * f)
00054         /*@globals fdhead @*/
00055         /*@modifies fdhead @*/
00056 {
00057     FDlist *node, *last;
00058 
00059     node = fdhead;
00060     last = NULL;
00061     while (node) {
00062         if (node->f == f)
00063             break;
00064         last = node;
00065         node = node->next;
00066     }
00067 /*@-branchstate@*/
00068     if (node) {
00069         if (last)
00070             last->next = node->next;
00071         else
00072             fdhead = node->next;
00073         node->note = _free (node->note);
00074         node->fd = fdLink(node->fd, "closeCallback");
00075         (void) Fclose (node->fd);
00076         while (node->fd)
00077             node->fd = fdFree(node->fd, "closeCallback");
00078         node = _free (node);
00079     }
00080 /*@=branchstate@*/
00081     return 0;
00082 }
00083 
00090 /*@null@*/
00091 static PyObject *
00092 rpmfd_Debug(/*@unused@*/ rpmfdObject * s, PyObject * args,
00093                 PyObject * kwds)
00094         /*@globals _Py_NoneStruct @*/
00095         /*@modifies _Py_NoneStruct @*/
00096 {
00097     char * kwlist[] = {"debugLevel", NULL};
00098 
00099     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmfd_debug))
00100         return NULL;
00101 
00102     Py_INCREF(Py_None);
00103     return Py_None;
00104 }
00105 
00108 /*@null@*/
00109 static PyObject *
00110 rpmfd_Fopen(/*@unused@*/ PyObject * s, PyObject * args, PyObject * kwds)
00111         /*@globals fdhead, fdtail @*/
00112         /*@modifies fdhead, fdtail @*/
00113 {
00114     char * path;
00115     char * mode = "r.fdio";
00116     FDlist *node;
00117     char * kwlist[] = {"path", "mode", NULL};
00118 
00119     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &path, &mode))
00120         return NULL;
00121 
00122     node = xmalloc (sizeof(FDlist));
00123 
00124     node->fd = Fopen(path, mode);
00125     node->fd = fdLink(node->fd, "doFopen");
00126     node->note = xstrdup (path);
00127 
00128     if (!node->fd) {
00129         (void) PyErr_SetFromErrno(pyrpmError);
00130         node = _free (node);
00131         return NULL;
00132     }
00133 
00134     if (Ferror(node->fd)) {
00135         const char *err = Fstrerror(node->fd);
00136         node = _free(node);
00137         if (err)
00138             PyErr_SetString(pyrpmError, err);
00139         return NULL;
00140     }
00141 
00142     node->f = fdGetFp(node->fd);
00143     if (!node->f) {
00144         PyErr_SetString(pyrpmError, "FD_t has no FILE*");
00145         free(node);
00146         return NULL;
00147     }
00148 
00149     node->next = NULL;
00150 /*@-branchstate@*/
00151     if (!fdhead) {
00152         fdhead = fdtail = node;
00153     } else if (fdtail) {
00154         fdtail->next = node;
00155     } else {
00156         fdhead = node;
00157     }
00158 /*@=branchstate@*/
00159     fdtail = node;
00160 
00161     return PyFile_FromFile (node->f, path, mode, closeCallback);
00162 }
00163 
00168 /*@-fullinitblock@*/
00169 /*@unchecked@*/ /*@observer@*/
00170 static struct PyMethodDef rpmfd_methods[] = {
00171     {"Debug",   (PyCFunction)rpmfd_Debug,       METH_VARARGS|METH_KEYWORDS,
00172         NULL},
00173     {"Fopen",   (PyCFunction)rpmfd_Fopen,       METH_VARARGS|METH_KEYWORDS,
00174         NULL},
00175     {NULL,              NULL}           /* sentinel */
00176 };
00177 /*@=fullinitblock@*/
00178 
00179 /* ---------- */
00180 
00183 static void
00184 rpmfd_dealloc(/*@only@*/ /*@null@*/ rpmfdObject * s)
00185         /*@modifies s @*/
00186 {
00187     if (s) {
00188         Fclose(s->fd);
00189         s->fd = NULL;
00190         PyObject_Del(s);
00191     }
00192 }
00193 
00194 static PyObject * rpmfd_getattro(PyObject * o, PyObject * n)
00195         /*@*/
00196 {
00197     return PyObject_GenericGetAttr(o, n);
00198 }
00199 
00200 static int rpmfd_setattro(PyObject * o, PyObject * n, PyObject * v)
00201         /*@*/
00202 {
00203     return PyObject_GenericSetAttr(o, n, v);
00204 }
00205 
00208 static int rpmfd_init(rpmfdObject * s, PyObject *args, PyObject *kwds)
00209         /*@modifies s @*/
00210 {
00211     char * path;
00212     char * mode = "r";
00213     char * kwlist[] = {"path", "mode", NULL};
00214 
00215 if (_rpmfd_debug)
00216 fprintf(stderr, "*** rpmfd_init(%p,%p,%p)\n", s, args, kwds);
00217 
00218     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s:rpmfd_init", kwlist,
00219             &path, &mode))
00220         return -1;
00221 
00222     s->fd = Fopen(path, mode);
00223 
00224     if (s->fd == NULL) {
00225         (void) PyErr_SetFromErrno(pyrpmError);
00226         return -1;
00227     }
00228 
00229     if (Ferror(s->fd)) {
00230         const char *err = Fstrerror(s->fd);
00231         if (s->fd)
00232             Fclose(s->fd);
00233         if (err)
00234             PyErr_SetString(pyrpmError, err);
00235         return -1;
00236     }
00237     return 0;
00238 }
00239 
00242 static void rpmfd_free(/*@only@*/ rpmfdObject * s)
00243         /*@modifies s @*/
00244 {
00245 if (_rpmfd_debug)
00246 fprintf(stderr, "%p -- fd %p\n", s, s->fd);
00247     if (s->fd)
00248         Fclose(s->fd);
00249 
00250     PyObject_Del((PyObject *)s);
00251 }
00252 
00255 static PyObject * rpmfd_alloc(PyTypeObject * subtype, int nitems)
00256         /*@*/
00257 {
00258     PyObject * s = PyType_GenericAlloc(subtype, nitems);
00259 
00260 if (_rpmfd_debug)
00261 fprintf(stderr, "*** rpmfd_alloc(%p,%d) ret %p\n", subtype, nitems, s);
00262     return s;
00263 }
00264 
00267 /*@null@*/
00268 static rpmfdObject * rpmfd_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
00269         /*@*/
00270 {
00271     rpmfdObject * s = PyObject_New(rpmfdObject, subtype);
00272 
00273     /* Perform additional initialization. */
00274     if (rpmfd_init(s, args, kwds) < 0) {
00275         rpmfd_free(s);
00276         return NULL;
00277     }
00278 
00279 if (_rpmfd_debug)
00280 fprintf(stderr, "%p ++ fd %p\n", s, s->fd);
00281 
00282     return s;
00283 }
00284 
00287 /*@unchecked@*/ /*@observer@*/
00288 static char rpmfd_doc[] =
00289 "";
00290 
00293 /*@-fullinitblock@*/
00294 PyTypeObject rpmfd_Type = {
00295         PyObject_HEAD_INIT(&PyType_Type)
00296         0,                              /* ob_size */
00297         "rpm.fd",                       /* tp_name */
00298         sizeof(rpmfdObject),            /* tp_size */
00299         0,                              /* tp_itemsize */
00300         /* methods */
00301         (destructor) rpmfd_dealloc,     /* tp_dealloc */
00302         0,                              /* tp_print */
00303         (getattrfunc)0,                 /* tp_getattr */
00304         (setattrfunc)0,                 /* tp_setattr */
00305         (cmpfunc)0,                     /* tp_compare */
00306         (reprfunc)0,                    /* tp_repr */
00307         0,                              /* tp_as_number */
00308         0,                              /* tp_as_sequence */
00309         0,                              /* tp_as_mapping */
00310         (hashfunc)0,                    /* tp_hash */
00311         (ternaryfunc)0,                 /* tp_call */
00312         (reprfunc)0,                    /* tp_str */
00313         (getattrofunc) rpmfd_getattro,  /* tp_getattro */
00314         (setattrofunc) rpmfd_setattro,  /* tp_setattro */
00315         0,                              /* tp_as_buffer */
00316         Py_TPFLAGS_DEFAULT,             /* tp_flags */
00317         rpmfd_doc,                      /* tp_doc */
00318 #if Py_TPFLAGS_HAVE_ITER
00319         0,                              /* tp_traverse */
00320         0,                              /* tp_clear */
00321         0,                              /* tp_richcompare */
00322         0,                              /* tp_weaklistoffset */
00323         0,                              /* tp_iter */
00324         0,                              /* tp_iternext */
00325         rpmfd_methods,                  /* tp_methods */
00326         0,                              /* tp_members */
00327         0,                              /* tp_getset */
00328         0,                              /* tp_base */
00329         0,                              /* tp_dict */
00330         0,                              /* tp_descr_get */
00331         0,                              /* tp_descr_set */
00332         0,                              /* tp_dictoffset */
00333         (initproc) rpmfd_init,          /* tp_init */
00334         (allocfunc) rpmfd_alloc,        /* tp_alloc */
00335         (newfunc) rpmfd_new,            /* tp_new */
00336         (freefunc) rpmfd_free,          /* tp_free */
00337         0,                              /* tp_is_gc */
00338 #endif
00339 };
00340 /*@=fullinitblock@*/
00341 
00342 rpmfdObject * rpmfd_Wrap(FD_t fd)
00343 {
00344     rpmfdObject *s = PyObject_New(rpmfdObject, &rpmfd_Type);
00345     if (s == NULL)
00346         return NULL;
00347     s->fd = fd;
00348     return s;
00349 }