Main Page Modules Data Structures File List Data Fields Globals Related Pages

# python/header-py.c

Go to the documentation of this file.

    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 "rpmio_internal.h"
    00014 #include "rpmcli.h"     /* XXX for rpmCheckSig */
    00015
    00016 #include "legacy.h"
    00017 #include "misc.h"
    00018 #include "header_internal.h"
    00019
    00020 #include "rpmts.h"      /* XXX rpmtsCreate/rpmtsFree */
    00021
    00022 #include "header-py.h"
    00023 #include "rpmds-py.h"
    00024 #include "rpmfi-py.h"
    00025
    00026 #include "debug.h"
    00027
    00090
    00093 struct hdrObject_s {
    00094     PyObject_HEAD
    00095     Header h;
    00096     char ** md5list;
    00097     char ** fileList;
    00098     char ** linkList;
    00099     int_32 * fileSizes;
    00100     int_32 * mtimes;
    00101     int_32 * uids, * gids;      /* XXX these tags are not used anymore */
    00102     unsigned short * rdevs;
    00103     unsigned short * modes;
    00104 } ;
    00105
    00106 /*@unused@*/ static inline Header headerAllocated(Header h)
    00107         /*@modifies h @*/
    00108 {
    00109     h->flags |= HEADERFLAG_ALLOCATED;
    00110     return 0;
    00111 }
    00112
    00115 static PyObject * hdrKeyList(hdrObject * s, PyObject * args)
    00116         /*@*/
    00117 {
    00118     PyObject * list, *o;
    00119     HeaderIterator hi;
    00120     int tag, type;
    00121
    00122     if (!PyArg_ParseTuple(args, "")) return NULL;
    00123
    00124     list = PyList_New(0);
    00125
    00126     hi = headerInitIterator(s->h);
    00127     while (headerNextIterator(hi, &tag, &type, NULL, NULL)) {
    00128         if (tag == HEADER_I18NTABLE) continue;
    00129
    00130         switch (type) {
    00131         case RPM_BIN_TYPE:
    00132         case RPM_INT32_TYPE:
    00133         case RPM_CHAR_TYPE:
    00134         case RPM_INT8_TYPE:
    00135         case RPM_INT16_TYPE:
    00136         case RPM_STRING_ARRAY_TYPE:
    00137         case RPM_STRING_TYPE:
    00138             PyList_Append(list, o=PyInt_FromLong(tag));
    00139             Py_DECREF(o);
    00140         }
    00141     }
    00142     headerFreeIterator(hi);
    00143
    00144     return list;
    00145 }
    00146
    00149 static PyObject * hdrUnload(hdrObject * s, PyObject * args, PyObject *keywords)
    00150         /*@*/
    00151 {
    00152     char * buf;
    00153     PyObject * rc;
    00154     int len, legacy = 0;
    00155     Header h;
    00156     static char *kwlist[] = { "legacyHeader", NULL};
    00157
    00158     if (!PyArg_ParseTupleAndKeywords(args, keywords, "|i", kwlist, &legacy))
    00159         return NULL;
    00160
    00161     h = headerLink(s->h);
    00162     /* XXX this legacy switch is a hack, needs to be removed. */
    00163     if (legacy) {
    00164         h = headerCopy(s->h);   /* XXX strip region tags, etc */
    00165         headerFree(s->h);
    00166     }
    00167     len = headerSizeof(h, 0);
    00168     buf = headerUnload(h);
    00169     h = headerFree(h);
    00170
    00171     if (buf == NULL || len == 0) {
    00172         PyErr_SetString(pyrpmError, "can't unload bad header\n");
    00173         return NULL;
    00174     }
    00175
    00176     rc = PyString_FromStringAndSize(buf, len);
    00177     buf = _free(buf);
    00178
    00179     return rc;
    00180 }
    00181
    00184 static PyObject * hdrExpandFilelist(hdrObject * s, PyObject * args)
    00185         /*@*/
    00186 {
    00187     expandFilelist (s->h);
    00188
    00189     Py_INCREF(Py_None);
    00190     return Py_None;
    00191 }
    00192
    00195 static PyObject * hdrCompressFilelist(hdrObject * s, PyObject * args)
    00196         /*@*/
    00197 {
    00198     compressFilelist (s->h);
    00199
    00200     Py_INCREF(Py_None);
    00201     return Py_None;
    00202 }
    00203
    00204 /* make a header with _all_ the tags we need */
    00207 static void mungeFilelist(Header h)
    00208         /*@*/
    00209 {
    00210     const char ** fileNames = NULL;
    00211     int count = 0;
    00212
    00213     if (!headerIsEntry (h, RPMTAG_BASENAMES)
    00214         || !headerIsEntry (h, RPMTAG_DIRNAMES)
    00215         || !headerIsEntry (h, RPMTAG_DIRINDEXES))
    00216         compressFilelist(h);
    00217
    00218     rpmBuildFileList(h, &fileNames, &count);
    00219
    00220     if (fileNames == NULL || count <= 0)
    00221         return;
    00222
    00223     /* XXX Legacy tag needs to go away. */
    00224     headerAddEntry(h, RPMTAG_OLDFILENAMES, RPM_STRING_ARRAY_TYPE,
    00225                         fileNames, count);
    00226
    00227     fileNames = _free(fileNames);
    00228 }
    00229
    00232 static PyObject * rhnUnload(hdrObject * s, PyObject * args)
    00233         /*@*/
    00234 {
    00235     int len;
    00236     char * uh;
    00237     PyObject * rc;
    00238     Header h;
    00239
    00240     if (!PyArg_ParseTuple(args, ""))
    00241         return NULL;
    00242
    00243     h = headerLink(s->h);
    00244
    00245     /* Retrofit a RHNPlatform: tag. */
    00246     if (!headerIsEntry(h, RPMTAG_RHNPLATFORM)) {
    00247         const char * arch;
    00248         int_32 at;
    00249         if (headerGetEntry(h, RPMTAG_ARCH, &at, (void **)&arch, NULL))
    00250             headerAddEntry(h, RPMTAG_RHNPLATFORM, at, arch, 1);
    00251     }
    00252
    00253     /* Legacy headers are forced into immutable region. */
    00254     if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
    00255         Header nh = headerReload(h, RPMTAG_HEADERIMMUTABLE);
    00256         /* XXX Another unload/load cycle to "seal" the immutable region. */
    00257         uh = headerUnload(nh);
    00258         headerFree(nh);
    00259         h = headerLoad(uh);
    00260         headerAllocated(h);
    00261     }
    00262
    00263     /* All headers have SHA1 digest, compute and add if necessary. */
    00264     if (!headerIsEntry(h, RPMTAG_SHA1HEADER)) {
    00265         int_32 uht, uhc;
    00266         const char * digest;
    00267         size_t digestlen;
    00268         DIGEST_CTX ctx;
    00269
    00270         headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, (void **)&uh, &uhc);
    00271
    00272         ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
    00273         rpmDigestUpdate(ctx, uh, uhc);
    00274         rpmDigestFinal(ctx, (void **)&digest, &digestlen, 1);
    00275
    00276         headerAddEntry(h, RPMTAG_SHA1RHN, RPM_STRING_TYPE, digest, 1);
    00277
    00278         uh = headerFreeData(uh, uht);
    00279         digest = _free(digest);
    00280     }
    00281
    00282     len = headerSizeof(h, 0);
    00283     uh = headerUnload(h);
    00284     headerFree(h);
    00285
    00286     rc = PyString_FromStringAndSize(uh, len);
    00287     uh = _free(uh);
    00288
    00289     return rc;
    00290 }
    00291
    00294 static PyObject * hdrFullFilelist(hdrObject * s, PyObject * args)
    00295         /*@*/
    00296 {
    00297     if (!PyArg_ParseTuple(args, ""))
    00298         return NULL;
    00299
    00300     mungeFilelist (s->h);
    00301
    00302     Py_INCREF(Py_None);
    00303     return Py_None;
    00304 }
    00305
    00308 static PyObject * hdrSprintf(hdrObject * s, PyObject * args)
    00309         /*@*/
    00310 {
    00311     char * fmt;
    00312     char * r;
    00313     errmsg_t err;
    00314     PyObject * result;
    00315
    00316     if (!PyArg_ParseTuple(args, "s", &fmt))
    00317         return NULL;
    00318
    00319     r = headerSprintf(s->h, fmt, rpmTagTable, rpmHeaderFormats, &err);
    00320     if (!r) {
    00321         PyErr_SetString(pyrpmError, err);
    00322         return NULL;
    00323     }
    00324
    00325     result = Py_BuildValue("s", r);
    00326     r = _free(r);
    00327
    00328     return result;
    00329 }
    00330
    00333 static int hdr_compare(hdrObject * a, hdrObject * b)
    00334         /*@*/
    00335 {
    00336     return rpmVersionCompare(a->h, b->h);
    00337 }
    00338
    00341 /*@unchecked@*/ /*@observer@*/
    00342 static struct PyMethodDef hdr_methods[] = {
    00343     {"keys",            (PyCFunction) hdrKeyList,       METH_VARARGS,
    00344         NULL },
    00345     {"unload",          (PyCFunction) hdrUnload,        METH_VARARGS|METH_KEYWORDS,
    00346         NULL },
    00347     {"expandFilelist",  (PyCFunction) hdrExpandFilelist,METH_VARARGS,
    00348         NULL },
    00349     {"compressFilelist",(PyCFunction) hdrCompressFilelist,METH_VARARGS,
    00350         NULL },
    00351     {"fullFilelist",    (PyCFunction) hdrFullFilelist,  METH_VARARGS,
    00352         NULL },
    00353     {"rhnUnload",       (PyCFunction) rhnUnload,        METH_VARARGS,
    00354         NULL },
    00355     {"sprintf",         (PyCFunction) hdrSprintf,       METH_VARARGS,
    00356         NULL },
    00357
    00358     {"dsOfHeader",      (PyCFunction)hdr_dsOfHeader,    METH_VARARGS,
    00359         NULL},
    00360     {"dsFromHeader",    (PyCFunction)hdr_dsFromHeader,  METH_VARARGS,
    00361         NULL},
    00362     {"fiFromHeader",    (PyCFunction)hdr_fiFromHeader,  METH_VARARGS,
    00363         NULL},
    00364
    00365     {NULL,              NULL}           /* sentinel */
    00366 };
    00367
    00370 static PyObject * hdr_getattr(hdrObject * s, char * name)
    00371         /*@*/
    00372 {
    00373     return Py_FindMethod(hdr_methods, (PyObject * ) s, name);
    00374 }
    00375
    00378 static void hdr_dealloc(hdrObject * s)
    00379         /*@*/
    00380 {
    00381     if (s->h) headerFree(s->h);
    00382     s->md5list = _free(s->md5list);
    00383     s->fileList = _free(s->fileList);
    00384     s->linkList = _free(s->linkList);
    00385     PyMem_DEL(s);
    00386 }
    00387
    00390 long tagNumFromPyObject (PyObject *item)
    00391 {
    00392     char * str;
    00393     int i;
    00394
    00395     if (PyInt_Check(item)) {
    00396         return PyInt_AsLong(item);
    00397     } else if (PyString_Check(item)) {
    00398         str = PyString_AsString(item);
    00399         for (i = 0; i < rpmTagTableSize; i++)
    00400             if (!xstrcasecmp(rpmTagTable[i].name + 7, str)) break;
    00401         if (i < rpmTagTableSize) return rpmTagTable[i].val;
    00402     }
    00403     return -1;
    00404 }
    00405
    00408 static PyObject * hdr_subscript(hdrObject * s, PyObject * item)
    00409         /*@*/
    00410 {
    00411     int type, count, i, tag = -1;
    00412     void * data;
    00413     PyObject * o, * metao;
    00414     char ** stringArray;
    00415     int forceArray = 0;
    00416     int freeData = 0;
    00417     char * str;
    00418     struct headerSprintfExtension_s * ext = NULL;
    00419     const struct headerSprintfExtension_s * extensions = rpmHeaderFormats;
    00420
    00421     if (PyCObject_Check (item))
    00422         ext = PyCObject_AsVoidPtr(item);
    00423     else
    00424         tag = tagNumFromPyObject (item);
    00425     if (tag == -1 && PyString_Check(item)) {
    00426         /* if we still don't have the tag, go looking for the header
    00427            extensions */
    00428         str = PyString_AsString(item);
    00429         while (extensions->name) {
    00430             if (extensions->type == HEADER_EXT_TAG
    00431                 && !xstrcasecmp(extensions->name + 7, str)) {
    00432                 (const struct headerSprintfExtension *) ext = extensions;
    00433             }
    00434             extensions++;
    00435         }
    00436     }
    00437
    00438     if (ext) {
    00439         ext->u.tagFunction(s->h, &type, (const void **) &data, &count, &freeData);
    00440     } else {
    00441         if (tag == -1) {
    00442             PyErr_SetString(PyExc_KeyError, "unknown header tag");
    00443             return NULL;
    00444         }
    00445
    00446         if (!rpmHeaderGetEntry(s->h, tag, &type, &data, &count)) {
    00447             Py_INCREF(Py_None);
    00448             return Py_None;
    00449         }
    00450     }
    00451
    00452     switch (tag) {
    00453     case RPMTAG_OLDFILENAMES:
    00454     case RPMTAG_FILESIZES:
    00455     case RPMTAG_FILESTATES:
    00456     case RPMTAG_FILEMODES:
    00457     case RPMTAG_FILEUIDS:
    00458     case RPMTAG_FILEGIDS:
    00459     case RPMTAG_FILERDEVS:
    00460     case RPMTAG_FILEMTIMES:
    00461     case RPMTAG_FILEMD5S:
    00462     case RPMTAG_FILELINKTOS:
    00463     case RPMTAG_FILEFLAGS:
    00464     case RPMTAG_ROOT:
    00465     case RPMTAG_FILEUSERNAME:
    00466     case RPMTAG_FILEGROUPNAME:
    00467         forceArray = 1;
    00468         break;
    00469     case RPMTAG_SUMMARY:
    00470     case RPMTAG_GROUP:
    00471     case RPMTAG_DESCRIPTION:
    00472         freeData = 1;
    00473         break;
    00474     default:
    00475         break;
    00476     }
    00477
    00478     switch (type) {
    00479     case RPM_BIN_TYPE:
    00480         o = PyString_FromStringAndSize(data, count);
    00481         break;
    00482
    00483     case RPM_INT32_TYPE:
    00484         if (count != 1 || forceArray) {
    00485             metao = PyList_New(0);
    00486             for (i = 0; i < count; i++) {
    00487                 o = PyInt_FromLong(((int *) data)[i]);
    00488                 PyList_Append(metao, o);
    00489                 Py_DECREF(o);
    00490             }
    00491             o = metao;
    00492         } else {
    00493             o = PyInt_FromLong(*((int *) data));
    00494         }
    00495         break;
    00496
    00497     case RPM_CHAR_TYPE:
    00498     case RPM_INT8_TYPE:
    00499         if (count != 1 || forceArray) {
    00500             metao = PyList_New(0);
    00501             for (i = 0; i < count; i++) {
    00502                 o = PyInt_FromLong(((char *) data)[i]);
    00503                 PyList_Append(metao, o);
    00504                 Py_DECREF(o);
    00505             }
    00506             o = metao;
    00507         } else {
    00508             o = PyInt_FromLong(*((char *) data));
    00509         }
    00510         break;
    00511
    00512     case RPM_INT16_TYPE:
    00513         if (count != 1 || forceArray) {
    00514             metao = PyList_New(0);
    00515             for (i = 0; i < count; i++) {
    00516                 o = PyInt_FromLong(((short *) data)[i]);
    00517                 PyList_Append(metao, o);
    00518                 Py_DECREF(o);
    00519             }
    00520             o = metao;
    00521         } else {
    00522             o = PyInt_FromLong(*((short *) data));
    00523         }
    00524         break;
    00525
    00526     case RPM_STRING_ARRAY_TYPE:
    00527         stringArray = data;
    00528
    00529         metao = PyList_New(0);
    00530         for (i = 0; i < count; i++) {
    00531             o = PyString_FromString(stringArray[i]);
    00532             PyList_Append(metao, o);
    00533             Py_DECREF(o);
    00534         }
    00535         free (stringArray);
    00536         o = metao;
    00537         break;
    00538
    00539     case RPM_STRING_TYPE:
    00540         if (count != 1 || forceArray) {
    00541             stringArray = data;
    00542
    00543             metao = PyList_New(0);
    00544             for (i=0; i < count; i++) {
    00545                 o = PyString_FromString(stringArray[i]);
    00546                 PyList_Append(metao, o);
    00547                 Py_DECREF(o);
    00548             }
    00549             o = metao;
    00550         } else {
    00551             o = PyString_FromString(data);
    00552             if (freeData)
    00553                 free (data);
    00554         }
    00555         break;
    00556
    00557     default:
    00558         PyErr_SetString(PyExc_TypeError, "unsupported type in header");
    00559         return NULL;
    00560     }
    00561
    00562     return o;
    00563 }
    00564
    00567 /*@unchecked@*/ /*@observer@*/
    00568 static PyMappingMethods hdr_as_mapping = {
    00569         (inquiry) 0,                    /* mp_length */
    00570         (binaryfunc) hdr_subscript,     /* mp_subscript */
    00571         (objobjargproc)0,               /* mp_ass_subscript */
    00572 };
    00573
    00576 static char hdr_doc[] =
    00577 "";
    00578
    00581 /*@unchecked@*/ /*@observer@*/
    00582 PyTypeObject hdr_Type = {
    00583         PyObject_HEAD_INIT(NULL)
    00584         0,                              /* ob_size */
    00585         "rpm.hdr",                      /* tp_name */
    00586         sizeof(hdrObject),              /* tp_size */
    00587         0,                              /* tp_itemsize */
    00588         (destructor) hdr_dealloc,       /* tp_dealloc */
    00589         0,                              /* tp_print */
    00590         (getattrfunc) hdr_getattr,      /* tp_getattr */
    00591         0,                              /* tp_setattr */
    00592         (cmpfunc) hdr_compare,          /* tp_compare */
    00593         0,                              /* tp_repr */
    00594         0,                              /* tp_as_number */
    00595         0,                              /* tp_as_sequence */
    00596         &hdr_as_mapping,                /* tp_as_mapping */
    00597         0,                              /* tp_hash */
    00598         0,                              /* tp_call */
    00599         0,                              /* tp_str */
    00600         0,                              /* tp_getattro */
    00601         0,                              /* tp_setattro */
    00602         0,                              /* tp_as_buffer */
    00603         Py_TPFLAGS_DEFAULT,             /* tp_flags */
    00604         hdr_doc,                        /* tp_doc */
    00605 #if Py_TPFLAGS_HAVE_ITER
    00606         0,                              /* tp_traverse */
    00607         0,                              /* tp_clear */
    00608         0,                              /* tp_richcompare */
    00609         0,                              /* tp_weaklistoffset */
    00610         0,                              /* tp_iter */
    00611         0,                              /* tp_iternext */
    00612         hdr_methods,                    /* tp_methods */
    00613         0,                              /* tp_members */
    00614         0,                              /* tp_getset */
    00615         0,                              /* tp_base */
    00616         0,                              /* tp_dict */
    00617         0,                              /* tp_descr_get */
    00618         0,                              /* tp_descr_set */
    00619         0,                              /* tp_dictoffset */
    00620         0,                              /* tp_init */
    00621         0,                              /* tp_alloc */
    00622         0,                              /* tp_new */
    00623         0,                              /* tp_free */
    00624         0,                              /* tp_is_gc */
    00625 #endif
    00626 };
    00627
    00628 hdrObject * hdr_Wrap(Header h)
    00629 {
    00630     hdrObject * hdr = PyObject_NEW(hdrObject, &hdr_Type);
    00631     hdr->h = headerLink(h);
    00632     hdr->fileList = hdr->linkList = hdr->md5list = NULL;
    00633     hdr->uids = hdr->gids = hdr->mtimes = hdr->fileSizes = NULL;
    00634     hdr->modes = hdr->rdevs = NULL;
    00635     return hdr;
    00636 }
    00637
    00638 Header hdrGetHeader(hdrObject * s)
    00639 {
    00640     return s->h;
    00641 }
    00642
    00645 PyObject * hdrLoad(PyObject * self, PyObject * args)
    00646 {
    00647     hdrObject * hdr;
    00648     char * copy = NULL;
    00649     char * obj;
    00650     Header h;
    00651     int len;
    00652
    00653     if (!PyArg_ParseTuple(args, "s#", &obj, &len)) return NULL;
    00654
    00655     /* malloc is needed to avoid surprises from data swab in headerLoad(). */
    00656     copy = malloc(len);
    00657     if (copy == NULL) {
    00658         PyErr_SetString(pyrpmError, "out of memory");
    00659         return NULL;
    00660     }
    00661     memcpy (copy, obj, len);
    00662
    00663     h = headerLoad(copy);
    00664     if (!h) {
    00665         PyErr_SetString(pyrpmError, "bad header");
    00666         return NULL;
    00667     }
    00668     headerAllocated(h);
    00669     compressFilelist (h);
    00670     providePackageNVR (h);
    00671
    00672     hdr = hdr_Wrap(h);
    00673     h = headerFree(h);  /* XXX ref held by hdr */
    00674
    00675     return (PyObject *) hdr;
    00676 }
    00677
    00680 PyObject * rhnLoad(PyObject * self, PyObject * args)
    00681 {
    00682     char * obj, * copy=NULL;
    00683     Header h;
    00684     int len;
    00685
    00686     if (!PyArg_ParseTuple(args, "s#", &obj, &len)) return NULL;
    00687
    00688     /* malloc is needed to avoid surprises from data swab in headerLoad(). */
    00689     copy = malloc(len);
    00690     if (copy == NULL) {
    00691         PyErr_SetString(pyrpmError, "out of memory");
    00692         return NULL;
    00693     }
    00694     memcpy (copy, obj, len);
    00695
    00696     h = headerLoad(copy);
    00697     if (!h) {
    00698         PyErr_SetString(pyrpmError, "bad header");
    00699         return NULL;
    00700     }
    00701     headerAllocated(h);
    00702
    00703     /* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
    00704     if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
    00705         PyErr_SetString(pyrpmError, "bad header, not immutable");
    00706         headerFree(h);
    00707         return NULL;
    00708     }
    00709
    00710     /* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
    00711     if (!headerIsEntry(h, RPMTAG_SHA1HEADER)
    00712     &&  !headerIsEntry(h, RPMTAG_SHA1RHN)) {
    00713         PyErr_SetString(pyrpmError, "bad header, no digest");
    00714         headerFree(h);
    00715         return NULL;
    00716     }
    00717
    00718     /* Retrofit a RHNPlatform: tag. */
    00719     if (!headerIsEntry(h, RPMTAG_RHNPLATFORM)) {
    00720         const char * arch;
    00721         int_32 at;
    00722         if (headerGetEntry(h, RPMTAG_ARCH, &at, (void **)&arch, NULL))
    00723             headerAddEntry(h, RPMTAG_RHNPLATFORM, at, arch, 1);
    00724     }
    00725
    00726     return (PyObject *) hdr_Wrap(h);
    00727 }
    00728
    00731 PyObject * rpmReadHeaders (FD_t fd)
    00732 {
    00733     PyObject * list;
    00734     Header h;
    00735     hdrObject * hdr;
    00736
    00737     if (!fd) {
    00738         PyErr_SetFromErrno(pyrpmError);
    00739         return NULL;
    00740     }
    00741
    00742     list = PyList_New(0);
    00743     Py_BEGIN_ALLOW_THREADS
    00744     h = headerRead(fd, HEADER_MAGIC_YES);
    00745     Py_END_ALLOW_THREADS
    00746
    00747     while (h) {
    00748         compressFilelist(h);
    00749         providePackageNVR(h);
    00750         hdr = hdr_Wrap(h);
    00751         if (PyList_Append(list, (PyObject *) hdr)) {
    00752             Py_DECREF(list);
    00753             Py_DECREF(hdr);
    00754             return NULL;
    00755         }
    00756         Py_DECREF(hdr);
    00757
    00758         h = headerFree(h);      /* XXX ref held by hdr */
    00759
    00760         Py_BEGIN_ALLOW_THREADS
    00761         h = headerRead(fd, HEADER_MAGIC_YES);
    00762         Py_END_ALLOW_THREADS
    00763     }
    00764
    00765     return list;
    00766 }
    00767
    00770 PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args)
    00771 {
    00772     FD_t fd;
    00773     int fileno;
    00774     PyObject * list;
    00775
    00776     if (!PyArg_ParseTuple(args, "i", &fileno)) return NULL;
    00777     fd = fdDup(fileno);
    00778
    00779     list = rpmReadHeaders (fd);
    00780     Fclose(fd);
    00781
    00782     return list;
    00783 }
    00784
    00787 PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args)
    00788 {
    00789     char * filespec;
    00790     FD_t fd;
    00791     PyObject * list;
    00792
    00793     if (!PyArg_ParseTuple(args, "s", &filespec)) return NULL;
    00794     fd = Fopen(filespec, "r.fdio");
    00795
    00796     if (!fd) {
    00797         PyErr_SetFromErrno(pyrpmError);
    00798         return NULL;
    00799     }
    00800
    00801     list = rpmReadHeaders (fd);
    00802     Fclose(fd);
    00803
    00804     return list;
    00805 }
    00806
    00811 int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag)
    00812 {
    00813     Header h;
    00814     HeaderIterator hi;
    00815     int_32 * newMatch;
    00816     int_32 * oldMatch;
    00817     hdrObject * hdr;
    00818     int count = 0;
    00819     int type, c, tag;
    00820     void * p;
    00821
    00822     Py_BEGIN_ALLOW_THREADS
    00823     h = headerRead(fd, HEADER_MAGIC_YES);
    00824     Py_END_ALLOW_THREADS
    00825
    00826     while (h) {
    00827         if (!headerGetEntry(h, matchTag, NULL, (void **) &newMatch, NULL)) {
    00828             PyErr_SetString(pyrpmError, "match tag missing in new header");
    00829             return 1;
    00830         }
    00831
    00832         hdr = (hdrObject *) PyList_GetItem(list, count++);
    00833         if (!hdr) return 1;
    00834
    00835         if (!headerGetEntry(hdr->h, matchTag, NULL, (void **) &oldMatch, NULL)) {
    00836             PyErr_SetString(pyrpmError, "match tag missing in new header");
    00837             return 1;
    00838         }
    00839
    00840         if (*newMatch != *oldMatch) {
    00841             PyErr_SetString(pyrpmError, "match tag mismatch");
    00842             return 1;
    00843         }
    00844
    00845         hdr->md5list = _free(hdr->md5list);
    00846         hdr->fileList = _free(hdr->fileList);
    00847         hdr->linkList = _free(hdr->linkList);
    00848
    00849         for (hi = headerInitIterator(h);
    00850             headerNextIterator(hi, &tag, &type, (void *) &p, &c);
    00851             p = headerFreeData(p, type))
    00852         {
    00853             /* could be dupes */
    00854             headerRemoveEntry(hdr->h, tag);
    00855             headerAddEntry(hdr->h, tag, type, p, c);
    00856         }
    00857
    00858         headerFreeIterator(hi);
    00859
    00860         Py_BEGIN_ALLOW_THREADS
    00861         h = headerRead(fd, HEADER_MAGIC_YES);
    00862         Py_END_ALLOW_THREADS
    00863     }
    00864
    00865     return 0;
    00866 }
    00867
    00868 PyObject * rpmMergeHeadersFromFD(PyObject * self, PyObject * args)
    00869 {
    00870     FD_t fd;
    00871     int fileno;
    00872     PyObject * list;
    00873     int rc;
    00874     int matchTag;
    00875
    00876     if (!PyArg_ParseTuple(args, "Oii", &list, &fileno, &matchTag))
    00877         return NULL;
    00878
    00879     if (!PyList_Check(list)) {
    00880         PyErr_SetString(PyExc_TypeError, "first parameter must be a list");
    00881         return NULL;
    00882     }
    00883
    00884     fd = fdDup(fileno);
    00885
    00886     rc = rpmMergeHeaders (list, fd, matchTag);
    00887     Fclose(fd);
    00888
    00889     if (rc) {
    00890         return NULL;
    00891     }
    00892
    00893     Py_INCREF(Py_None);
    00894     return Py_None;
    00895 }
    00896
    00899 PyObject * versionCompare (PyObject * self, PyObject * args)
    00900 {
    00901     hdrObject * h1, * h2;
    00902
    00903     if (!PyArg_ParseTuple(args, "O!O!", &hdr_Type, &h1, &hdr_Type, &h2))
    00904         return NULL;
    00905
    00906     return Py_BuildValue("i", hdr_compare(h1, h2));
    00907 }
    00908
    00911 PyObject * labelCompare (PyObject * self, PyObject * args)
    00912 {
    00913     char *v1, *r1, *e1, *v2, *r2, *e2;
    00914     int rc;
    00915
    00916     if (!PyArg_ParseTuple(args, "(zzz)(zzz)",
    00917                           &e1, &v1, &r1,
    00918                           &e2, &v2, &r2)) return NULL;
    00919
    00920     if (e1 && !e2)
    00921         return Py_BuildValue("i", 1);
    00922     else if (!e1 && e2)
    00923         return Py_BuildValue("i", -1);
    00924     else if (e1 && e2) {
    00925         int ep1, ep2;
    00926         ep1 = atoi (e1);
    00927         ep2 = atoi (e2);
    00928         if (ep1 < ep2)
    00929             return Py_BuildValue("i", -1);
    00930         else if (ep1 > ep2)
    00931             return Py_BuildValue("i", 1);
    00932     }
    00933
    00934     rc = rpmvercmp(v1, v2);
    00935     if (rc)
    00936         return Py_BuildValue("i", rc);
    00937
    00938     return Py_BuildValue("i", rpmvercmp(r1, r2));
    00939 }
    00940