rpm 5.2.1
|
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 #include <rpmcb.h> /* XXX fnpyKey */ 00011 #include <rpmtypes.h> 00012 #include <rpmtag.h> 00013 00014 #include "header-py.h" /* XXX pyrpmError */ 00015 #include "rpmfd-py.h" 00016 00017 #include "debug.h" 00018 00019 /*@access FD_t @*/ 00020 00021 /*@unchecked@*/ 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 /*@globals fdhead @*/ 00055 /*@modifies fdhead @*/ 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 /*@-branchstate@*/ 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 /*@=branchstate@*/ 00081 return 0; 00082 } 00083 00090 /*@null@*/ 00091 static PyObject * 00092 rpmfd_Debug(/*@unused@*/ rpmfdObject * s, PyObject * args, 00093 PyObject * kwds) 00094 /*@globals _Py_NoneStruct @*/ 00095 /*@modifies _Py_NoneStruct @*/ 00096 { 00097 char * kwlist[] = {"debugLevel", NULL}; 00098 00099 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmfd_debug)) 00100 return NULL; 00101 00102 Py_INCREF(Py_None); 00103 return Py_None; 00104 } 00105 00108 /*@null@*/ 00109 static PyObject * 00110 rpmfd_Fopen(/*@unused@*/ PyObject * s, PyObject * args, PyObject * kwds) 00111 /*@globals fdhead, fdtail @*/ 00112 /*@modifies fdhead, fdtail @*/ 00113 { 00114 char * path; 00115 char * mode = "r.fdio"; 00116 FDlist *node; 00117 char * kwlist[] = {"path", "mode", NULL}; 00118 00119 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &path, &mode)) 00120 return NULL; 00121 00122 node = xmalloc (sizeof(FDlist)); 00123 00124 node->fd = Fopen(path, mode); 00125 node->fd = fdLink(node->fd, "doFopen"); 00126 node->note = xstrdup (path); 00127 00128 if (!node->fd) { 00129 (void) PyErr_SetFromErrno(pyrpmError); 00130 node = _free (node); 00131 return NULL; 00132 } 00133 00134 if (Ferror(node->fd)) { 00135 const char *err = Fstrerror(node->fd); 00136 node = _free(node); 00137 if (err) 00138 PyErr_SetString(pyrpmError, err); 00139 return NULL; 00140 } 00141 00142 node->f = fdGetFp(node->fd); 00143 if (!node->f) { 00144 PyErr_SetString(pyrpmError, "FD_t has no FILE*"); 00145 free(node); 00146 return NULL; 00147 } 00148 00149 node->next = NULL; 00150 /*@-branchstate@*/ 00151 if (!fdhead) { 00152 fdhead = fdtail = node; 00153 } else if (fdtail) { 00154 fdtail->next = node; 00155 } else { 00156 fdhead = node; 00157 } 00158 /*@=branchstate@*/ 00159 fdtail = node; 00160 00161 return PyFile_FromFile (node->f, path, mode, closeCallback); 00162 } 00163 00168 /*@-fullinitblock@*/ 00169 /*@unchecked@*/ /*@observer@*/ 00170 static struct PyMethodDef rpmfd_methods[] = { 00171 {"Debug", (PyCFunction)rpmfd_Debug, METH_VARARGS|METH_KEYWORDS, 00172 NULL}, 00173 {"Fopen", (PyCFunction)rpmfd_Fopen, METH_VARARGS|METH_KEYWORDS, 00174 NULL}, 00175 {NULL, NULL} /* sentinel */ 00176 }; 00177 /*@=fullinitblock@*/ 00178 00179 /* ---------- */ 00180 00183 static void 00184 rpmfd_dealloc(/*@only@*/ /*@null@*/ rpmfdObject * s) 00185 /*@modifies s @*/ 00186 { 00187 if (s) { 00188 Fclose(s->fd); 00189 s->fd = NULL; 00190 PyObject_Del(s); 00191 } 00192 } 00193 00194 static PyObject * rpmfd_getattro(PyObject * o, PyObject * n) 00195 /*@*/ 00196 { 00197 return PyObject_GenericGetAttr(o, n); 00198 } 00199 00200 static int rpmfd_setattro(PyObject * o, PyObject * n, PyObject * v) 00201 /*@*/ 00202 { 00203 return PyObject_GenericSetAttr(o, n, v); 00204 } 00205 00208 static int rpmfd_init(rpmfdObject * s, PyObject *args, PyObject *kwds) 00209 /*@modifies s @*/ 00210 { 00211 char * path; 00212 char * mode = "r"; 00213 char * kwlist[] = {"path", "mode", NULL}; 00214 00215 if (_rpmfd_debug) 00216 fprintf(stderr, "*** rpmfd_init(%p,%p,%p)\n", s, args, kwds); 00217 00218 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s:rpmfd_init", kwlist, 00219 &path, &mode)) 00220 return -1; 00221 00222 s->fd = Fopen(path, mode); 00223 00224 if (s->fd == NULL) { 00225 (void) PyErr_SetFromErrno(pyrpmError); 00226 return -1; 00227 } 00228 00229 if (Ferror(s->fd)) { 00230 const char *err = Fstrerror(s->fd); 00231 if (s->fd) 00232 Fclose(s->fd); 00233 if (err) 00234 PyErr_SetString(pyrpmError, err); 00235 return -1; 00236 } 00237 return 0; 00238 } 00239 00242 static void rpmfd_free(/*@only@*/ rpmfdObject * s) 00243 /*@modifies s @*/ 00244 { 00245 if (_rpmfd_debug) 00246 fprintf(stderr, "%p -- fd %p\n", s, s->fd); 00247 if (s->fd) 00248 Fclose(s->fd); 00249 00250 PyObject_Del((PyObject *)s); 00251 } 00252 00255 static PyObject * rpmfd_alloc(PyTypeObject * subtype, int nitems) 00256 /*@*/ 00257 { 00258 PyObject * s = PyType_GenericAlloc(subtype, nitems); 00259 00260 if (_rpmfd_debug) 00261 fprintf(stderr, "*** rpmfd_alloc(%p,%d) ret %p\n", subtype, nitems, s); 00262 return s; 00263 } 00264 00267 /*@null@*/ 00268 static rpmfdObject * rpmfd_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds) 00269 /*@*/ 00270 { 00271 rpmfdObject * s = PyObject_New(rpmfdObject, subtype); 00272 00273 /* Perform additional initialization. */ 00274 if (rpmfd_init(s, args, kwds) < 0) { 00275 rpmfd_free(s); 00276 return NULL; 00277 } 00278 00279 if (_rpmfd_debug) 00280 fprintf(stderr, "%p ++ fd %p\n", s, s->fd); 00281 00282 return s; 00283 } 00284 00287 /*@unchecked@*/ /*@observer@*/ 00288 static char rpmfd_doc[] = 00289 ""; 00290 00293 /*@-fullinitblock@*/ 00294 PyTypeObject rpmfd_Type = { 00295 PyObject_HEAD_INIT(&PyType_Type) 00296 0, /* ob_size */ 00297 "rpm.fd", /* tp_name */ 00298 sizeof(rpmfdObject), /* tp_size */ 00299 0, /* tp_itemsize */ 00300 /* methods */ 00301 (destructor) rpmfd_dealloc, /* tp_dealloc */ 00302 0, /* tp_print */ 00303 (getattrfunc)0, /* tp_getattr */ 00304 (setattrfunc)0, /* tp_setattr */ 00305 (cmpfunc)0, /* tp_compare */ 00306 (reprfunc)0, /* tp_repr */ 00307 0, /* tp_as_number */ 00308 0, /* tp_as_sequence */ 00309 0, /* tp_as_mapping */ 00310 (hashfunc)0, /* tp_hash */ 00311 (ternaryfunc)0, /* tp_call */ 00312 (reprfunc)0, /* tp_str */ 00313 (getattrofunc) rpmfd_getattro, /* tp_getattro */ 00314 (setattrofunc) rpmfd_setattro, /* tp_setattro */ 00315 0, /* tp_as_buffer */ 00316 Py_TPFLAGS_DEFAULT, /* tp_flags */ 00317 rpmfd_doc, /* tp_doc */ 00318 #if Py_TPFLAGS_HAVE_ITER 00319 0, /* tp_traverse */ 00320 0, /* tp_clear */ 00321 0, /* tp_richcompare */ 00322 0, /* tp_weaklistoffset */ 00323 0, /* tp_iter */ 00324 0, /* tp_iternext */ 00325 rpmfd_methods, /* tp_methods */ 00326 0, /* tp_members */ 00327 0, /* tp_getset */ 00328 0, /* tp_base */ 00329 0, /* tp_dict */ 00330 0, /* tp_descr_get */ 00331 0, /* tp_descr_set */ 00332 0, /* tp_dictoffset */ 00333 (initproc) rpmfd_init, /* tp_init */ 00334 (allocfunc) rpmfd_alloc, /* tp_alloc */ 00335 (newfunc) rpmfd_new, /* tp_new */ 00336 (freefunc) rpmfd_free, /* tp_free */ 00337 0, /* tp_is_gc */ 00338 #endif 00339 }; 00340 /*@=fullinitblock@*/ 00341 00342 rpmfdObject * rpmfd_Wrap(FD_t fd) 00343 { 00344 rpmfdObject *s = PyObject_New(rpmfdObject, &rpmfd_Type); 00345 if (s == NULL) 00346 return NULL; 00347 s->fd = fd; 00348 return s; 00349 }