rpm 5.3.12
python/rpmfi-py.c
Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include <rpmio.h>
00008 #include <rpmcb.h>              /* XXX fnpyKey */
00009 #include <rpmtypes.h>
00010 #include <rpmtag.h>
00011 
00012 #include "header-py.h"
00013 #include "rpmfi-py.h"
00014 
00015 #include "debug.h"
00016 
00017 /*@access rpmfi @*/
00018 
00019 #if Py_TPFLAGS_HAVE_ITER
00020 static PyObject *
00021 rpmfi_iter(rpmfiObject * s)
00022         /*@*/
00023 {
00024     Py_INCREF(s);
00025     return (PyObject *)s;
00026 }
00027 #endif
00028 
00029 /* forward ref */
00030 static PyObject * rpmfi_Digest(rpmfiObject * s)
00031         /*@*/;
00032 
00033 /*@null@*/
00034 static PyObject *
00035 rpmfi_iternext(rpmfiObject * s)
00036         /*@globals _Py_NoneStruct @*/
00037         /*@modifies s, _Py_NoneStruct @*/
00038 {
00039     PyObject * result = NULL;
00040 
00041     /* Reset loop indices on 1st entry. */
00042     if (!s->active) {
00043         s->fi = rpmfiInit(s->fi, 0);
00044         s->active = 1;
00045     }
00046 
00047     /* If more to do, return the file tuple. */
00048     if (rpmfiNext(s->fi) >= 0) {
00049         const char * FN = rpmfiFN(s->fi);
00050         int FSize = rpmfiFSize(s->fi);
00051         int FMode = rpmfiFMode(s->fi);
00052         int FMtime = rpmfiFMtime(s->fi);
00053         int FFlags = rpmfiFFlags(s->fi);
00054         int FRdev = rpmfiFRdev(s->fi);
00055         int FInode = rpmfiFInode(s->fi);
00056         int FNlink = rpmfiFNlink(s->fi);
00057         int FState = rpmfiFState(s->fi);
00058         int VFlags = rpmfiVFlags(s->fi);
00059         const char * FUser = rpmfiFUser(s->fi);
00060         const char * FGroup = rpmfiFGroup(s->fi);
00061 
00062         result = PyTuple_New(13);
00063         if (FN == NULL) {
00064             Py_INCREF(Py_None);
00065             PyTuple_SET_ITEM(result, 0, Py_None);
00066         } else
00067             PyTuple_SET_ITEM(result,  0, Py_BuildValue("s", FN));
00068         PyTuple_SET_ITEM(result,  1, PyInt_FromLong(FSize));
00069         PyTuple_SET_ITEM(result,  2, PyInt_FromLong(FMode));
00070         PyTuple_SET_ITEM(result,  3, PyInt_FromLong(FMtime));
00071         PyTuple_SET_ITEM(result,  4, PyInt_FromLong(FFlags));
00072         PyTuple_SET_ITEM(result,  5, PyInt_FromLong(FRdev));
00073         PyTuple_SET_ITEM(result,  6, PyInt_FromLong(FInode));
00074         PyTuple_SET_ITEM(result,  7, PyInt_FromLong(FNlink));
00075         PyTuple_SET_ITEM(result,  8, PyInt_FromLong(FState));
00076         PyTuple_SET_ITEM(result,  9, PyInt_FromLong(VFlags));
00077         if (FUser == NULL) {
00078             Py_INCREF(Py_None);
00079             PyTuple_SET_ITEM(result, 10, Py_None);
00080         } else
00081             PyTuple_SET_ITEM(result, 10, Py_BuildValue("s", FUser));
00082         if (FGroup == NULL) {
00083             Py_INCREF(Py_None);
00084             PyTuple_SET_ITEM(result, 11, Py_None);
00085         } else
00086             PyTuple_SET_ITEM(result, 11, Py_BuildValue("s", FGroup));
00087         PyTuple_SET_ITEM(result, 12, rpmfi_Digest(s));
00088     } else
00089         s->active = 0;
00090 
00091     return result;
00092 }
00093 
00098 
00099 static PyObject *
00100 rpmfi_Next(rpmfiObject * s)
00101         /*@globals _Py_NoneStruct @*/
00102         /*@modifies s, _Py_NoneStruct @*/
00103 {
00104     PyObject * result = NULL;
00105 
00106     result = rpmfi_iternext(s);
00107 
00108     if (result == NULL) {
00109         Py_INCREF(Py_None);
00110         return Py_None;
00111     }
00112 
00113     return result;
00114 }
00115 
00116 #ifdef  NOTYET
00117 /*@null@*/
00118 static PyObject *
00119 rpmfi_NextD(rpmfiObject * s)
00120         /*@*/
00121 {
00122         Py_INCREF(Py_None);
00123         return Py_None;
00124 }
00125 
00126 /*@null@*/
00127 static PyObject *
00128 rpmfi_InitD(rpmfiObject * s)
00129         /*@*/
00130 {
00131         Py_INCREF(Py_None);
00132         return Py_None;
00133 }
00134 #endif
00135 
00136 /*@null@*/
00137 static PyObject *
00138 rpmfi_Debug(/*@unused@*/ rpmfiObject * s, PyObject * args,
00139                 PyObject * kwds)
00140         /*@globals _Py_NoneStruct @*/
00141         /*@modifies _Py_NoneStruct @*/
00142 {
00143     char * kwlist[] = {"debugLevel", NULL};
00144 
00145     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmfi_debug))
00146         return NULL;
00147 
00148     Py_INCREF(Py_None);
00149     return Py_None;
00150 }
00151 
00152 /*@null@*/
00153 static PyObject *
00154 rpmfi_FC(rpmfiObject * s)
00155         /*@*/
00156 {
00157     return Py_BuildValue("i", rpmfiFC(s->fi));
00158 }
00159 
00160 /*@null@*/
00161 static PyObject *
00162 rpmfi_FX(rpmfiObject * s)
00163         /*@*/
00164 {
00165     return Py_BuildValue("i", rpmfiFX(s->fi));
00166 }
00167 
00168 /*@null@*/
00169 static PyObject *
00170 rpmfi_DC(rpmfiObject * s)
00171         /*@*/
00172 {
00173     return Py_BuildValue("i", rpmfiDC(s->fi));
00174 }
00175 
00176 /*@null@*/
00177 static PyObject *
00178 rpmfi_DX(rpmfiObject * s)
00179         /*@*/
00180 {
00181     return Py_BuildValue("i", rpmfiDX(s->fi));
00182 }
00183 
00184 /*@null@*/
00185 static PyObject *
00186 rpmfi_BN(rpmfiObject * s)
00187         /*@*/
00188 {
00189     return Py_BuildValue("s", xstrdup(rpmfiBN(s->fi)));
00190 }
00191 
00192 /*@null@*/
00193 static PyObject *
00194 rpmfi_DN(rpmfiObject * s)
00195         /*@*/
00196 {
00197     return Py_BuildValue("s", xstrdup(rpmfiDN(s->fi)));
00198 }
00199 
00200 /*@null@*/
00201 static PyObject *
00202 rpmfi_FN(rpmfiObject * s)
00203         /*@modifies s @*/
00204 {
00205     return Py_BuildValue("s", xstrdup(rpmfiFN(s->fi)));
00206 }
00207 
00208 /*@null@*/
00209 static PyObject *
00210 rpmfi_FFlags(rpmfiObject * s)
00211         /*@*/
00212 {
00213     return Py_BuildValue("i", rpmfiFFlags(s->fi));
00214 }
00215 
00216 /*@null@*/
00217 static PyObject *
00218 rpmfi_VFlags(rpmfiObject * s)
00219         /*@*/
00220 {
00221     return Py_BuildValue("i", rpmfiVFlags(s->fi));
00222 }
00223 
00224 /*@null@*/
00225 static PyObject *
00226 rpmfi_FMode(rpmfiObject * s)
00227         /*@*/
00228 {
00229     return Py_BuildValue("i", rpmfiFMode(s->fi));
00230 }
00231 
00232 /*@null@*/
00233 static PyObject *
00234 rpmfi_FState(rpmfiObject * s)
00235         /*@*/
00236 {
00237     return Py_BuildValue("i", rpmfiFState(s->fi));
00238 }
00239 
00240 /*@null@*/
00241 static PyObject *
00242 rpmfi_Digest(rpmfiObject * s)
00243         /*@*/
00244 {
00245     int dalgo = 0;
00246     size_t dlen = 0;
00247     const unsigned char * digest;
00248     const char * fdigest;
00249     char * t;
00250     size_t i;
00251 
00252     digest = rpmfiDigest(s->fi, &dalgo, &dlen);
00253     if (digest == NULL || dlen == 0) {
00254         Py_INCREF(Py_None);
00255         return Py_None;
00256     }
00257     fdigest = t = memset(alloca(dlen), 0, dlen);
00258     for (i = 0; i < dlen; i++, t += 2)
00259         sprintf(t, "%02x", digest[i]);
00260     *t = '\0';
00261     return Py_BuildValue("s", xstrdup(fdigest));
00262 }
00263 
00264 /*@null@*/
00265 static PyObject *
00266 rpmfi_FLink(rpmfiObject * s)
00267         /*@*/
00268 {
00269     return Py_BuildValue("s", xstrdup(rpmfiFLink(s->fi)));
00270 }
00271 
00272 /*@null@*/
00273 static PyObject *
00274 rpmfi_FSize(rpmfiObject * s)
00275         /*@*/
00276 {
00277     return Py_BuildValue("i", rpmfiFSize(s->fi));
00278 }
00279 
00280 /*@null@*/
00281 static PyObject *
00282 rpmfi_FRdev(rpmfiObject * s)
00283         /*@*/
00284 {
00285     return Py_BuildValue("i", rpmfiFRdev(s->fi));
00286 }
00287 
00288 /*@null@*/
00289 static PyObject *
00290 rpmfi_FMtime(rpmfiObject * s)
00291         /*@*/
00292 {
00293     return Py_BuildValue("i", rpmfiFMtime(s->fi));
00294 }
00295 
00296 /*@null@*/
00297 static PyObject *
00298 rpmfi_FUser(rpmfiObject * s)
00299         /*@*/
00300 {
00301     return Py_BuildValue("s", xstrdup(rpmfiFUser(s->fi)));
00302 }
00303 
00304 /*@null@*/
00305 static PyObject *
00306 rpmfi_FGroup(rpmfiObject * s)
00307         /*@*/
00308 {
00309     return Py_BuildValue("s", xstrdup(rpmfiFGroup(s->fi)));
00310 }
00311 
00312 /*@null@*/
00313 static PyObject *
00314 rpmfi_FColor(rpmfiObject * s)
00315         /*@*/
00316 {
00317     return Py_BuildValue("i", rpmfiFColor(s->fi));
00318 }
00319 
00320 /*@null@*/
00321 static PyObject *
00322 rpmfi_FClass(rpmfiObject * s)
00323         /*@*/
00324 {
00325     const char * FClass;
00326 
00327     if ((FClass = rpmfiFClass(s->fi)) == NULL)
00328         FClass = "";
00329     return Py_BuildValue("s", xstrdup(FClass));
00330 }
00331 
00334 /*@-fullinitblock@*/
00335 /*@unchecked@*/ /*@observer@*/
00336 static struct PyMethodDef rpmfi_methods[] = {
00337  {"Debug",      (PyCFunction)rpmfi_Debug,       METH_VARARGS|METH_KEYWORDS,
00338         NULL},
00339  {"FC",         (PyCFunction)rpmfi_FC,          METH_NOARGS,
00340         NULL},
00341  {"FX",         (PyCFunction)rpmfi_FX,          METH_NOARGS,
00342         NULL},
00343  {"DC",         (PyCFunction)rpmfi_DC,          METH_NOARGS,
00344         NULL},
00345  {"DX",         (PyCFunction)rpmfi_DX,          METH_NOARGS,
00346         NULL},
00347  {"BN",         (PyCFunction)rpmfi_BN,          METH_NOARGS,
00348         NULL},
00349  {"DN",         (PyCFunction)rpmfi_DN,          METH_NOARGS,
00350         NULL},
00351  {"FN",         (PyCFunction)rpmfi_FN,          METH_NOARGS,
00352         NULL},
00353  {"FFlags",     (PyCFunction)rpmfi_FFlags,      METH_NOARGS,
00354         NULL},
00355  {"VFlags",     (PyCFunction)rpmfi_VFlags,      METH_NOARGS,
00356         NULL},
00357  {"FMode",      (PyCFunction)rpmfi_FMode,       METH_NOARGS,
00358         NULL},
00359  {"FState",     (PyCFunction)rpmfi_FState,      METH_NOARGS,
00360         NULL},
00361  {"MD5",        (PyCFunction)rpmfi_Digest,      METH_NOARGS,
00362         NULL},
00363  {"Digest",     (PyCFunction)rpmfi_Digest,      METH_NOARGS,
00364         NULL},
00365  {"FLink",      (PyCFunction)rpmfi_FLink,       METH_NOARGS,
00366         NULL},
00367  {"FSize",      (PyCFunction)rpmfi_FSize,       METH_NOARGS,
00368         NULL},
00369  {"FRdev",      (PyCFunction)rpmfi_FRdev,       METH_NOARGS,
00370         NULL},
00371  {"FMtime",     (PyCFunction)rpmfi_FMtime,      METH_NOARGS,
00372         NULL},
00373  {"FUser",      (PyCFunction)rpmfi_FUser,       METH_NOARGS,
00374         NULL},
00375  {"FGroup",     (PyCFunction)rpmfi_FGroup,      METH_NOARGS,
00376         NULL},
00377  {"FColor",     (PyCFunction)rpmfi_FColor,      METH_NOARGS,
00378         NULL},
00379  {"FClass",     (PyCFunction)rpmfi_FClass,      METH_NOARGS,
00380         NULL},
00381  {"next",       (PyCFunction)rpmfi_Next,        METH_NOARGS,
00382 "fi.next() -> (FN, FSize, FMode, FMtime, FFlags, FRdev, FInode, FNlink, FState, VFlags, FUser, FGroup, Digest))\n\
00383 - Retrieve next file info tuple.\n" },
00384 #ifdef  NOTYET
00385  {"NextD",      (PyCFunction)rpmfi_NextD,       METH_NOARGS,
00386         NULL},
00387  {"InitD",      (PyCFunction)rpmfi_InitD,       METH_NOARGS,
00388         NULL},
00389 #endif
00390  {NULL,         NULL}           /* sentinel */
00391 };
00392 /*@=fullinitblock@*/
00393 
00394 /* ---------- */
00395 
00396 static void
00397 rpmfi_dealloc(/*@only@*/ /*@null@*/ rpmfiObject * s)
00398         /*@modifies s @*/
00399 {
00400     if (s) {
00401         s->fi = rpmfiFree(s->fi);
00402         PyObject_Del(s);
00403     }
00404 }
00405 
00406 static int
00407 rpmfi_print(rpmfiObject * s, FILE * fp, /*@unused@*/ int flags)
00408         /*@globals fileSystem @*/
00409         /*@modifies s, fp, fileSystem @*/
00410 {
00411     if (!(s && s->fi))
00412         return -1;
00413 
00414     s->fi = rpmfiInit(s->fi, 0);
00415     while (rpmfiNext(s->fi) >= 0)
00416         fprintf(fp, "%s\n", rpmfiFN(s->fi));
00417     return 0;
00418 }
00419 
00420 static PyObject * rpmfi_getattro(PyObject * o, PyObject * n)
00421         /*@*/
00422 {
00423     return PyObject_GenericGetAttr(o, n);
00424 }
00425 
00426 static int rpmfi_setattro(PyObject * o, PyObject * n, PyObject * v)
00427         /*@*/
00428 {
00429     return PyObject_GenericSetAttr(o, n, v);
00430 }
00431 
00432 static int
00433 rpmfi_length(rpmfiObject * s)
00434         /*@*/
00435 {
00436     return rpmfiFC(s->fi);
00437 }
00438 
00439 /*@null@*/
00440 static PyObject *
00441 rpmfi_subscript(rpmfiObject * s, PyObject * key)
00442         /*@modifies s @*/
00443 {
00444     int ix;
00445 
00446     if (!PyInt_Check(key)) {
00447         PyErr_SetString(PyExc_TypeError, "integer expected");
00448         return NULL;
00449     }
00450 
00451     ix = (int) PyInt_AsLong(key);
00452     rpmfiSetFX(s->fi, ix);
00453     return Py_BuildValue("s", xstrdup(rpmfiFN(s->fi)));
00454 }
00455 
00456 /*@unchecked@*/ /*@observer@*/
00457 static PyMappingMethods rpmfi_as_mapping = {
00458         (lenfunc) rpmfi_length,         /* mp_length */
00459         (binaryfunc) rpmfi_subscript,   /* mp_subscript */
00460         (objobjargproc)0,               /* mp_ass_subscript */
00461 };
00462 
00465 static int rpmfi_init(rpmfiObject * s, PyObject *args, PyObject *kwds)
00466         /*@globals rpmGlobalMacroContext @*/
00467         /*@modifies s, rpmGlobalMacroContext @*/
00468 {
00469     hdrObject * ho = NULL;
00470     PyObject * to = NULL;
00471     rpmts ts = NULL;    /* XXX FIXME: fiFromHeader should be a ts method. */
00472     int tagN = RPMTAG_BASENAMES;
00473     int flags = 0;
00474     char * kwlist[] = {"header", "tag", "flags", NULL};
00475 
00476 if (_rpmfi_debug < 0)
00477 fprintf(stderr, "*** rpmfi_init(%p,%p,%p)\n", s, args, kwds);
00478 
00479     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|Oi:rpmfi_init", kwlist,
00480             &hdr_Type, &ho, &to, &flags))
00481         return -1;
00482 
00483     if (to != NULL) {
00484         tagN = tagNumFromPyObject(to);
00485         if (tagN == -1) {
00486             PyErr_SetString(PyExc_KeyError, "unknown header tag");
00487             return -1;
00488         }
00489     }
00490     s->fi = rpmfiNew(ts, hdrGetHeader(ho), tagN, flags);
00491     s->active = 0;
00492 
00493     return 0;
00494 }
00495 
00498 static void rpmfi_free(/*@only@*/ rpmfiObject * s)
00499         /*@modifies s @*/
00500 {
00501 if (_rpmfi_debug)
00502 fprintf(stderr, "%p -- fi %p\n", s, s->fi);
00503     s->fi = rpmfiFree(s->fi);
00504 
00505     PyObject_Del((PyObject *)s);
00506 }
00507 
00510 static PyObject * rpmfi_alloc(PyTypeObject * subtype, int nitems)
00511         /*@*/
00512 {
00513     PyObject * s = PyType_GenericAlloc(subtype, nitems);
00514 
00515 if (_rpmfi_debug < 0)
00516 fprintf(stderr, "*** rpmfi_alloc(%p,%d) ret %p\n", subtype, nitems, s);
00517     return s;
00518 }
00519 
00522 /*@null@*/
00523 static PyObject * rpmfi_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
00524         /*@globals rpmGlobalMacroContext @*/
00525         /*@modifies rpmGlobalMacroContext @*/
00526 {
00527     rpmfiObject * s = (void *) PyObject_New(rpmfiObject, subtype);
00528 
00529     /* Perform additional initialization. */
00530     if (rpmfi_init(s, args, kwds) < 0) {
00531         rpmfi_free(s);
00532         return NULL;
00533     }
00534 
00535 if (_rpmfi_debug)
00536 fprintf(stderr, "%p ++ fi %p\n", s, s->fi);
00537 
00538     return (PyObject *)s;
00539 }
00540 
00543 /*@unchecked@*/ /*@observer@*/
00544 static char rpmfi_doc[] =
00545 "";
00546 
00547 /*@-fullinitblock@*/
00548 PyTypeObject rpmfi_Type = {
00549         PyObject_HEAD_INIT(&PyType_Type)
00550         0,                              /* ob_size */
00551         "rpm.fi",                       /* tp_name */
00552         sizeof(rpmfiObject),            /* tp_basicsize */
00553         0,                              /* tp_itemsize */
00554         /* methods */
00555         (destructor) rpmfi_dealloc,     /* tp_dealloc */
00556         (printfunc) rpmfi_print,        /* tp_print */
00557         (getattrfunc)0,                 /* tp_getattr */
00558         (setattrfunc)0,                 /* tp_setattr */
00559         (cmpfunc)0,                     /* tp_compare */
00560         (reprfunc)0,                    /* tp_repr */
00561         0,                              /* tp_as_number */
00562         0,                              /* tp_as_sequence */
00563         &rpmfi_as_mapping,              /* tp_as_mapping */
00564         (hashfunc)0,                    /* tp_hash */
00565         (ternaryfunc)0,                 /* tp_call */
00566         (reprfunc)0,                    /* tp_str */
00567         (getattrofunc) rpmfi_getattro,  /* tp_getattro */
00568         (setattrofunc) rpmfi_setattro,  /* tp_setattro */
00569         0,                              /* tp_as_buffer */
00570         Py_TPFLAGS_DEFAULT,             /* tp_flags */
00571         rpmfi_doc,                      /* tp_doc */
00572 #if Py_TPFLAGS_HAVE_ITER
00573         0,                              /* tp_traverse */
00574         0,                              /* tp_clear */
00575         0,                              /* tp_richcompare */
00576         0,                              /* tp_weaklistoffset */
00577         (getiterfunc) rpmfi_iter,       /* tp_iter */
00578         (iternextfunc) rpmfi_iternext,  /* tp_iternext */
00579         rpmfi_methods,                  /* tp_methods */
00580         0,                              /* tp_members */
00581         0,                              /* tp_getset */
00582         0,                              /* tp_base */
00583         0,                              /* tp_dict */
00584         0,                              /* tp_descr_get */
00585         0,                              /* tp_descr_set */
00586         0,                              /* tp_dictoffset */
00587         (initproc) rpmfi_init,          /* tp_init */
00588         (allocfunc) rpmfi_alloc,        /* tp_alloc */
00589         (newfunc) rpmfi_new,            /* tp_new */
00590         (freefunc) rpmfi_free,          /* tp_free */
00591         0,                              /* tp_is_gc */
00592 #endif
00593 };
00594 /*@=fullinitblock@*/
00595 
00596 /* ---------- */
00597 
00598 rpmfi fiFromFi(rpmfiObject * s)
00599 {
00600     return s->fi;
00601 }
00602 
00603 rpmfiObject *
00604 rpmfi_Wrap(rpmfi fi)
00605 {
00606     rpmfiObject *s = PyObject_New(rpmfiObject, &rpmfi_Type);
00607 
00608     if (s == NULL)
00609         return NULL;
00610     s->fi = fi;
00611     s->active = 0;
00612     return s;
00613 }
00614 
00615 rpmfiObject *
00616 hdr_fiFromHeader(PyObject * s, PyObject * args, PyObject * kwds)
00617 {
00618     hdrObject * ho = (hdrObject *)s;
00619     PyObject * to = NULL;
00620     rpmts ts = NULL;    /* XXX FIXME: fiFromHeader should be a ts method. */
00621     rpmTag tagN = RPMTAG_BASENAMES;
00622     int flags = 0;
00623     char * kwlist[] = {"tag", "flags", NULL};
00624 
00625     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:fiFromHeader", kwlist,
00626             &to, &flags))
00627         return NULL;
00628 
00629     if (to != NULL) {
00630         tagN = tagNumFromPyObject(to);
00631         if (tagN == (rpmTag)-1) {
00632             PyErr_SetString(PyExc_KeyError, "unknown header tag");
00633             return NULL;
00634         }
00635     }
00636     return rpmfi_Wrap( rpmfiNew(ts, hdrGetHeader(ho), tagN, flags) );
00637 }