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
00029
00030 static PyObject *
00031 rpmfd_Debug( rpmfdObject * s, PyObject * args, PyObject * kwds)
00032
00033
00034 {
00035 char * kwlist[] = {"debugLevel", NULL};
00036
00037 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmfd_debug))
00038 return NULL;
00039
00040 Py_INCREF(Py_None);
00041 return Py_None;
00042 }
00043
00046 typedef struct FDlist_t FDlist;
00047
00050 struct FDlist_t {
00051 FILE * f;
00052 FD_t fd;
00053 const char * note;
00054 FDlist * next;
00055 } ;
00056
00059 static FDlist *fdhead = NULL;
00060
00063 static FDlist *fdtail = NULL;
00064
00067 static int closeCallback(FILE * f)
00068
00069
00070 {
00071 FDlist *node, *last;
00072
00073 node = fdhead;
00074 last = NULL;
00075 while (node) {
00076 if (node->f == f)
00077 break;
00078 last = node;
00079 node = node->next;
00080 }
00081
00082 if (node) {
00083 if (last)
00084 last->next = node->next;
00085 else
00086 fdhead = node->next;
00087 node->note = _free (node->note);
00088 node->fd = fdLink(node->fd, "closeCallback");
00089 (void) Fclose (node->fd);
00090 while (node->fd)
00091 node->fd = fdFree(node->fd, "closeCallback");
00092 node = _free (node);
00093 }
00094
00095 return 0;
00096 }
00097
00100
00101 static PyObject *
00102 rpmfd_Fopen( PyObject * s, PyObject * args, PyObject * kwds)
00103
00104
00105 {
00106 char * path;
00107 char * mode = "r.ufdio";
00108 FDlist *node;
00109 char * kwlist[] = {"path", "mode", NULL};
00110
00111 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &path, &mode))
00112 return NULL;
00113
00114 node = xmalloc (sizeof(FDlist));
00115
00116 node->fd = Fopen(path, mode);
00117 node->fd = fdLink(node->fd, "doFopen");
00118 node->note = xstrdup (path);
00119
00120 if (!node->fd) {
00121 (void) PyErr_SetFromErrno(pyrpmError);
00122 node = _free (node);
00123 return NULL;
00124 }
00125
00126 if (Ferror(node->fd)) {
00127 const char *err = Fstrerror(node->fd);
00128 node = _free(node);
00129 if (err)
00130 PyErr_SetString(pyrpmError, err);
00131 return NULL;
00132 }
00133
00134 node->f = fdGetFp(node->fd);
00135 if (!node->f) {
00136 PyErr_SetString(pyrpmError, "FD_t has no FILE*");
00137 free(node);
00138 return NULL;
00139 }
00140
00141 node->next = NULL;
00142
00143 if (!fdhead) {
00144 fdhead = fdtail = node;
00145 } else if (fdtail) {
00146 fdtail->next = node;
00147 } else {
00148 fdhead = node;
00149 }
00150
00151 fdtail = node;
00152
00153 return PyFile_FromFile (node->f, path, mode, closeCallback);
00154 }
00155
00158
00159
00160 static struct PyMethodDef rpmfd_methods[] = {
00161 {"Debug", (PyCFunction)rpmfd_Debug, METH_VARARGS|METH_KEYWORDS,
00162 NULL},
00163 {"Fopen", (PyCFunction)rpmfd_Fopen, METH_VARARGS|METH_KEYWORDS,
00164 NULL},
00165 {NULL, NULL}
00166 };
00167
00168
00169
00170
00173 static void
00174 rpmfd_dealloc( rpmfdObject * s)
00175
00176 {
00177 if (s) {
00178 Fclose(s->fd);
00179 s->fd = NULL;
00180 PyObject_Del(s);
00181 }
00182 }
00183
00184 static PyObject * rpmfd_getattro(PyObject * o, PyObject * n)
00185
00186 {
00187 return PyObject_GenericGetAttr(o, n);
00188 }
00189
00190 static int rpmfd_setattro(PyObject * o, PyObject * n, PyObject * v)
00191
00192 {
00193 return PyObject_GenericSetAttr(o, n, v);
00194 }
00195
00198 static int rpmfd_init(rpmfdObject * s, PyObject *args, PyObject *kwds)
00199
00200 {
00201 char * path;
00202 char * mode = "r.ufdio";
00203 char * kwlist[] = {"path", "mode", NULL};
00204
00205 if (_rpmfd_debug)
00206 fprintf(stderr, "*** rpmfd_init(%p,%p,%p)\n", s, args, kwds);
00207
00208 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s:rpmfd_init", kwlist,
00209 &path, &mode))
00210 return -1;
00211
00212 s->fd = Fopen(path, mode);
00213
00214 if (s->fd == NULL) {
00215 (void) PyErr_SetFromErrno(pyrpmError);
00216 return -1;
00217 }
00218
00219 if (Ferror(s->fd)) {
00220 const char *err = Fstrerror(s->fd);
00221 if (s->fd)
00222 Fclose(s->fd);
00223 if (err)
00224 PyErr_SetString(pyrpmError, err);
00225 return -1;
00226 }
00227 return 0;
00228 }
00229
00232 static void rpmfd_free( rpmfdObject * s)
00233
00234 {
00235 if (_rpmfd_debug)
00236 fprintf(stderr, "%p -- fd %p\n", s, s->fd);
00237 if (s->fd)
00238 Fclose(s->fd);
00239
00240 PyObject_Del((PyObject *)s);
00241 }
00242
00245 static PyObject * rpmfd_alloc(PyTypeObject * subtype, int nitems)
00246
00247 {
00248 PyObject * s = PyType_GenericAlloc(subtype, nitems);
00249
00250 if (_rpmfd_debug)
00251 fprintf(stderr, "*** rpmfd_alloc(%p,%d) ret %p\n", subtype, nitems, s);
00252 return s;
00253 }
00254
00257
00258 static rpmfdObject * rpmfd_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
00259
00260 {
00261 rpmfdObject * s = PyObject_New(rpmfdObject, subtype);
00262
00263
00264 if (rpmfd_init(s, args, kwds) < 0) {
00265 rpmfd_free(s);
00266 return NULL;
00267 }
00268
00269 if (_rpmfd_debug)
00270 fprintf(stderr, "%p ++ fd %p\n", s, s->fd);
00271
00272 return s;
00273 }
00274
00277
00278 static char rpmfd_doc[] =
00279 "";
00280
00283
00284 PyTypeObject rpmfd_Type = {
00285 PyObject_HEAD_INIT(&PyType_Type)
00286 0,
00287 "rpm.fd",
00288 sizeof(rpmfdObject),
00289 0,
00290
00291 (destructor) rpmfd_dealloc,
00292 0,
00293 (getattrfunc)0,
00294 (setattrfunc)0,
00295 (cmpfunc)0,
00296 (reprfunc)0,
00297 0,
00298 0,
00299 0,
00300 (hashfunc)0,
00301 (ternaryfunc)0,
00302 (reprfunc)0,
00303 (getattrofunc) rpmfd_getattro,
00304 (setattrofunc) rpmfd_setattro,
00305 0,
00306 Py_TPFLAGS_DEFAULT,
00307 rpmfd_doc,
00308 #if Py_TPFLAGS_HAVE_ITER
00309 0,
00310 0,
00311 0,
00312 0,
00313 0,
00314 0,
00315 rpmfd_methods,
00316 0,
00317 0,
00318 0,
00319 0,
00320 0,
00321 0,
00322 0,
00323 (initproc) rpmfd_init,
00324 (allocfunc) rpmfd_alloc,
00325 (newfunc) rpmfd_new,
00326 rpmfd_free,
00327 0,
00328 #endif
00329 };
00330
00331
00332 rpmfdObject * rpmfd_Wrap(FD_t fd)
00333 {
00334 rpmfdObject *s = PyObject_New(rpmfdObject, &rpmfd_Type);
00335 if (s == NULL)
00336 return NULL;
00337 s->fd = fd;
00338 return s;
00339 }