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