00001
00005 #include "system.h"
00006
00007 #include <glob.h>
00008 #include <dirent.h>
00009 #include <rpmio_internal.h>
00010 #include <rpmcb.h>
00011
00012 #include <rpmlib.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, PyObject * kwds)
00093
00094
00095 {
00096 char * kwlist[] = {"debugLevel", NULL};
00097
00098 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmfd_debug))
00099 return NULL;
00100
00101 Py_INCREF(Py_None);
00102 return Py_None;
00103 }
00104
00107
00108 static PyObject *
00109 rpmfd_Fopen( PyObject * s, PyObject * args, PyObject * kwds)
00110
00111
00112 {
00113 char * path;
00114 char * mode = "r.fdio";
00115 FDlist *node;
00116 char * kwlist[] = {"path", "mode", NULL};
00117
00118 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &path, &mode))
00119 return NULL;
00120
00121 node = xmalloc (sizeof(FDlist));
00122
00123 node->fd = Fopen(path, mode);
00124 node->fd = fdLink(node->fd, "doFopen");
00125 node->note = xstrdup (path);
00126
00127 if (!node->fd) {
00128 (void) PyErr_SetFromErrno(pyrpmError);
00129 node = _free (node);
00130 return NULL;
00131 }
00132
00133 if (Ferror(node->fd)) {
00134 const char *err = Fstrerror(node->fd);
00135 node = _free(node);
00136 if (err)
00137 PyErr_SetString(pyrpmError, err);
00138 return NULL;
00139 }
00140
00141 node->f = fdGetFp(node->fd);
00142 if (!node->f) {
00143 PyErr_SetString(pyrpmError, "FD_t has no FILE*");
00144 free(node);
00145 return NULL;
00146 }
00147
00148 node->next = NULL;
00149
00150 if (!fdhead) {
00151 fdhead = fdtail = node;
00152 } else if (fdtail) {
00153 fdtail->next = node;
00154 } else {
00155 fdhead = node;
00156 }
00157
00158 fdtail = node;
00159
00160 return PyFile_FromFile (node->f, path, mode, closeCallback);
00161 }
00162
00167
00168
00169 static struct PyMethodDef rpmfd_methods[] = {
00170 {"Debug", (PyCFunction)rpmfd_Debug, METH_VARARGS|METH_KEYWORDS,
00171 NULL},
00172 {"Fopen", (PyCFunction)rpmfd_Fopen, METH_VARARGS|METH_KEYWORDS,
00173 NULL},
00174 {NULL, NULL}
00175 };
00176
00177
00178
00179
00182 static void
00183 rpmfd_dealloc( rpmfdObject * s)
00184
00185 {
00186 if (s) {
00187 Fclose(s->fd);
00188 s->fd = NULL;
00189 PyObject_Del(s);
00190 }
00191 }
00192
00193 static PyObject * rpmfd_getattro(PyObject * o, PyObject * n)
00194
00195 {
00196 return PyObject_GenericGetAttr(o, n);
00197 }
00198
00199 static int rpmfd_setattro(PyObject * o, PyObject * n, PyObject * v)
00200
00201 {
00202 return PyObject_GenericSetAttr(o, n, v);
00203 }
00204
00207 static int rpmfd_init(rpmfdObject * s, PyObject *args, PyObject *kwds)
00208
00209 {
00210 char * path;
00211 char * mode = "r";
00212 char * kwlist[] = {"path", "mode", NULL};
00213
00214 if (_rpmfd_debug)
00215 fprintf(stderr, "*** rpmfd_init(%p,%p,%p)\n", s, args, kwds);
00216
00217 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s:rpmfd_init", kwlist,
00218 &path, &mode))
00219 return -1;
00220
00221 s->fd = Fopen(path, mode);
00222
00223 if (s->fd == NULL) {
00224 (void) PyErr_SetFromErrno(pyrpmError);
00225 return -1;
00226 }
00227
00228 if (Ferror(s->fd)) {
00229 const char *err = Fstrerror(s->fd);
00230 if (s->fd)
00231 Fclose(s->fd);
00232 if (err)
00233 PyErr_SetString(pyrpmError, err);
00234 return -1;
00235 }
00236 return 0;
00237 }
00238
00241 static void rpmfd_free( rpmfdObject * s)
00242
00243 {
00244 if (_rpmfd_debug)
00245 fprintf(stderr, "%p -- fd %p\n", s, s->fd);
00246 if (s->fd)
00247 Fclose(s->fd);
00248
00249 PyObject_Del((PyObject *)s);
00250 }
00251
00254 static PyObject * rpmfd_alloc(PyTypeObject * subtype, int nitems)
00255
00256 {
00257 PyObject * s = PyType_GenericAlloc(subtype, nitems);
00258
00259 if (_rpmfd_debug)
00260 fprintf(stderr, "*** rpmfd_alloc(%p,%d) ret %p\n", subtype, nitems, s);
00261 return s;
00262 }
00263
00266
00267 static rpmfdObject * rpmfd_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
00268
00269 {
00270 rpmfdObject * s = PyObject_New(rpmfdObject, subtype);
00271
00272
00273 if (rpmfd_init(s, args, kwds) < 0) {
00274 rpmfd_free(s);
00275 return NULL;
00276 }
00277
00278 if (_rpmfd_debug)
00279 fprintf(stderr, "%p ++ fd %p\n", s, s->fd);
00280
00281 return s;
00282 }
00283
00286
00287 static char rpmfd_doc[] =
00288 "";
00289
00292
00293 PyTypeObject rpmfd_Type = {
00294 PyObject_HEAD_INIT(&PyType_Type)
00295 0,
00296 "rpm.fd",
00297 sizeof(rpmfdObject),
00298 0,
00299
00300 (destructor) rpmfd_dealloc,
00301 0,
00302 (getattrfunc)0,
00303 (setattrfunc)0,
00304 (cmpfunc)0,
00305 (reprfunc)0,
00306 0,
00307 0,
00308 0,
00309 (hashfunc)0,
00310 (ternaryfunc)0,
00311 (reprfunc)0,
00312 (getattrofunc) rpmfd_getattro,
00313 (setattrofunc) rpmfd_setattro,
00314 0,
00315 Py_TPFLAGS_DEFAULT,
00316 rpmfd_doc,
00317 #if Py_TPFLAGS_HAVE_ITER
00318 0,
00319 0,
00320 0,
00321 0,
00322 0,
00323 0,
00324 rpmfd_methods,
00325 0,
00326 0,
00327 0,
00328 0,
00329 0,
00330 0,
00331 0,
00332 (initproc) rpmfd_init,
00333 (allocfunc) rpmfd_alloc,
00334 (newfunc) rpmfd_new,
00335 (freefunc) rpmfd_free,
00336 0,
00337 #endif
00338 };
00339
00340
00341 rpmfdObject * rpmfd_Wrap(FD_t fd)
00342 {
00343 rpmfdObject *s = PyObject_New(rpmfdObject, &rpmfd_Type);
00344 if (s == NULL)
00345 return NULL;
00346 s->fd = fd;
00347 return s;
00348 }