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 rpmBuildFileList(h, &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
00341
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}
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
00427
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
00568 static PyMappingMethods hdr_as_mapping = {
00569 (inquiry) 0,
00570 (binaryfunc) hdr_subscript,
00571 (objobjargproc)0,
00572 };
00573
00576 static char hdr_doc[] =
00577 "";
00578
00581
00582 PyTypeObject hdr_Type = {
00583 PyObject_HEAD_INIT(NULL)
00584 0,
00585 "rpm.hdr",
00586 sizeof(hdrObject),
00587 0,
00588 (destructor) hdr_dealloc,
00589 0,
00590 (getattrfunc) hdr_getattr,
00591 0,
00592 (cmpfunc) hdr_compare,
00593 0,
00594 0,
00595 0,
00596 &hdr_as_mapping,
00597 0,
00598 0,
00599 0,
00600 0,
00601 0,
00602 0,
00603 Py_TPFLAGS_DEFAULT,
00604 hdr_doc,
00605 #if Py_TPFLAGS_HAVE_ITER
00606 0,
00607 0,
00608 0,
00609 0,
00610 0,
00611 0,
00612 hdr_methods,
00613 0,
00614 0,
00615 0,
00616 0,
00617 0,
00618 0,
00619 0,
00620 0,
00621 0,
00622 0,
00623 0,
00624 0,
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
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);
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
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
00704 if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
00705 PyErr_SetString(pyrpmError, "bad header, not immutable");
00706 headerFree(h);
00707 return NULL;
00708 }
00709
00710
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
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);
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
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