00001
00005 #include "system.h"
00006
00007 #include <glob.h>
00008 #include <dirent.h>
00009 #include <rpmio_internal.h>
00010
00011 #include <rpmlib.h>
00012
00013 #include "header-py.h"
00014 #include "rpmfd-py.h"
00015
00016 #include "debug.h"
00017
00018
00019
00020
00021 static int _rpmfd_debug = 1;
00022
00031 typedef struct FDlist_t FDlist;
00032
00035 struct FDlist_t {
00036 FILE * f;
00037 FD_t fd;
00038 const char * note;
00039 FDlist * next;
00040 } ;
00041
00044 static FDlist *fdhead = NULL;
00045
00048 static FDlist *fdtail = NULL;
00049
00052 static int closeCallback(FILE * f)
00053
00054
00055 {
00056 FDlist *node, *last;
00057
00058 node = fdhead;
00059 last = NULL;
00060 while (node) {
00061 if (node->f == f)
00062 break;
00063 last = node;
00064 node = node->next;
00065 }
00066
00067 if (node) {
00068 if (last)
00069 last->next = node->next;
00070 else
00071 fdhead = node->next;
00072 node->note = _free (node->note);
00073 node->fd = fdLink(node->fd, "closeCallback");
00074 (void) Fclose (node->fd);
00075 while (node->fd)
00076 node->fd = fdFree(node->fd, "closeCallback");
00077 node = _free (node);
00078 }
00079
00080 return 0;
00081 }
00082
00089
00090 static PyObject *
00091 rpmfd_Debug( rpmfdObject * s, PyObject * args, PyObject * kwds)
00092
00093
00094 {
00095 char * kwlist[] = {"debugLevel", NULL};
00096
00097 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmfd_debug))
00098 return NULL;
00099
00100 Py_INCREF(Py_None);
00101 return Py_None;
00102 }
00103
00106
00107 static PyObject *
00108 rpmfd_Fopen( PyObject * s, PyObject * args, PyObject * kwds)
00109
00110
00111 {
00112 char * path;
00113 char * mode = "r";
00114 FDlist *node;
00115 char * kwlist[] = {"path", "mode", NULL};
00116
00117 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &path, &mode))
00118 return NULL;
00119
00120 node = xmalloc (sizeof(FDlist));
00121
00122 node->fd = Fopen(path, mode);
00123 node->fd = fdLink(node->fd, "doFopen");
00124 node->note = xstrdup (path);
00125
00126 if (!node->fd) {
00127 (void) PyErr_SetFromErrno(pyrpmError);
00128 node = _free (node);
00129 return NULL;
00130 }
00131
00132 if (Ferror(node->fd)) {
00133 const char *err = Fstrerror(node->fd);
00134 node = _free(node);
00135 if (err)
00136 PyErr_SetString(pyrpmError, err);
00137 return NULL;
00138 }
00139
00140 node->f = fdGetFp(node->fd);
00141 if (!node->f) {
00142 PyErr_SetString(pyrpmError, "FD_t has no FILE*");
00143 free(node);
00144 return NULL;
00145 }
00146
00147 node->next = NULL;
00148
00149 if (!fdhead) {
00150 fdhead = fdtail = node;
00151 } else if (fdtail) {
00152 fdtail->next = node;
00153 } else {
00154 fdhead = node;
00155 }
00156
00157 fdtail = node;
00158
00159 return PyFile_FromFile (node->f, path, mode, closeCallback);
00160 }
00161
00166
00167
00168 static struct PyMethodDef rpmfd_methods[] = {
00169 {"Debug", (PyCFunction)rpmfd_Debug, METH_VARARGS|METH_KEYWORDS,
00170 NULL},
00171 {"Fopen", (PyCFunction)rpmfd_Fopen, METH_VARARGS|METH_KEYWORDS,
00172 NULL},
00173 {NULL, NULL}
00174 };
00175
00176
00177
00178
00181 static void
00182 rpmfd_dealloc( rpmfdObject * s)
00183
00184 {
00185 if (s) {
00186 Fclose(s->fd);
00187 s->fd = NULL;
00188 PyObject_Del(s);
00189 }
00190 }
00191
00192 static PyObject * rpmfd_getattro(PyObject * o, PyObject * n)
00193
00194 {
00195 return PyObject_GenericGetAttr(o, n);
00196 }
00197
00198 static int rpmfd_setattro(PyObject * o, PyObject * n, PyObject * v)
00199
00200 {
00201 return PyObject_GenericSetAttr(o, n, v);
00202 }
00203
00206 static int rpmfd_init(rpmfdObject * s, PyObject *args, PyObject *kwds)
00207
00208 {
00209 char * path;
00210 char * mode = "r";
00211 char * kwlist[] = {"path", "mode", NULL};
00212
00213 if (_rpmfd_debug)
00214 fprintf(stderr, "*** rpmfd_init(%p,%p,%p)\n", s, args, kwds);
00215
00216 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s:rpmfd_init", kwlist,
00217 &path, &mode))
00218 return -1;
00219
00220 s->fd = Fopen(path, mode);
00221
00222 if (s->fd == NULL) {
00223 (void) PyErr_SetFromErrno(pyrpmError);
00224 return -1;
00225 }
00226
00227 if (Ferror(s->fd)) {
00228 const char *err = Fstrerror(s->fd);
00229 if (s->fd)
00230 Fclose(s->fd);
00231 if (err)
00232 PyErr_SetString(pyrpmError, err);
00233 return -1;
00234 }
00235 return 0;
00236 }
00237
00240 static void rpmfd_free( rpmfdObject * s)
00241
00242 {
00243 if (_rpmfd_debug)
00244 fprintf(stderr, "%p -- fd %p\n", s, s->fd);
00245 if (s->fd)
00246 Fclose(s->fd);
00247
00248 PyObject_Del((PyObject *)s);
00249 }
00250
00253 static PyObject * rpmfd_alloc(PyTypeObject * subtype, int nitems)
00254
00255 {
00256 PyObject * s = PyType_GenericAlloc(subtype, nitems);
00257
00258 if (_rpmfd_debug)
00259 fprintf(stderr, "*** rpmfd_alloc(%p,%d) ret %p\n", subtype, nitems, s);
00260 return s;
00261 }
00262
00265
00266 static rpmfdObject * rpmfd_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
00267
00268 {
00269 rpmfdObject * s = PyObject_New(rpmfdObject, subtype);
00270
00271
00272 if (rpmfd_init(s, args, kwds) < 0) {
00273 rpmfd_free(s);
00274 return NULL;
00275 }
00276
00277 if (_rpmfd_debug)
00278 fprintf(stderr, "%p ++ fd %p\n", s, s->fd);
00279
00280 return s;
00281 }
00282
00285
00286 static char rpmfd_doc[] =
00287 "";
00288
00291
00292 PyTypeObject rpmfd_Type = {
00293 PyObject_HEAD_INIT(&PyType_Type)
00294 0,
00295 "rpm.fd",
00296 sizeof(rpmfdObject),
00297 0,
00298
00299 (destructor) rpmfd_dealloc,
00300 0,
00301 (getattrfunc)0,
00302 (setattrfunc)0,
00303 (cmpfunc)0,
00304 (reprfunc)0,
00305 0,
00306 0,
00307 0,
00308 (hashfunc)0,
00309 (ternaryfunc)0,
00310 (reprfunc)0,
00311 (getattrofunc) rpmfd_getattro,
00312 (setattrofunc) rpmfd_setattro,
00313 0,
00314 Py_TPFLAGS_DEFAULT,
00315 rpmfd_doc,
00316 #if Py_TPFLAGS_HAVE_ITER
00317 0,
00318 0,
00319 0,
00320 0,
00321 0,
00322 0,
00323 rpmfd_methods,
00324 0,
00325 0,
00326 0,
00327 0,
00328 0,
00329 0,
00330 0,
00331 (initproc) rpmfd_init,
00332 (allocfunc) rpmfd_alloc,
00333 (newfunc) rpmfd_new,
00334 rpmfd_free,
00335 0,
00336 #endif
00337 };
00338
00339
00340 rpmfdObject * rpmfd_Wrap(FD_t fd)
00341 {
00342 rpmfdObject *s = PyObject_New(rpmfdObject, &rpmfd_Type);
00343 if (s == NULL)
00344 return NULL;
00345 s->fd = fd;
00346 return s;
00347 }