00001
00005 #include "system.h"
00006
00007 #include <glob.h>
00008 #include <dirent.h>
00009 #include <rpmio_internal.h>
00010 #include <rpmcb.h>
00011 #include <rpmtypes.h>
00012 #include <rpmtag.h>
00013
00014 #include "header-py.h"
00015 #include "rpmfd-py.h"
00016
00017 #include "debug.h"
00018
00019
00020
00021
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
00055
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
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
00081 return 0;
00082 }
00083
00090
00091 static PyObject *
00092 rpmfd_Debug( rpmfdObject * s, PyObject * args,
00093 PyObject * kwds)
00094
00095
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
00109 static PyObject *
00110 rpmfd_Fopen( PyObject * s, PyObject * args, PyObject * kwds)
00111
00112
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
00151 if (!fdhead) {
00152 fdhead = fdtail = node;
00153 } else if (fdtail) {
00154 fdtail->next = node;
00155 } else {
00156 fdhead = node;
00157 }
00158
00159 fdtail = node;
00160
00161 return PyFile_FromFile (node->f, path, mode, closeCallback);
00162 }
00163
00168
00169
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}
00176 };
00177
00178
00179
00180
00183 static void
00184 rpmfd_dealloc( rpmfdObject * s)
00185
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
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( rpmfdObject * s)
00243
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
00268 static rpmfdObject * rpmfd_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
00269
00270 {
00271 rpmfdObject * s = PyObject_New(rpmfdObject, subtype);
00272
00273
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
00288 static char rpmfd_doc[] =
00289 "";
00290
00293
00294 PyTypeObject rpmfd_Type = {
00295 PyObject_HEAD_INIT(&PyType_Type)
00296 0,
00297 "rpm.fd",
00298 sizeof(rpmfdObject),
00299 0,
00300
00301 (destructor) rpmfd_dealloc,
00302 0,
00303 (getattrfunc)0,
00304 (setattrfunc)0,
00305 (cmpfunc)0,
00306 (reprfunc)0,
00307 0,
00308 0,
00309 0,
00310 (hashfunc)0,
00311 (ternaryfunc)0,
00312 (reprfunc)0,
00313 (getattrofunc) rpmfd_getattro,
00314 (setattrofunc) rpmfd_setattro,
00315 0,
00316 Py_TPFLAGS_DEFAULT,
00317 rpmfd_doc,
00318 #if Py_TPFLAGS_HAVE_ITER
00319 0,
00320 0,
00321 0,
00322 0,
00323 0,
00324 0,
00325 rpmfd_methods,
00326 0,
00327 0,
00328 0,
00329 0,
00330 0,
00331 0,
00332 0,
00333 (initproc) rpmfd_init,
00334 (allocfunc) rpmfd_alloc,
00335 (newfunc) rpmfd_new,
00336 (freefunc) rpmfd_free,
00337 0,
00338 #endif
00339 };
00340
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 }