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"
00015
00016 #include "legacy.h"
00017 #include "misc.h"
00018 #include "header_internal.h"
00019
00020 #include "rpmts.h"
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;
00102 unsigned short * rdevs;
00103 unsigned short * modes;
00104 } ;
00105
00106 static inline Header headerAllocated(Header h)
00107
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
00163 if (legacy) {
00164 h = headerCopy(s->h);
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
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 rpmfiBuildFNames(h, RPMTAG_BASENAMES, &fileNames, &count);
00219
00220 if (fileNames == NULL || count <= 0)
00221 return;
00222
00223
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
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
00254 if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
00255 Header nh = headerReload(h, RPMTAG_HEADERIMMUTABLE);
00256
00257 uh = headerUnload(nh);
00258 headerFree(nh);
00259 h = headerLoad(uh);
00260 headerAllocated(h);
00261 }
00262
00263
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
00339 static long hdr_hash(PyObject * h)
00340 {
00341 return (long) h;
00342 }
00343
00346
00347 static struct PyMethodDef hdr_methods[] = {
00348 {"keys", (PyCFunction) hdrKeyList, METH_VARARGS,
00349 NULL },
00350 {"unload", (PyCFunction) hdrUnload, METH_VARARGS|METH_KEYWORDS,
00351 NULL },
00352 {"expandFilelist", (PyCFunction) hdrExpandFilelist,METH_VARARGS,
00353 NULL },
00354 {"compressFilelist",(PyCFunction) hdrCompressFilelist,METH_VARARGS,
00355 NULL },
00356 {"fullFilelist", (PyCFunction) hdrFullFilelist, METH_VARARGS,
00357 NULL },
00358 {"rhnUnload", (PyCFunction) rhnUnload, METH_VARARGS,
00359 NULL },
00360 {"sprintf", (PyCFunction) hdrSprintf, METH_VARARGS,
00361 NULL },
00362
00363 {"dsOfHeader", (PyCFunction)hdr_dsOfHeader, METH_VARARGS,
00364 NULL},
00365 {"dsFromHeader", (PyCFunction)hdr_dsFromHeader, METH_VARARGS,
00366 NULL},
00367 {"fiFromHeader", (PyCFunction)hdr_fiFromHeader, METH_VARARGS,
00368 NULL},
00369
00370 {NULL, NULL}
00371 };
00372
00375 static PyObject * hdr_getattr(hdrObject * s, char * name)
00376
00377 {
00378 return Py_FindMethod(hdr_methods, (PyObject * ) s, name);
00379 }
00380
00383 static void hdr_dealloc(hdrObject * s)
00384
00385 {
00386 if (s->h) headerFree(s->h);
00387 s->md5list = _free(s->md5list);
00388 s->fileList = _free(s->fileList);
00389 s->linkList = _free(s->linkList);
00390 PyObject_Del(s);
00391 }
00392
00395 long tagNumFromPyObject (PyObject *item)
00396 {
00397 char * str;
00398 int i;
00399
00400 if (PyInt_Check(item)) {
00401 return PyInt_AsLong(item);
00402 } else if (PyString_Check(item)) {
00403 str = PyString_AsString(item);
00404 for (i = 0; i < rpmTagTableSize; i++)
00405 if (!xstrcasecmp(rpmTagTable[i].name + 7, str)) break;
00406 if (i < rpmTagTableSize) return rpmTagTable[i].val;
00407 }
00408 return -1;
00409 }
00410
00413 static PyObject * hdr_subscript(hdrObject * s, PyObject * item)
00414
00415 {
00416 int type, count, i, tag = -1;
00417 void * data;
00418 PyObject * o, * metao;
00419 char ** stringArray;
00420 int forceArray = 0;
00421 int freeData = 0;
00422 char * str;
00423 struct headerSprintfExtension_s * ext = NULL;
00424 const struct headerSprintfExtension_s * extensions = rpmHeaderFormats;
00425
00426 if (PyCObject_Check (item))
00427 ext = PyCObject_AsVoidPtr(item);
00428 else
00429 tag = tagNumFromPyObject (item);
00430 if (tag == -1 && PyString_Check(item)) {
00431
00432
00433 str = PyString_AsString(item);
00434 while (extensions->name) {
00435 if (extensions->type == HEADER_EXT_TAG
00436 && !xstrcasecmp(extensions->name + 7, str)) {
00437 (const struct headerSprintfExtension *) ext = extensions;
00438 }
00439 extensions++;
00440 }
00441 }
00442
00443 if (ext) {
00444 ext->u.tagFunction(s->h, &type, (const void **) &data, &count, &freeData);
00445 } else {
00446 if (tag == -1) {
00447 PyErr_SetString(PyExc_KeyError, "unknown header tag");
00448 return NULL;
00449 }
00450
00451 if (!rpmHeaderGetEntry(s->h, tag, &type, &data, &count)) {
00452 Py_INCREF(Py_None);
00453 return Py_None;
00454 }
00455 }
00456
00457 switch (tag) {
00458 case RPMTAG_OLDFILENAMES:
00459 case RPMTAG_FILESIZES:
00460 case RPMTAG_FILESTATES:
00461 case RPMTAG_FILEMODES:
00462 case RPMTAG_FILEUIDS:
00463 case RPMTAG_FILEGIDS:
00464 case RPMTAG_FILERDEVS:
00465 case RPMTAG_FILEMTIMES:
00466 case RPMTAG_FILEMD5S:
00467 case RPMTAG_FILELINKTOS:
00468 case RPMTAG_FILEFLAGS:
00469 case RPMTAG_ROOT:
00470 case RPMTAG_FILEUSERNAME:
00471 case RPMTAG_FILEGROUPNAME:
00472 forceArray = 1;
00473 break;
00474 case RPMTAG_SUMMARY:
00475 case RPMTAG_GROUP:
00476 case RPMTAG_DESCRIPTION:
00477 freeData = 1;
00478 break;
00479 default:
00480 break;
00481 }
00482
00483 switch (type) {
00484 case RPM_BIN_TYPE:
00485 o = PyString_FromStringAndSize(data, count);
00486 break;
00487
00488 case RPM_INT32_TYPE:
00489 if (count != 1 || forceArray) {
00490 metao = PyList_New(0);
00491 for (i = 0; i < count; i++) {
00492 o = PyInt_FromLong(((int *) data)[i]);
00493 PyList_Append(metao, o);
00494 Py_DECREF(o);
00495 }
00496 o = metao;
00497 } else {
00498 o = PyInt_FromLong(*((int *) data));
00499 }
00500 break;
00501
00502 case RPM_CHAR_TYPE:
00503 case RPM_INT8_TYPE:
00504 if (count != 1 || forceArray) {
00505 metao = PyList_New(0);
00506 for (i = 0; i < count; i++) {
00507 o = PyInt_FromLong(((char *) data)[i]);
00508 PyList_Append(metao, o);
00509 Py_DECREF(o);
00510 }
00511 o = metao;
00512 } else {
00513 o = PyInt_FromLong(*((char *) data));
00514 }
00515 break;
00516
00517 case RPM_INT16_TYPE:
00518 if (count != 1 || forceArray) {
00519 metao = PyList_New(0);
00520 for (i = 0; i < count; i++) {
00521 o = PyInt_FromLong(((short *) data)[i]);
00522 PyList_Append(metao, o);
00523 Py_DECREF(o);
00524 }
00525 o = metao;
00526 } else {
00527 o = PyInt_FromLong(*((short *) data));
00528 }
00529 break;
00530
00531 case RPM_STRING_ARRAY_TYPE:
00532 stringArray = data;
00533
00534 metao = PyList_New(0);
00535 for (i = 0; i < count; i++) {
00536 o = PyString_FromString(stringArray[i]);
00537 PyList_Append(metao, o);
00538 Py_DECREF(o);
00539 }
00540 free (stringArray);
00541 o = metao;
00542 break;
00543
00544 case RPM_STRING_TYPE:
00545 if (count != 1 || forceArray) {
00546 stringArray = data;
00547
00548 metao = PyList_New(0);
00549 for (i=0; i < count; i++) {
00550 o = PyString_FromString(stringArray[i]);
00551 PyList_Append(metao, o);
00552 Py_DECREF(o);
00553 }
00554 o = metao;
00555 } else {
00556 o = PyString_FromString(data);
00557 if (freeData)
00558 free (data);
00559 }
00560 break;
00561
00562 default:
00563 PyErr_SetString(PyExc_TypeError, "unsupported type in header");
00564 return NULL;
00565 }
00566
00567 return o;
00568 }
00569
00572
00573 static PyMappingMethods hdr_as_mapping = {
00574 (inquiry) 0,
00575 (binaryfunc) hdr_subscript,
00576 (objobjargproc)0,
00577 };
00578
00581 static char hdr_doc[] =
00582 "";
00583
00586
00587 PyTypeObject hdr_Type = {
00588 PyObject_HEAD_INIT(&PyType_Type)
00589 0,
00590 "rpm.hdr",
00591 sizeof(hdrObject),
00592 0,
00593 (destructor) hdr_dealloc,
00594 0,
00595 (getattrfunc) hdr_getattr,
00596 0,
00597 (cmpfunc) hdr_compare,
00598 0,
00599 0,
00600 0,
00601 &hdr_as_mapping,
00602 hdr_hash,
00603 0,
00604 0,
00605 0,
00606 0,
00607 0,
00608 Py_TPFLAGS_DEFAULT,
00609 hdr_doc,
00610 #if Py_TPFLAGS_HAVE_ITER
00611 0,
00612 0,
00613 0,
00614 0,
00615 0,
00616 0,
00617 hdr_methods,
00618 0,
00619 0,
00620 0,
00621 0,
00622 0,
00623 0,
00624 0,
00625 0,
00626 0,
00627 0,
00628 0,
00629 0,
00630 #endif
00631 };
00632
00633 hdrObject * hdr_Wrap(Header h)
00634 {
00635 hdrObject * hdr = PyObject_New(hdrObject, &hdr_Type);
00636 hdr->h = headerLink(h);
00637 hdr->fileList = hdr->linkList = hdr->md5list = NULL;
00638 hdr->uids = hdr->gids = hdr->mtimes = hdr->fileSizes = NULL;
00639 hdr->modes = hdr->rdevs = NULL;
00640 return hdr;
00641 }
00642
00643 Header hdrGetHeader(hdrObject * s)
00644 {
00645 return s->h;
00646 }
00647
00650 PyObject * hdrLoad(PyObject * self, PyObject * args)
00651 {
00652 hdrObject * hdr;
00653 char * copy = NULL;
00654 char * obj;
00655 Header h;
00656 int len;
00657
00658 if (!PyArg_ParseTuple(args, "s#", &obj, &len)) return NULL;
00659
00660
00661 copy = malloc(len);
00662 if (copy == NULL) {
00663 PyErr_SetString(pyrpmError, "out of memory");
00664 return NULL;
00665 }
00666 memcpy (copy, obj, len);
00667
00668 h = headerLoad(copy);
00669 if (!h) {
00670 PyErr_SetString(pyrpmError, "bad header");
00671 return NULL;
00672 }
00673 headerAllocated(h);
00674 compressFilelist (h);
00675 providePackageNVR (h);
00676
00677 hdr = hdr_Wrap(h);
00678 h = headerFree(h);
00679
00680 return (PyObject *) hdr;
00681 }
00682
00685 PyObject * rhnLoad(PyObject * self, PyObject * args)
00686 {
00687 char * obj, * copy=NULL;
00688 Header h;
00689 int len;
00690
00691 if (!PyArg_ParseTuple(args, "s#", &obj, &len)) return NULL;
00692
00693
00694 copy = malloc(len);
00695 if (copy == NULL) {
00696 PyErr_SetString(pyrpmError, "out of memory");
00697 return NULL;
00698 }
00699 memcpy (copy, obj, len);
00700
00701 h = headerLoad(copy);
00702 if (!h) {
00703 PyErr_SetString(pyrpmError, "bad header");
00704 return NULL;
00705 }
00706 headerAllocated(h);
00707
00708
00709 if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
00710 PyErr_SetString(pyrpmError, "bad header, not immutable");
00711 headerFree(h);
00712 return NULL;
00713 }
00714
00715
00716 if (!headerIsEntry(h, RPMTAG_SHA1HEADER)
00717 && !headerIsEntry(h, RPMTAG_SHA1RHN)) {
00718 PyErr_SetString(pyrpmError, "bad header, no digest");
00719 headerFree(h);
00720 return NULL;
00721 }
00722
00723
00724 if (!headerIsEntry(h, RPMTAG_RHNPLATFORM)) {
00725 const char * arch;
00726 int_32 at;
00727 if (headerGetEntry(h, RPMTAG_ARCH, &at, (void **)&arch, NULL))
00728 headerAddEntry(h, RPMTAG_RHNPLATFORM, at, arch, 1);
00729 }
00730
00731 return (PyObject *) hdr_Wrap(h);
00732 }
00733
00736 PyObject * rpmReadHeaders (FD_t fd)
00737 {
00738 PyObject * list;
00739 Header h;
00740 hdrObject * hdr;
00741
00742 if (!fd) {
00743 PyErr_SetFromErrno(pyrpmError);
00744 return NULL;
00745 }
00746
00747 list = PyList_New(0);
00748 Py_BEGIN_ALLOW_THREADS
00749 h = headerRead(fd, HEADER_MAGIC_YES);
00750 Py_END_ALLOW_THREADS
00751
00752 while (h) {
00753 compressFilelist(h);
00754 providePackageNVR(h);
00755 hdr = hdr_Wrap(h);
00756 if (PyList_Append(list, (PyObject *) hdr)) {
00757 Py_DECREF(list);
00758 Py_DECREF(hdr);
00759 return NULL;
00760 }
00761 Py_DECREF(hdr);
00762
00763 h = headerFree(h);
00764
00765 Py_BEGIN_ALLOW_THREADS
00766 h = headerRead(fd, HEADER_MAGIC_YES);
00767 Py_END_ALLOW_THREADS
00768 }
00769
00770 return list;
00771 }
00772
00775 PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args)
00776 {
00777 FD_t fd;
00778 int fileno;
00779 PyObject * list;
00780
00781 if (!PyArg_ParseTuple(args, "i", &fileno)) return NULL;
00782 fd = fdDup(fileno);
00783
00784 list = rpmReadHeaders (fd);
00785 Fclose(fd);
00786
00787 return list;
00788 }
00789
00792 PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args)
00793 {
00794 char * filespec;
00795 FD_t fd;
00796 PyObject * list;
00797
00798 if (!PyArg_ParseTuple(args, "s", &filespec)) return NULL;
00799 fd = Fopen(filespec, "r.fdio");
00800
00801 if (!fd) {
00802 PyErr_SetFromErrno(pyrpmError);
00803 return NULL;
00804 }
00805
00806 list = rpmReadHeaders (fd);
00807 Fclose(fd);
00808
00809 return list;
00810 }
00811
00816 int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag)
00817 {
00818 Header h;
00819 HeaderIterator hi;
00820 int_32 * newMatch;
00821 int_32 * oldMatch;
00822 hdrObject * hdr;
00823 int count = 0;
00824 int type, c, tag;
00825 void * p;
00826
00827 Py_BEGIN_ALLOW_THREADS
00828 h = headerRead(fd, HEADER_MAGIC_YES);
00829 Py_END_ALLOW_THREADS
00830
00831 while (h) {
00832 if (!headerGetEntry(h, matchTag, NULL, (void **) &newMatch, NULL)) {
00833 PyErr_SetString(pyrpmError, "match tag missing in new header");
00834 return 1;
00835 }
00836
00837 hdr = (hdrObject *) PyList_GetItem(list, count++);
00838 if (!hdr) return 1;
00839
00840 if (!headerGetEntry(hdr->h, matchTag, NULL, (void **) &oldMatch, NULL)) {
00841 PyErr_SetString(pyrpmError, "match tag missing in new header");
00842 return 1;
00843 }
00844
00845 if (*newMatch != *oldMatch) {
00846 PyErr_SetString(pyrpmError, "match tag mismatch");
00847 return 1;
00848 }
00849
00850 hdr->md5list = _free(hdr->md5list);
00851 hdr->fileList = _free(hdr->fileList);
00852 hdr->linkList = _free(hdr->linkList);
00853
00854 for (hi = headerInitIterator(h);
00855 headerNextIterator(hi, &tag, &type, (void *) &p, &c);
00856 p = headerFreeData(p, type))
00857 {
00858
00859 headerRemoveEntry(hdr->h, tag);
00860 headerAddEntry(hdr->h, tag, type, p, c);
00861 }
00862
00863 headerFreeIterator(hi);
00864 h = headerFree(h);
00865
00866 Py_BEGIN_ALLOW_THREADS
00867 h = headerRead(fd, HEADER_MAGIC_YES);
00868 Py_END_ALLOW_THREADS
00869 }
00870
00871 return 0;
00872 }
00873
00874 PyObject * rpmMergeHeadersFromFD(PyObject * self, PyObject * args)
00875 {
00876 FD_t fd;
00877 int fileno;
00878 PyObject * list;
00879 int rc;
00880 int matchTag;
00881
00882 if (!PyArg_ParseTuple(args, "Oii", &list, &fileno, &matchTag))
00883 return NULL;
00884
00885 if (!PyList_Check(list)) {
00886 PyErr_SetString(PyExc_TypeError, "first parameter must be a list");
00887 return NULL;
00888 }
00889
00890 fd = fdDup(fileno);
00891
00892 rc = rpmMergeHeaders (list, fd, matchTag);
00893 Fclose(fd);
00894
00895 if (rc) {
00896 return NULL;
00897 }
00898
00899 Py_INCREF(Py_None);
00900 return Py_None;
00901 }
00902
00905 PyObject * versionCompare (PyObject * self, PyObject * args)
00906 {
00907 hdrObject * h1, * h2;
00908
00909 if (!PyArg_ParseTuple(args, "O!O!", &hdr_Type, &h1, &hdr_Type, &h2))
00910 return NULL;
00911
00912 return Py_BuildValue("i", hdr_compare(h1, h2));
00913 }
00914
00917 PyObject * labelCompare (PyObject * self, PyObject * args)
00918 {
00919 char *v1, *r1, *e1, *v2, *r2, *e2;
00920 int rc;
00921
00922 if (!PyArg_ParseTuple(args, "(zzz)(zzz)",
00923 &e1, &v1, &r1,
00924 &e2, &v2, &r2)) return NULL;
00925
00926 if (e1 && !e2)
00927 return Py_BuildValue("i", 1);
00928 else if (!e1 && e2)
00929 return Py_BuildValue("i", -1);
00930 else if (e1 && e2) {
00931 int ep1, ep2;
00932 ep1 = atoi (e1);
00933 ep2 = atoi (e2);
00934 if (ep1 < ep2)
00935 return Py_BuildValue("i", -1);
00936 else if (ep1 > ep2)
00937 return Py_BuildValue("i", 1);
00938 }
00939
00940 rc = rpmvercmp(v1, v2);
00941 if (rc)
00942 return Py_BuildValue("i", rc);
00943
00944 return Py_BuildValue("i", rpmvercmp(r1, r2));
00945 }
00946