rpm
4.5
|
00001 00005 #include "system.h" 00006 00007 #include <glob.h> /* XXX rpmio.h */ 00008 #include <dirent.h> /* XXX rpmio.h */ 00009 #include <rpmio_internal.h> 00010 00011 #include <rpmlib.h> /* XXX _free */ 00012 00013 #include "header-py.h" /* XXX pyrpmError */ 00014 #include "rpmfd-py.h" 00015 00016 #include "debug.h" 00017 00018 /*@access FD_t @*/ 00019 00020 /*@unchecked@*/ 00021 static int _rpmfd_debug = 1; 00022 00031 typedef struct FDlist_t FDlist; 00032 00035 struct FDlist_t { 00036 FILE * f; 00037 FD_t fd; 00038 const char * note; 00039 FDlist * next; 00040 } ; 00041 00044 static FDlist *fdhead = NULL; 00045 00048 static FDlist *fdtail = NULL; 00049 00052 static int closeCallback(FILE * f) 00053 /*@globals fdhead @*/ 00054 /*@modifies fdhead @*/ 00055 { 00056 FDlist *node, *last; 00057 00058 node = fdhead; 00059 last = NULL; 00060 while (node) { 00061 if (node->f == f) 00062 break; 00063 last = node; 00064 node = node->next; 00065 } 00066 /*@-branchstate@*/ 00067 if (node) { 00068 if (last) 00069 last->next = node->next; 00070 else 00071 fdhead = node->next; 00072 node->note = _free (node->note); 00073 node->fd = fdLink(node->fd, "closeCallback"); 00074 (void) Fclose (node->fd); 00075 while (node->fd) 00076 node->fd = fdFree(node->fd, "closeCallback"); 00077 node = _free (node); 00078 } 00079 /*@=branchstate@*/ 00080 return 0; 00081 } 00082 00089 /*@null@*/ 00090 static PyObject * 00091 rpmfd_Debug(/*@unused@*/ rpmfdObject * s, PyObject * args, PyObject * kwds) 00092 /*@globals _Py_NoneStruct @*/ 00093 /*@modifies _Py_NoneStruct @*/ 00094 { 00095 char * kwlist[] = {"debugLevel", NULL}; 00096 00097 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmfd_debug)) 00098 return NULL; 00099 00100 Py_INCREF(Py_None); 00101 return Py_None; 00102 } 00103 00106 /*@null@*/ 00107 static PyObject * 00108 rpmfd_Fopen(/*@unused@*/ PyObject * s, PyObject * args, PyObject * kwds) 00109 /*@globals fdhead, fdtail @*/ 00110 /*@modifies fdhead, fdtail @*/ 00111 { 00112 char * path; 00113 char * mode = "r"; 00114 FDlist *node; 00115 char * kwlist[] = {"path", "mode", NULL}; 00116 00117 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &path, &mode)) 00118 return NULL; 00119 00120 node = xmalloc (sizeof(FDlist)); 00121 00122 node->fd = Fopen(path, mode); 00123 node->fd = fdLink(node->fd, "doFopen"); 00124 node->note = xstrdup (path); 00125 00126 if (!node->fd) { 00127 (void) PyErr_SetFromErrno(pyrpmError); 00128 node = _free (node); 00129 return NULL; 00130 } 00131 00132 if (Ferror(node->fd)) { 00133 const char *err = Fstrerror(node->fd); 00134 node = _free(node); 00135 if (err) 00136 PyErr_SetString(pyrpmError, err); 00137 return NULL; 00138 } 00139 00140 node->f = fdGetFp(node->fd); 00141 if (!node->f) { 00142 PyErr_SetString(pyrpmError, "FD_t has no FILE*"); 00143 free(node); 00144 return NULL; 00145 } 00146 00147 node->next = NULL; 00148 /*@-branchstate@*/ 00149 if (!fdhead) { 00150 fdhead = fdtail = node; 00151 } else if (fdtail) { 00152 fdtail->next = node; 00153 } else { 00154 fdhead = node; 00155 } 00156 /*@=branchstate@*/ 00157 fdtail = node; 00158 00159 return PyFile_FromFile (node->f, path, mode, closeCallback); 00160 } 00161 00166 /*@-fullinitblock@*/ 00167 /*@unchecked@*/ /*@observer@*/ 00168 static struct PyMethodDef rpmfd_methods[] = { 00169 {"Debug", (PyCFunction)rpmfd_Debug, METH_VARARGS|METH_KEYWORDS, 00170 NULL}, 00171 {"Fopen", (PyCFunction)rpmfd_Fopen, METH_VARARGS|METH_KEYWORDS, 00172 NULL}, 00173 {NULL, NULL} /* sentinel */ 00174 }; 00175 /*@=fullinitblock@*/ 00176 00177 /* ---------- */ 00178 00181 static void 00182 rpmfd_dealloc(/*@only@*/ /*@null@*/ rpmfdObject * s) 00183 /*@modifies s @*/ 00184 { 00185 if (s) { 00186 Fclose(s->fd); 00187 s->fd = NULL; 00188 PyObject_Del(s); 00189 } 00190 } 00191 00192 static PyObject * rpmfd_getattro(PyObject * o, PyObject * n) 00193 /*@*/ 00194 { 00195 return PyObject_GenericGetAttr(o, n); 00196 } 00197 00198 static int rpmfd_setattro(PyObject * o, PyObject * n, PyObject * v) 00199 /*@*/ 00200 { 00201 return PyObject_GenericSetAttr(o, n, v); 00202 } 00203 00206 static int rpmfd_init(rpmfdObject * s, PyObject *args, PyObject *kwds) 00207 /*@modifies s @*/ 00208 { 00209 char * path; 00210 char * mode = "r"; 00211 char * kwlist[] = {"path", "mode", NULL}; 00212 00213 if (_rpmfd_debug) 00214 fprintf(stderr, "*** rpmfd_init(%p,%p,%p)\n", s, args, kwds); 00215 00216 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s:rpmfd_init", kwlist, 00217 &path, &mode)) 00218 return -1; 00219 00220 s->fd = Fopen(path, mode); 00221 00222 if (s->fd == NULL) { 00223 (void) PyErr_SetFromErrno(pyrpmError); 00224 return -1; 00225 } 00226 00227 if (Ferror(s->fd)) { 00228 const char *err = Fstrerror(s->fd); 00229 if (s->fd) 00230 Fclose(s->fd); 00231 if (err) 00232 PyErr_SetString(pyrpmError, err); 00233 return -1; 00234 } 00235 return 0; 00236 } 00237 00240 static void rpmfd_free(/*@only@*/ rpmfdObject * s) 00241 /*@modifies s @*/ 00242 { 00243 if (_rpmfd_debug) 00244 fprintf(stderr, "%p -- fd %p\n", s, s->fd); 00245 if (s->fd) 00246 Fclose(s->fd); 00247 00248 PyObject_Del((PyObject *)s); 00249 } 00250 00253 static PyObject * rpmfd_alloc(PyTypeObject * subtype, int nitems) 00254 /*@*/ 00255 { 00256 PyObject * s = PyType_GenericAlloc(subtype, nitems); 00257 00258 if (_rpmfd_debug) 00259 fprintf(stderr, "*** rpmfd_alloc(%p,%d) ret %p\n", subtype, nitems, s); 00260 return s; 00261 } 00262 00265 /*@null@*/ 00266 static rpmfdObject * rpmfd_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds) 00267 /*@*/ 00268 { 00269 rpmfdObject * s = PyObject_New(rpmfdObject, subtype); 00270 00271 /* Perform additional initialization. */ 00272 if (rpmfd_init(s, args, kwds) < 0) { 00273 rpmfd_free(s); 00274 return NULL; 00275 } 00276 00277 if (_rpmfd_debug) 00278 fprintf(stderr, "%p ++ fd %p\n", s, s->fd); 00279 00280 return s; 00281 } 00282 00285 /*@unchecked@*/ /*@observer@*/ 00286 static char rpmfd_doc[] = 00287 ""; 00288 00291 /*@-fullinitblock@*/ 00292 PyTypeObject rpmfd_Type = { 00293 PyObject_HEAD_INIT(&PyType_Type) 00294 0, /* ob_size */ 00295 "rpm.fd", /* tp_name */ 00296 sizeof(rpmfdObject), /* tp_size */ 00297 0, /* tp_itemsize */ 00298 /* methods */ 00299 (destructor) rpmfd_dealloc, /* tp_dealloc */ 00300 0, /* tp_print */ 00301 (getattrfunc)0, /* tp_getattr */ 00302 (setattrfunc)0, /* tp_setattr */ 00303 (cmpfunc)0, /* tp_compare */ 00304 (reprfunc)0, /* tp_repr */ 00305 0, /* tp_as_number */ 00306 0, /* tp_as_sequence */ 00307 0, /* tp_as_mapping */ 00308 (hashfunc)0, /* tp_hash */ 00309 (ternaryfunc)0, /* tp_call */ 00310 (reprfunc)0, /* tp_str */ 00311 (getattrofunc) rpmfd_getattro, /* tp_getattro */ 00312 (setattrofunc) rpmfd_setattro, /* tp_setattro */ 00313 0, /* tp_as_buffer */ 00314 Py_TPFLAGS_DEFAULT, /* tp_flags */ 00315 rpmfd_doc, /* tp_doc */ 00316 #if Py_TPFLAGS_HAVE_ITER 00317 0, /* tp_traverse */ 00318 0, /* tp_clear */ 00319 0, /* tp_richcompare */ 00320 0, /* tp_weaklistoffset */ 00321 0, /* tp_iter */ 00322 0, /* tp_iternext */ 00323 rpmfd_methods, /* tp_methods */ 00324 0, /* tp_members */ 00325 0, /* tp_getset */ 00326 0, /* tp_base */ 00327 0, /* tp_dict */ 00328 0, /* tp_descr_get */ 00329 0, /* tp_descr_set */ 00330 0, /* tp_dictoffset */ 00331 (initproc) rpmfd_init, /* tp_init */ 00332 (allocfunc) rpmfd_alloc, /* tp_alloc */ 00333 (newfunc) rpmfd_new, /* tp_new */ 00334 rpmfd_free, /* tp_free */ 00335 0, /* tp_is_gc */ 00336 #endif 00337 }; 00338 /*@=fullinitblock@*/ 00339 00340 rpmfdObject * rpmfd_Wrap(FD_t fd) 00341 { 00342 rpmfdObject *s = PyObject_New(rpmfdObject, &rpmfd_Type); 00343 if (s == NULL) 00344 return NULL; 00345 s->fd = fd; 00346 return s; 00347 }