rpm 5.3.12
python/header-py.c
Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include "rpmio_internal.h"
00008 #include <rpmcb.h>
00009 
00010 #include "legacy.h"
00011 #define _RPMTAG_INTERNAL
00012 #include "header_internal.h"    /* XXX HEADERFLAG_ALLOCATED */
00013 #include "rpmtypes.h"
00014 #define _RPMEVR_INTERNAL
00015 #include "rpmevr.h"
00016 #include "pkgio.h"              /* XXX rpmpkgRead */
00017 
00018 #include "rpmts.h"      /* XXX rpmtsCreate/rpmtsFree */
00019 
00020 #include "rpmcli.h"
00021 
00022 #include "header-py.h"
00023 #include "rpmds-py.h"
00024 #include "rpmfi-py.h"
00025 
00026 #include "debug.h"
00027 
00138 struct hdrObject_s {
00139     PyObject_HEAD
00140     Header h;
00141 } ;
00142 
00145 /*@unused@*/ static inline Header headerAllocated(Header h)
00146         /*@modifies h @*/
00147 {
00148     h->flags |= HEADERFLAG_ALLOCATED;
00149     return 0;
00150 }
00151 
00152 static PyObject *hdrIsSource(hdrObject *s)
00153 {
00154     int isSource = !headerIsEntry(s->h, RPMTAG_SOURCERPM);
00155     return PyBool_FromLong(isSource);
00156 }
00157 
00162 
00165 static PyObject * hdrKeyList(hdrObject * s)
00166         /*@*/
00167 {
00168     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00169     PyObject * list, *o;
00170     HeaderIterator hi;
00171 
00172     list = PyList_New(0);
00173 
00174     for (hi = headerInit(s->h);
00175         headerNext(hi, he, 0);
00176         he->p.ptr = _free(he->p.ptr))
00177     {
00178         if (he->tag == HEADER_I18NTABLE) continue;
00179         switch (he->t) {
00180         case RPM_I18NSTRING_TYPE:
00181             break;
00182         case RPM_BIN_TYPE:
00183         case RPM_UINT64_TYPE:
00184         case RPM_UINT32_TYPE:
00185         case RPM_UINT16_TYPE:
00186         case RPM_UINT8_TYPE:
00187         case RPM_STRING_ARRAY_TYPE:
00188         case RPM_STRING_TYPE:
00189             PyList_Append(list, o=PyInt_FromLong(he->tag));
00190             Py_DECREF(o);
00191             break;
00192         }
00193     }
00194     hi = headerFini(hi);
00195 
00196     return list;
00197 }
00198 
00201 static PyObject * hdrUnload(hdrObject * s, PyObject * args, PyObject *keywords)
00202         /*@*/
00203 {
00204     char * buf;
00205     PyObject * rc;
00206     int legacy = 0;
00207     int nb;
00208     Header h;
00209     static char *kwlist[] = { "legacyHeader", NULL};
00210 
00211     if (!PyArg_ParseTupleAndKeywords(args, keywords, "|i", kwlist, &legacy))
00212         return NULL;
00213 
00214     h = headerLink(s->h);
00215     /* XXX this legacy switch is a hack, needs to be removed. */
00216     if (legacy) {
00217         h = headerCopy(s->h);   /* XXX strip region tags, etc */
00218         (void)headerFree(s->h);
00219         s->h = NULL;
00220     }
00221     {   size_t len;
00222         buf = headerUnload(h, &len);
00223         nb = len;
00224         nb -= 8;        /* XXX HEADER_MAGIC_NO */
00225     }
00226     (void)headerFree(h);
00227     h = NULL;
00228 
00229     if (buf == NULL || nb == 0) {
00230         PyErr_SetString(pyrpmError, "can't unload bad header\n");
00231         return NULL;
00232     }
00233 
00234     rc = PyString_FromStringAndSize(buf, nb);
00235     buf = _free(buf);
00236 
00237     return rc;
00238 }
00239 
00242 static PyObject * hdrGetOrigin(hdrObject * s)
00243         /*@*/
00244 {
00245     const char * origin = NULL;
00246     if (s->h != NULL)
00247 
00248         origin = headerGetOrigin(s->h);
00249     if (origin != NULL)
00250         return Py_BuildValue("s", origin);
00251     Py_INCREF(Py_None);
00252     return Py_None;
00253 }
00254 
00257 static PyObject * hdrSetOrigin(hdrObject * s, PyObject * args, PyObject * kwds)
00258         /*@*/
00259 {
00260     char * kwlist[] = {"origin", NULL};
00261     const char * origin = NULL;
00262 
00263     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:SetOrigin", kwlist, &origin))
00264         return NULL;
00265 
00266     if (s->h != NULL && origin != NULL)
00267         headerSetOrigin(s->h, origin);
00268 
00269     Py_INCREF(Py_None);
00270     return Py_None;
00271 }
00272 
00275 static PyObject * hdrSprintf(hdrObject * s, PyObject * args, PyObject * kwds)
00276         /*@*/
00277 {
00278     char * fmt;
00279     char * r;
00280     errmsg_t err;
00281     PyObject * result;
00282     char * kwlist[] = {"format", NULL};
00283 
00284     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &fmt))
00285         return NULL;
00286 
00287     r = headerSprintf(s->h, fmt, NULL, rpmHeaderFormats, &err);
00288     if (!r) {
00289         PyErr_SetString(pyrpmError, err);
00290         return NULL;
00291     }
00292 
00293     result = Py_BuildValue("s", r);
00294     r = _free(r);
00295 
00296     return result;
00297 }
00298 
00303 /*@unchecked@*/ /*@observer@*/
00304 static struct PyMethodDef hdr_methods[] = {
00305     {"keys",            (PyCFunction) hdrKeyList,       METH_NOARGS,
00306         NULL },
00307     {"unload",          (PyCFunction) hdrUnload,        METH_VARARGS|METH_KEYWORDS,
00308         NULL },
00309     {"getorigin",       (PyCFunction) hdrGetOrigin,     METH_NOARGS,
00310         NULL },
00311     {"setorigin",       (PyCFunction) hdrSetOrigin,     METH_VARARGS|METH_KEYWORDS,
00312         NULL },
00313     {"sprintf",         (PyCFunction) hdrSprintf,       METH_VARARGS|METH_KEYWORDS,
00314         NULL },
00315     {"isSource",        (PyCFunction)hdrIsSource,       METH_NOARGS, 
00316         NULL },
00317 
00318     {"dsOfHeader",      (PyCFunction)hdr_dsOfHeader,    METH_NOARGS,
00319         NULL},
00320     {"dsFromHeader",    (PyCFunction)hdr_dsFromHeader,  METH_VARARGS|METH_KEYWORDS,
00321         NULL},
00322     {"fiFromHeader",    (PyCFunction)hdr_fiFromHeader,  METH_VARARGS|METH_KEYWORDS,
00323         NULL},
00324 
00325     {NULL,              NULL}           /* sentinel */
00326 };
00327 
00330 static int hdr_compare(hdrObject * a, hdrObject * b)
00331         /*@*/
00332 {
00333     return rpmVersionCompare(a->h, b->h);
00334 }
00335 
00336 static long hdr_hash(PyObject * h)
00337 {
00338     return (long) h;
00339 }
00340 
00343 static void hdr_dealloc(hdrObject * s)
00344         /*@*/
00345 {
00346     if (s->h) (void) headerFree(s->h);
00347     s->h = NULL;
00348     PyObject_Del(s);
00349 }
00350 
00353 rpmTag tagNumFromPyObject (PyObject *item)
00354 {
00355     char * str;
00356 
00357     if (PyInt_Check(item)) {
00358         return (rpmTag) PyInt_AsLong(item);
00359     } else if (PyString_Check(item) || PyUnicode_Check(item)) {
00360         str = PyString_AsString(item);
00361         return tagValue(str);
00362     }
00363     return (rpmTag)0xffffffff;
00364 }
00365 
00368 static PyObject * hdr_subscript(hdrObject * s, PyObject * item)
00369         /*@*/
00370 {
00371     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00372     rpmTag tag = (rpmTag)0xffffffff;
00373     uint32_t i;
00374     PyObject * o, * metao;
00375     int forceArray = 0;
00376     const struct headerSprintfExtension_s * ext = NULL;
00377     int xx;
00378 
00379     if (PyCObject_Check (item))
00380         ext = PyCObject_AsVoidPtr(item);
00381     else
00382         tag = tagNumFromPyObject (item);
00383 
00384     if (tag == (rpmTag)0xffffffff && (PyString_Check(item) || PyUnicode_Check(item))) {
00385         const struct headerSprintfExtension_s * extensions = rpmHeaderFormats;
00386         char * str;
00387         /* if we still don't have the tag, go looking for the header
00388            extensions */
00389         str = PyString_AsString(item);
00390         while (extensions->name) {
00391             if (extensions->type == HEADER_EXT_TAG
00392              && !xstrcasecmp(extensions->name + 7, str)) {
00393                 ext = extensions;
00394             }
00395             extensions++;
00396             if (extensions->type == HEADER_EXT_MORE)
00397                 extensions = *extensions->u.more;
00398         }
00399     }
00400 
00401     /* Retrieve data from extension or header. */
00402     if (ext) {
00403         ext->u.tagFunction(s->h, he);
00404     } else {
00405         if (tag == (rpmTag)0xffffffff) {
00406             PyErr_SetString(PyExc_KeyError, "unknown header tag");
00407             return NULL;
00408         }
00409         
00410         he->tag = tag;
00411         xx = headerGet(s->h, he, 0);
00412         if (!xx) {
00413             he->p.ptr = _free(he->p.ptr);
00414             switch (tag) {
00415             case RPMTAG_EPOCH:
00416             case RPMTAG_NAME:
00417             case RPMTAG_VERSION:
00418             case RPMTAG_RELEASE:
00419             case RPMTAG_DISTEPOCH:
00420             case RPMTAG_ARCH:
00421             case RPMTAG_OS:
00422                 Py_INCREF(Py_None);
00423                 return Py_None;
00424                 break;
00425             default:
00426                 return PyList_New(0);
00427                 break;
00428             }
00429         }
00430     }
00431 
00432     switch (tag) {
00433     case RPMTAG_FILEPATHS:
00434     case RPMTAG_ORIGPATHS:
00435     case RPMTAG_OLDFILENAMES:
00436     case RPMTAG_FILESIZES:
00437     case RPMTAG_FILESTATES:
00438     case RPMTAG_FILEMODES:
00439     case RPMTAG_FILEUIDS:
00440     case RPMTAG_FILEGIDS:
00441     case RPMTAG_FILERDEVS:
00442     case RPMTAG_FILEMTIMES:
00443     case RPMTAG_FILEMD5S:
00444     case RPMTAG_FILELINKTOS:
00445     case RPMTAG_FILEFLAGS:
00446     case RPMTAG_ROOT:
00447     case RPMTAG_FILEUSERNAME:
00448     case RPMTAG_FILEGROUPNAME:
00449     case RPMTAG_REQUIRENAME:
00450     case RPMTAG_REQUIREFLAGS:
00451     case RPMTAG_REQUIREVERSION:
00452     case RPMTAG_PROVIDENAME:
00453     case RPMTAG_PROVIDEFLAGS:
00454     case RPMTAG_PROVIDEVERSION:
00455     case RPMTAG_OBSOLETENAME:
00456     case RPMTAG_OBSOLETEFLAGS:
00457     case RPMTAG_OBSOLETEVERSION:
00458     case RPMTAG_CONFLICTNAME:
00459     case RPMTAG_CONFLICTFLAGS:
00460     case RPMTAG_CONFLICTVERSION:
00461     case RPMTAG_CHANGELOGTIME:
00462     case RPMTAG_FILEVERIFYFLAGS:
00463         forceArray = 1;
00464         break;
00465     default:
00466         break;
00467     }
00468 
00469     switch (he->t) {
00470     case RPM_BIN_TYPE:
00471         o = PyString_FromStringAndSize(he->p.str, he->c);
00472         break;
00473 
00474     case RPM_UINT8_TYPE:
00475         if (he->c != 1 || forceArray) {
00476             metao = PyList_New(0);
00477             for (i = 0; i < he->c; i++) {
00478                 o = PyInt_FromLong(he->p.ui8p[i]);
00479                 PyList_Append(metao, o);
00480                 Py_DECREF(o);
00481             }
00482             o = metao;
00483         } else {
00484             o = PyInt_FromLong(he->p.ui8p[0]);
00485         }
00486         break;
00487 
00488     case RPM_UINT16_TYPE:
00489         if (he->c != 1 || forceArray) {
00490             metao = PyList_New(0);
00491             for (i = 0; i < he->c; i++) {
00492                 o = PyInt_FromLong(he->p.ui16p[i]);
00493                 PyList_Append(metao, o);
00494                 Py_DECREF(o);
00495             }
00496             o = metao;
00497         } else {
00498             o = PyInt_FromLong(he->p.ui16p[0]);
00499         }
00500         break;
00501 
00502     case RPM_UINT32_TYPE:
00503         if (he->c != 1 || forceArray) {
00504             metao = PyList_New(0);
00505             for (i = 0; i < he->c; i++) {
00506                 o = PyInt_FromLong(he->p.ui32p[i]);
00507                 PyList_Append(metao, o);
00508                 Py_DECREF(o);
00509             }
00510             o = metao;
00511         } else {
00512             o = PyInt_FromLong(he->p.ui32p[0]);
00513         }
00514         break;
00515 
00516     case RPM_UINT64_TYPE:
00517         if (he->c != 1 || forceArray) {
00518             metao = PyList_New(0);
00519             for (i = 0; i < he->c; i++) {
00520                 o = PyInt_FromLong(he->p.ui64p[i]);
00521                 PyList_Append(metao, o);
00522                 Py_DECREF(o);
00523             }
00524             o = metao;
00525         } else {
00526             o = PyInt_FromLong(he->p.ui64p[0]);
00527         }
00528         break;
00529 
00530     case RPM_STRING_ARRAY_TYPE:
00531         metao = PyList_New(0);
00532         for (i = 0; i < he->c; i++) {
00533             o = PyString_FromString(he->p.argv[i]);
00534             PyList_Append(metao, o);
00535             Py_DECREF(o);
00536         }
00537         o = metao;
00538         break;
00539 
00540     case RPM_STRING_TYPE:
00541         if (he->p.str != NULL)
00542             o = PyString_FromString(he->p.str);
00543         else
00544             o = PyString_FromString("");
00545         break;
00546 
00547     default:
00548         PyErr_SetString(PyExc_TypeError, "unsupported type in header");
00549         return NULL;
00550     }
00551     if (he->freeData)
00552         he->p.ptr = _free(he->p.ptr);
00553 
00554     return o;
00555 }
00556 
00559 /*@unchecked@*/ /*@observer@*/
00560 static PyMappingMethods hdr_as_mapping = {
00561         (lenfunc) 0,                    /* mp_length */
00562         (binaryfunc) hdr_subscript,     /* mp_subscript */
00563         (objobjargproc) 0,              /* mp_ass_subscript */
00564 };
00565 
00566 static PyObject * hdr_getattro(hdrObject * o, PyObject * n)
00567         /*@*/
00568 {
00569     PyObject * res;
00570     res = PyObject_GenericGetAttr((PyObject *)o, n);
00571     if (res == NULL)
00572         res = hdr_subscript(o, n);
00573     return res;
00574 }
00575 
00576 static int hdr_setattro(hdrObject * o, PyObject * n, PyObject * v)
00577         /*@*/
00578 {
00579     return PyObject_GenericSetAttr((PyObject *)o, n, v);
00580 }
00581 
00584 static char hdr_doc[] =
00585 "";
00586 
00589 /*@unchecked@*/ /*@observer@*/
00590 PyTypeObject hdr_Type = {
00591         PyObject_HEAD_INIT(&PyType_Type)
00592         0,                              /* ob_size */
00593         "rpm.hdr",                      /* tp_name */
00594         sizeof(hdrObject),              /* tp_size */
00595         0,                              /* tp_itemsize */
00596         (destructor) hdr_dealloc,       /* tp_dealloc */
00597         0,                              /* tp_print */
00598         (getattrfunc) 0,                /* tp_getattr */
00599         0,                              /* tp_setattr */
00600         (cmpfunc) hdr_compare,          /* tp_compare */
00601         0,                              /* tp_repr */
00602         0,                              /* tp_as_number */
00603         0,                              /* tp_as_sequence */
00604         &hdr_as_mapping,                /* tp_as_mapping */
00605         hdr_hash,                       /* tp_hash */
00606         0,                              /* tp_call */
00607         0,                              /* tp_str */
00608         (getattrofunc) hdr_getattro,    /* tp_getattro */
00609         (setattrofunc) hdr_setattro,    /* tp_setattro */
00610         0,                              /* tp_as_buffer */
00611         Py_TPFLAGS_DEFAULT,             /* tp_flags */
00612         hdr_doc,                        /* tp_doc */
00613 #if Py_TPFLAGS_HAVE_ITER
00614         0,                              /* tp_traverse */
00615         0,                              /* tp_clear */
00616         0,                              /* tp_richcompare */
00617         0,                              /* tp_weaklistoffset */
00618         0,                              /* tp_iter */
00619         0,                              /* tp_iternext */
00620         hdr_methods,                    /* tp_methods */
00621         0,                              /* tp_members */
00622         0,                              /* tp_getset */
00623         0,                              /* tp_base */
00624         0,                              /* tp_dict */
00625         0,                              /* tp_descr_get */
00626         0,                              /* tp_descr_set */
00627         0,                              /* tp_dictoffset */
00628         0,                              /* tp_init */
00629         0,                              /* tp_alloc */
00630         0,                              /* tp_new */
00631         0,                              /* tp_free */
00632         0,                              /* tp_is_gc */
00633 #endif
00634 };
00635 
00636 hdrObject * hdr_Wrap(Header h)
00637 {
00638     hdrObject * hdr = PyObject_New(hdrObject, &hdr_Type);
00639     hdr->h = headerLink(h);
00640     return hdr;
00641 }
00642 
00643 Header hdrGetHeader(hdrObject * s)
00644 {
00645     return s->h;
00646 }
00647 
00650 PyObject * hdrLoad(PyObject * self, PyObject * args, PyObject * kwds)
00651 {
00652     hdrObject * hdr;
00653     char * copy = NULL;
00654     char * obj;
00655     Header h;
00656     int len;
00657     char * kwlist[] = {"headers", NULL};
00658 
00659     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwlist, &obj, &len))
00660         return NULL;
00661 
00662     /* malloc is needed to avoid surprises from data swab in headerLoad(). */
00663     copy = malloc(len);
00664     if (copy == NULL) {
00665         PyErr_SetString(pyrpmError, "out of memory");
00666         return NULL;
00667     }
00668     memcpy (copy, obj, len);
00669 
00670     h = headerLoad(copy);
00671     if (!h) {
00672         PyErr_SetString(pyrpmError, "bad header");
00673         return NULL;
00674     }
00675     headerAllocated(h);
00676 
00677     hdr = hdr_Wrap(h);
00678     (void)headerFree(h);        /* XXX ref held by hdr */
00679     h = NULL;
00680 
00681     return (PyObject *) hdr;
00682 }
00683 
00686 PyObject * rpmReadHeaders (FD_t fd)
00687 {
00688     PyObject * list;
00689     Header h;
00690     hdrObject * hdr;
00691 
00692     if (!fd) {
00693         PyErr_SetFromErrno(pyrpmError);
00694         return NULL;
00695     }
00696 
00697     list = PyList_New(0);
00698     Py_BEGIN_ALLOW_THREADS
00699     {   const char item[] = "Header";
00700         const char * msg = NULL;
00701         rpmRC rc = rpmpkgRead(item, fd, &h, &msg);
00702         if(rc == RPMRC_NOTFOUND) {
00703                 Py_INCREF(Py_None);
00704                 list = Py_None;
00705         }
00706         else if (rc != RPMRC_OK)
00707             rpmlog(RPMLOG_ERR, "%s: %s: %s : error code: %d\n", "rpmpkgRead", item, msg, rc);
00708         msg = _free(msg);
00709     }
00710     Py_END_ALLOW_THREADS
00711 
00712     while (h) {
00713         hdr = hdr_Wrap(h);
00714         if (PyList_Append(list, (PyObject *) hdr)) {
00715             Py_DECREF(list);
00716             Py_DECREF(hdr);
00717             return NULL;
00718         }
00719         Py_DECREF(hdr);
00720 
00721         (void)headerFree(h);    /* XXX ref held by hdr */
00722         h = NULL;
00723 
00724         Py_BEGIN_ALLOW_THREADS
00725         {   const char item[] = "Header";
00726             const char * msg = NULL;
00727             rpmRC rc = rpmpkgRead(item, fd, &h, &msg);
00728             if(rc == RPMRC_NOTFOUND) {
00729                     Py_INCREF(Py_None);
00730                     list = Py_None;
00731             }
00732             else if (rc != RPMRC_OK)
00733                 rpmlog(RPMLOG_ERR, "%s: %s: %s : error code: %d\n", "rpmpkgRead", item, msg, rc);
00734             msg = _free(msg);
00735         }
00736         Py_END_ALLOW_THREADS
00737     }
00738 
00739     return list;
00740 }
00741 
00744 PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args,
00745                 PyObject * kwds)
00746 {
00747     FD_t fd;
00748     int fileno;
00749     PyObject * list;
00750     char * kwlist[] = {"fd", NULL};
00751 
00752     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
00753         return NULL;
00754 
00755     fd = fdDup(fileno);
00756 
00757     list = rpmReadHeaders (fd);
00758     Fclose(fd);
00759 
00760     return list;
00761 }
00762 
00765 PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args,
00766                 PyObject *kwds)
00767 {
00768     char * filespec;
00769     FD_t fd;
00770     PyObject * list;
00771     char * kwlist[] = {"file", NULL};
00772 
00773     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &filespec))
00774         return NULL;
00775 
00776     fd = Fopen(filespec, "r.fdio");
00777 
00778     if (!fd) {
00779         PyErr_SetFromErrno(pyrpmError);
00780         return NULL;
00781     }
00782 
00783     list = rpmReadHeaders (fd);
00784     Fclose(fd);
00785 
00786     return list;
00787 }
00788 
00791 PyObject *
00792 rpmSingleHeaderFromFD(PyObject * self, PyObject * args,
00793                 PyObject * kwds)
00794 {
00795     FD_t fd;
00796     int fileno;
00797     off_t offset;
00798     PyObject * tuple;
00799     Header h;
00800     char * kwlist[] = {"fd", NULL};
00801 
00802     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
00803         return NULL;
00804 
00805     offset = lseek(fileno, 0, SEEK_CUR);
00806 
00807     fd = fdDup(fileno);
00808 
00809     if (!fd) {
00810         PyErr_SetFromErrno(pyrpmError);
00811         return NULL;
00812     }
00813 
00814     Py_BEGIN_ALLOW_THREADS
00815     {   const char item[] = "Header";
00816         const char * msg = NULL;
00817         rpmRC rc = rpmpkgRead(item, fd, &h, &msg);
00818         if(rc == RPMRC_NOTFOUND) {
00819                 Py_INCREF(Py_None);
00820                 tuple = Py_None;
00821         }
00822         else if (rc != RPMRC_OK)
00823             rpmlog(RPMLOG_ERR, "%s: %s: %s : error code: %d\n", "rpmpkgRead", item, msg, rc);
00824         msg = _free(msg);
00825     }
00826     Py_END_ALLOW_THREADS
00827 
00828     Fclose(fd);
00829 
00830     tuple = PyTuple_New(2);
00831 
00832     if (h && tuple) {
00833         PyTuple_SET_ITEM(tuple, 0, (PyObject *) hdr_Wrap(h));
00834         PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(offset));
00835         (void)headerFree(h);
00836         h = NULL;
00837     } else {
00838         Py_INCREF(Py_None);
00839         Py_INCREF(Py_None);
00840         PyTuple_SET_ITEM(tuple, 0, Py_None);
00841         PyTuple_SET_ITEM(tuple, 1, Py_None);
00842     }
00843 
00844     return tuple;
00845 }
00846 
00849 PyObject * rpmWriteHeaders (PyObject * list, FD_t fd)
00850 {
00851     int count;
00852 
00853     if (!fd) {
00854         PyErr_SetFromErrno(pyrpmError);
00855         return NULL;
00856     }
00857 
00858     for(count = 0; count < PyList_Size(list); count++){
00859         Py_BEGIN_ALLOW_THREADS
00860         const char item[] = "Header";
00861         const char * msg = NULL;
00862         hdrObject * hdr = (hdrObject *)PyList_GetItem(list, count);
00863         rpmRC rc = rpmpkgWrite(item, fd, hdr->h, &msg);
00864         if (rc != RPMRC_OK)
00865             rpmlog(RPMLOG_ERR, "%s: %s: %s : error code: %d\n", "rpmpkgWrite", item, msg, rc);
00866         msg = _free(msg);
00867         Py_END_ALLOW_THREADS
00868     }
00869     
00870     Py_RETURN_TRUE;
00871 }
00872 
00875 PyObject * rpmHeaderToFD(PyObject * self, PyObject * args,
00876                 PyObject * kwds)
00877 {
00878     FD_t fd;
00879     int fileno;
00880     PyObject * list;
00881     PyObject * ret;
00882     char * kwlist[] = {"headers", "fd", NULL};
00883 
00884     if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi", kwlist, &list, &fileno))
00885         return NULL;
00886 
00887     fd = fdDup(fileno);
00888 
00889     ret = rpmWriteHeaders (list, fd);
00890     Fclose(fd);
00891 
00892     return list;
00893 }
00894 
00897 PyObject * rpmHeaderToFile(PyObject * self, PyObject * args,
00898                 PyObject *kwds)
00899 {
00900     char * filespec;
00901     FD_t fd;
00902     PyObject * list;
00903     PyObject * ret;
00904     char * kwlist[] = {"headers", "file", NULL};
00905 
00906     if (!PyArg_ParseTupleAndKeywords(args, kwds, "Os", kwlist, &list, &filespec))
00907         return NULL;
00908 
00909     fd = Fopen(filespec, "w.fdio");
00910     if (!fd) {
00911         PyErr_SetFromErrno(pyrpmError);
00912         return NULL;
00913     }
00914 
00915     ret = rpmWriteHeaders (list, fd);
00916     Fclose(fd);
00917 
00918     return ret; 
00919 } 
00920 
00923 PyObject * versionCompare (PyObject * self, PyObject * args,
00924                 PyObject * kwds)
00925 {
00926     hdrObject * h1, * h2;
00927     char * kwlist[] = {"version0", "version1", NULL};
00928 
00929     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!", kwlist, &hdr_Type,
00930             &h1, &hdr_Type, &h2))
00931         return NULL;
00932 
00933     return Py_BuildValue("i", hdr_compare(h1, h2));
00934 }
00935 
00936 PyObject * labelCompare (PyObject * self, PyObject * args)
00937 {
00938     EVR_t a = rpmEVRnew(RPMSENSE_EQUAL, 1);
00939     EVR_t b = rpmEVRnew(RPMSENSE_EQUAL, 1);
00940     int rc;
00941     PyObject *aTuple, *bTuple;
00942 
00943     if (!PyArg_ParseTuple(args, "OO", &aTuple, &bTuple) ||
00944             !PyArg_ParseTuple(aTuple, "zzz|z",
00945                 &a->F[RPMEVR_E], &a->F[RPMEVR_V], &a->F[RPMEVR_R], &a->F[RPMEVR_D]) ||
00946             !PyArg_ParseTuple(bTuple, "zzz|z",
00947                 &b->F[RPMEVR_E], &b->F[RPMEVR_V], &b->F[RPMEVR_R], &b->F[RPMEVR_D]))
00948     {
00949         a = rpmEVRfree(a);
00950         b = rpmEVRfree(b);
00951         return NULL;
00952     }
00953 
00954     /* XXX HACK: postpone committing to single "missing" value for now. */
00955     if (a->F[RPMEVR_E] == NULL) a->F[RPMEVR_E] = "0";
00956     if (b->F[RPMEVR_E] == NULL) b->F[RPMEVR_E] = "0";
00957     if (a->F[RPMEVR_V] == NULL) a->F[RPMEVR_V] = "";
00958     if (b->F[RPMEVR_V] == NULL) b->F[RPMEVR_V] = "";
00959     if (a->F[RPMEVR_R] == NULL) a->F[RPMEVR_R] = "";
00960     if (b->F[RPMEVR_R] == NULL) b->F[RPMEVR_R] = "";
00961     if (a->F[RPMEVR_D] == NULL) a->F[RPMEVR_D] = "";
00962     if (b->F[RPMEVR_D] == NULL) b->F[RPMEVR_D] = "";
00963 
00964     rc = rpmEVRcompare(a, b);
00965 
00966     a = rpmEVRfree(a);
00967     b = rpmEVRfree(b);
00968 
00969     return Py_BuildValue("i", rc);
00970 }
00971 
00972 PyObject * evrCompare (PyObject * self, PyObject * args,
00973                 PyObject * kwds)
00974 {
00975     EVR_t lEVR = rpmEVRnew(RPMSENSE_EQUAL, 0),
00976           rEVR = rpmEVRnew(RPMSENSE_EQUAL, 0);
00977     int rc;
00978     char * evr1, * evr2;
00979     char * kwlist[] = {"evr0", "evr1", NULL};
00980 
00981     if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss", kwlist, &evr1, &evr2))
00982         return NULL;
00983 
00984     rpmEVRparse(evr1, lEVR);
00985     rpmEVRparse(evr2, rEVR);
00986     rc = rpmEVRcompare(lEVR, rEVR);
00987     lEVR = rpmEVRfree(lEVR);
00988     rEVR = rpmEVRfree(rEVR);
00989 
00990     return PyLong_FromLong(rc);
00991 }
00992 
00993 PyObject * evrSplit (PyObject * self, PyObject * args, PyObject * kwds)
00994 {
00995     EVR_t EVR = rpmEVRnew(RPMSENSE_EQUAL, 0);
00996     char * evr;
00997     char * kwlist[] = {"evr", NULL};
00998     PyObject * tuple;
00999 
01000     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &evr))
01001         return NULL;
01002 
01003     rpmEVRparse(evr, EVR);
01004     tuple = Py_BuildValue("(Isss)", EVR->F[RPMEVR_E] ? atoi(EVR->F[RPMEVR_E]) : 0, EVR->F[RPMEVR_V], EVR->F[RPMEVR_R], EVR->F[RPMEVR_D]);
01005     EVR = rpmEVRfree(EVR);
01006 
01007     return tuple;
01008 }