00001
00005 #include "system.h"
00006
00007 #include "Python.h"
00008 #ifdef __LCLINT__
00009 #undef PyObject_HEAD
00010 #define PyObject_HEAD int _PyObjectHead;
00011 #endif
00012
00013 #include <glob.h>
00014 #include <dirent.h>
00015 #include <rpmio_internal.h>
00016
00017 #include <rpmlib.h>
00018
00019 #include "header-py.h"
00020 #include "rpmfd-py.h"
00021
00022 #include "debug.h"
00023
00024
00025
00026
00027 static int _rpmfd_debug = 1;
00028
00035 static PyObject *
00036 rpmfd_Debug( rpmfdObject * s, PyObject * args)
00037
00038
00039 {
00040 if (!PyArg_ParseTuple(args, "i", &_rpmfd_debug)) return NULL;
00041 Py_INCREF(Py_None);
00042 return Py_None;
00043 }
00044
00047 typedef struct FDlist_t FDlist;
00048
00051 struct FDlist_t {
00052 FILE * f;
00053 FD_t fd;
00054 const char * note;
00055 FDlist * next;
00056 } ;
00057
00060 static FDlist *fdhead = NULL;
00061
00064 static FDlist *fdtail = NULL;
00065
00068 static int closeCallback(FILE * f)
00069
00070
00071 {
00072 FDlist *node, *last;
00073
00074 node = fdhead;
00075 last = NULL;
00076 while (node) {
00077 if (node->f == f)
00078 break;
00079 last = node;
00080 node = node->next;
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 return 0;
00095 }
00096
00099 static PyObject *
00100 rpmfd_Fopen( PyObject * s, PyObject * args)
00101
00102
00103 {
00104 char * path;
00105 char * mode = "r.ufdio";
00106 FDlist *node;
00107
00108 if (!PyArg_ParseTuple(args, "s|s", &path, &mode))
00109 return NULL;
00110
00111 node = xmalloc (sizeof(FDlist));
00112
00113 node->fd = Fopen(path, mode);
00114 node->fd = fdLink(node->fd, "doFopen");
00115 node->note = xstrdup (path);
00116
00117 if (!node->fd) {
00118 PyErr_SetFromErrno(pyrpmError);
00119 node = _free (node);
00120 return NULL;
00121 }
00122
00123 if (Ferror(node->fd)) {
00124 const char *err = Fstrerror(node->fd);
00125 node = _free(node);
00126 if (err)
00127 PyErr_SetString(pyrpmError, err);
00128 return NULL;
00129 }
00130
00131 node->f = fdGetFp(node->fd);
00132 if (!node->f) {
00133 PyErr_SetString(pyrpmError, "FD_t has no FILE*");
00134 free(node);
00135 return NULL;
00136 }
00137
00138 node->next = NULL;
00139 if (!fdhead) {
00140 fdhead = fdtail = node;
00141 } else if (fdtail) {
00142 fdtail->next = node;
00143 } else {
00144 fdhead = node;
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
00181 static PyObject * rpmfd_getattr(rpmfdObject * o, char * name)
00182
00183 {
00184 return Py_FindMethod(rpmfd_methods, (PyObject *) o, name);
00185 }
00186
00189 static int rpmfd_init(rpmfdObject * s, PyObject *args, PyObject *kwds)
00190
00191 {
00192 char * path;
00193 char * mode = "r.ufdio";
00194
00195 if (_rpmfd_debug)
00196 fprintf(stderr, "*** rpmfd_init(%p,%p,%p)\n", s, args, kwds);
00197
00198 if (!PyArg_ParseTuple(args, "s|s:rpmfd_init", &path, &mode))
00199 return -1;
00200
00201 s->fd = Fopen(path, mode);
00202
00203 if (s->fd == NULL) {
00204 PyErr_SetFromErrno(pyrpmError);
00205 return -1;
00206 }
00207
00208 if (Ferror(s->fd)) {
00209 const char *err = Fstrerror(s->fd);
00210 if (s->fd)
00211 Fclose(s->fd);
00212 if (err)
00213 PyErr_SetString(pyrpmError, err);
00214 return -1;
00215 }
00216 return 0;
00217 }
00218
00221 static void rpmfd_free( rpmfdObject * s)
00222
00223 {
00224 if (_rpmfd_debug)
00225 fprintf(stderr, "%p -- fd %p\n", s, s->fd);
00226 if (s->fd)
00227 Fclose(s->fd);
00228
00229 PyObject_Del((PyObject *)s);
00230 }
00231
00234 static PyObject * rpmfd_alloc(PyTypeObject * subtype, int nitems)
00235
00236 {
00237 PyObject * s = PyType_GenericAlloc(subtype, nitems);
00238
00239 if (_rpmfd_debug)
00240 fprintf(stderr, "*** rpmfd_alloc(%p,%d) ret %p\n", subtype, nitems, s);
00241 return s;
00242 }
00243
00246 static rpmfdObject * rpmfd_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
00247
00248 {
00249 rpmfdObject * s = PyObject_New(rpmfdObject, subtype);
00250
00251
00252 if (rpmfd_init(s, args, kwds) < 0) {
00253 rpmfd_free(s);
00254 return NULL;
00255 }
00256
00257 if (_rpmfd_debug)
00258 fprintf(stderr, "%p ++ fd %p\n", s, s->fd);
00259
00260 return s;
00261 }
00262
00265
00266 static char rpmfd_doc[] =
00267 "";
00268
00271
00272 PyTypeObject rpmfd_Type = {
00273 PyObject_HEAD_INIT(&PyType_Type)
00274 0,
00275 "rpm.fd",
00276 sizeof(rpmfdObject),
00277 0,
00278
00279 (destructor) rpmfd_dealloc,
00280 0,
00281 (getattrfunc) rpmfd_getattr,
00282 (setattrfunc)0,
00283 (cmpfunc)0,
00284 (reprfunc)0,
00285 0,
00286 0,
00287 0,
00288 (hashfunc)0,
00289 (ternaryfunc)0,
00290 (reprfunc)0,
00291 0,
00292 0,
00293 0,
00294 Py_TPFLAGS_DEFAULT,
00295 rpmfd_doc,
00296 #if Py_TPFLAGS_HAVE_ITER
00297 0,
00298 0,
00299 0,
00300 0,
00301 0,
00302 0,
00303 rpmfd_methods,
00304 0,
00305 0,
00306 0,
00307 0,
00308 0,
00309 0,
00310 0,
00311 (initproc) rpmfd_init,
00312 (allocfunc) rpmfd_alloc,
00313 (newfunc) rpmfd_new,
00314 (destructor) rpmfd_free,
00315 0,
00316 #endif
00317 };
00318
00319
00320 rpmfdObject * rpmfd_Wrap(FD_t fd)
00321 {
00322 rpmfdObject *s = PyObject_New(rpmfdObject, &rpmfd_Type);
00323 if (s == NULL)
00324 return NULL;
00325 s->fd = fd;
00326 return s;
00327 }