rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

header-py.c
Go to the documentation of this file.
1
5 #include "system.h"
6
7 #include "rpmio_internal.h"
8 #include <rpmcb.h>
9
10 #include "legacy.h"
11 #define _RPMTAG_INTERNAL
12 #include "header_internal.h" /* XXX HEADERFLAG_ALLOCATED */
13 #include "rpmtypes.h"
14 #define _RPMEVR_INTERNAL
15 #include "rpmevr.h"
16 #include "pkgio.h" /* XXX rpmpkgRead */
17
18 #include "rpmts.h" /* XXX rpmtsCreate/rpmtsFree */
19
20 #include "rpmcli.h"
21
22 #include "header-py.h"
23 #include "rpmds-py.h"
24 #include "rpmfi-py.h"
25
26 #include "debug.h"
27
138 struct hdrObject_s {
139 PyObject_HEAD
140 Header h;
141 } ;
142
145 /*@unused@*/ static inline Header headerAllocated(Header h)
146 /*@modifies h @*/
147 {
148 h->flags |= HEADERFLAG_ALLOCATED;
149 return 0;
150 }
151
156
159 static PyObject * hdrKeyList(hdrObject * s)
160 /*@*/
161 {
162 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
163 PyObject * list, *o;
164 HeaderIterator hi;
165
166 list = PyList_New(0);
167
168 for (hi = headerInit(s->h);
169 headerNext(hi, he, 0);
170 he->p.ptr = _free(he->p.ptr))
171 {
172 if (he->tag == HEADER_I18NTABLE) continue;
173 switch (he->t) {
174 case RPM_I18NSTRING_TYPE:
175 break;
176 case RPM_BIN_TYPE:
177 case RPM_UINT64_TYPE:
178 case RPM_UINT32_TYPE:
179 case RPM_UINT16_TYPE:
180 case RPM_UINT8_TYPE:
181 case RPM_STRING_ARRAY_TYPE:
182 case RPM_STRING_TYPE:
183 PyList_Append(list, o=PyInt_FromLong(he->tag));
184 Py_DECREF(o);
185 break;
186 }
187 }
188 hi = headerFini(hi);
189
190 return list;
191 }
192
195 static PyObject * hdrUnload(hdrObject * s, PyObject * args, PyObject *keywords)
196 /*@*/
197 {
198 char * buf;
199 PyObject * rc;
200 int legacy = 0;
201 int nb;
202 Header h;
203 static char *kwlist[] = { "legacyHeader", NULL};
204
205 if (!PyArg_ParseTupleAndKeywords(args, keywords, "|i", kwlist, &legacy))
206 return NULL;
207
208 h = headerLink(s->h);
209 /* XXX this legacy switch is a hack, needs to be removed. */
210 if (legacy) {
211 h = headerCopy(s->h); /* XXX strip region tags, etc */
212 (void)headerFree(s->h);
213 s->h = NULL;
214 }
215 { size_t len;
216 buf = headerUnload(h, &len);
217 nb = len;
218 nb -= 8; /* XXX HEADER_MAGIC_NO */
219 }
220 (void)headerFree(h);
221 h = NULL;
222
223 if (buf == NULL || nb == 0) {
224 PyErr_SetString(pyrpmError, "can't unload bad header\n");
225 return NULL;
226 }
227
228 rc = PyString_FromStringAndSize(buf, nb);
229 buf = _free(buf);
230
231 return rc;
232 }
233
236 static PyObject * hdrGetOrigin(hdrObject * s)
237 /*@*/
238 {
239 const char * origin = NULL;
240 if (s->h != NULL)
241
242 origin = headerGetOrigin(s->h);
243 if (origin != NULL)
244 return Py_BuildValue("s", origin);
245 Py_INCREF(Py_None);
246 return Py_None;
247 }
248
251 static PyObject * hdrSetOrigin(hdrObject * s, PyObject * args, PyObject * kwds)
252 /*@*/
253 {
254 char * kwlist[] = {"origin", NULL};
255 const char * origin = NULL;
256
257 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:SetOrigin", kwlist, &origin))
258 return NULL;
259
260 if (s->h != NULL && origin != NULL)
261 headerSetOrigin(s->h, origin);
262
263 Py_INCREF(Py_None);
264 return Py_None;
265 }
266
269 static PyObject * hdrSprintf(hdrObject * s, PyObject * args, PyObject * kwds)
270 /*@*/
271 {
272 char * fmt;
273 char * r;
274 errmsg_t err;
275 PyObject * result;
276 char * kwlist[] = {"format", NULL};
277
278 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &fmt))
279 return NULL;
280
281 r = headerSprintf(s->h, fmt, NULL, rpmHeaderFormats, &err);
282 if (!r) {
283 PyErr_SetString(pyrpmError, err);
284 return NULL;
285 }
286
287 result = Py_BuildValue("s", r);
288 r = _free(r);
289
290 return result;
291 }
292
297 /*@unchecked@*/ /*@observer@*/
298 static struct PyMethodDef hdr_methods[] = {
299 {"keys", (PyCFunction) hdrKeyList, METH_NOARGS,
300 NULL },
301 {"unload", (PyCFunction) hdrUnload, METH_VARARGS|METH_KEYWORDS,
302 NULL },
303 {"getorigin", (PyCFunction) hdrGetOrigin, METH_NOARGS,
304 NULL },
305 {"setorigin", (PyCFunction) hdrSetOrigin, METH_NOARGS,
306 NULL },
307 {"sprintf", (PyCFunction) hdrSprintf, METH_VARARGS|METH_KEYWORDS,
308 NULL },
309
310 {"dsOfHeader", (PyCFunction)hdr_dsOfHeader, METH_NOARGS,
311 NULL},
312 {"dsFromHeader", (PyCFunction)hdr_dsFromHeader, METH_VARARGS|METH_KEYWORDS,
313 NULL},
314 {"fiFromHeader", (PyCFunction)hdr_fiFromHeader, METH_VARARGS|METH_KEYWORDS,
315 NULL},
316
317 {NULL, NULL} /* sentinel */
318 };
319
322 static int hdr_compare(hdrObject * a, hdrObject * b)
323 /*@*/
324 {
325 return rpmVersionCompare(a->h, b->h);
326 }
327
328 static long hdr_hash(PyObject * h)
329 {
330 return (long) h;
331 }
332
335 static void hdr_dealloc(hdrObject * s)
336 /*@*/
337 {
338 if (s->h) headerFree(s->h);
339 s->h = NULL;
340 PyObject_Del(s);
341 }
342
345 rpmTag tagNumFromPyObject (PyObject *item)
346 {
347 char * str;
348
349 if (PyInt_Check(item)) {
350 return (rpmTag) PyInt_AsLong(item);
351 } else if (PyString_Check(item) || PyUnicode_Check(item)) {
352 str = PyString_AsString(item);
353 return tagValue(str);
354 }
355 return (rpmTag)0xffffffff;
356 }
357
360 static PyObject * hdr_subscript(hdrObject * s, PyObject * item)
361 /*@*/
362 {
363 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
364 rpmTag tag = (rpmTag)0xffffffff;
365 uint32_t i;
366 PyObject * o, * metao;
367 int forceArray = 0;
368 const struct headerSprintfExtension_s * ext = NULL;
369 int xx;
370
371 if (PyCObject_Check (item))
372 ext = PyCObject_AsVoidPtr(item);
373 else
374 tag = tagNumFromPyObject (item);
375
376 if (tag == (rpmTag)0xffffffff && (PyString_Check(item) || PyUnicode_Check(item))) {
377 const struct headerSprintfExtension_s * extensions = rpmHeaderFormats;
378 char * str;
379 /* if we still don't have the tag, go looking for the header
380 extensions */
381 str = PyString_AsString(item);
382 while (extensions->name) {
383 if (extensions->type == HEADER_EXT_TAG
384 && !xstrcasecmp(extensions->name + 7, str)) {
385 ext = extensions;
386 }
387 extensions++;
388 if (extensions->type == HEADER_EXT_MORE)
389 extensions = *extensions->u.more;
390 }
391 }
392
393 /* Retrieve data from extension or header. */
394 if (ext) {
395 ext->u.tagFunction(s->h, he);
396 } else {
397 if (tag == (rpmTag)0xffffffff) {
398 PyErr_SetString(PyExc_KeyError, "unknown header tag");
399 return NULL;
400 }
401
402 he->tag = tag;
403 xx = headerGet(s->h, he, 0);
404 if (!xx) {
405 he->p.ptr = _free(he->p.ptr);
406 switch (tag) {
407 case RPMTAG_EPOCH:
408 case RPMTAG_NAME:
409 case RPMTAG_VERSION:
410 case RPMTAG_RELEASE:
411 case RPMTAG_DISTEPOCH:
412 case RPMTAG_ARCH:
413 case RPMTAG_OS:
414 Py_INCREF(Py_None);
415 return Py_None;
416 break;
417 default:
418 return PyList_New(0);
419 break;
420 }
421 }
422 }
423
424 switch (tag) {
425 case RPMTAG_FILEPATHS:
426 case RPMTAG_ORIGPATHS:
427 case RPMTAG_OLDFILENAMES:
428 case RPMTAG_FILESIZES:
429 case RPMTAG_FILESTATES:
430 case RPMTAG_FILEMODES:
431 case RPMTAG_FILEUIDS:
432 case RPMTAG_FILEGIDS:
433 case RPMTAG_FILERDEVS:
434 case RPMTAG_FILEMTIMES:
435 case RPMTAG_FILEMD5S:
436 case RPMTAG_FILELINKTOS:
437 case RPMTAG_FILEFLAGS:
438 case RPMTAG_ROOT:
439 case RPMTAG_FILEUSERNAME:
440 case RPMTAG_FILEGROUPNAME:
441 case RPMTAG_REQUIRENAME:
442 case RPMTAG_REQUIREFLAGS:
443 case RPMTAG_REQUIREVERSION:
444 case RPMTAG_PROVIDENAME:
445 case RPMTAG_PROVIDEFLAGS:
446 case RPMTAG_PROVIDEVERSION:
447 case RPMTAG_OBSOLETENAME:
448 case RPMTAG_OBSOLETEFLAGS:
449 case RPMTAG_OBSOLETEVERSION:
450 case RPMTAG_CONFLICTNAME:
451 case RPMTAG_CONFLICTFLAGS:
452 case RPMTAG_CONFLICTVERSION:
453 case RPMTAG_CHANGELOGTIME:
454 case RPMTAG_FILEVERIFYFLAGS:
455 forceArray = 1;
456 break;
457 default:
458 break;
459 }
460
461 switch (he->t) {
462 case RPM_BIN_TYPE:
463 o = PyString_FromStringAndSize(he->p.str, he->c);
464 break;
465
466 case RPM_UINT8_TYPE:
467 if (he->c != 1 || forceArray) {
468 metao = PyList_New(0);
469 for (i = 0; i < he->c; i++) {
470 o = PyInt_FromLong(he->p.ui8p[i]);
471 PyList_Append(metao, o);
472 Py_DECREF(o);
473 }
474 o = metao;
475 } else {
476 o = PyInt_FromLong(he->p.ui8p[0]);
477 }
478 break;
479
480 case RPM_UINT16_TYPE:
481 if (he->c != 1 || forceArray) {
482 metao = PyList_New(0);
483 for (i = 0; i < he->c; i++) {
484 o = PyInt_FromLong(he->p.ui16p[i]);
485 PyList_Append(metao, o);
486 Py_DECREF(o);
487 }
488 o = metao;
489 } else {
490 o = PyInt_FromLong(he->p.ui16p[0]);
491 }
492 break;
493
494 case RPM_UINT32_TYPE:
495 if (he->c != 1 || forceArray) {
496 metao = PyList_New(0);
497 for (i = 0; i < he->c; i++) {
498 o = PyInt_FromLong(he->p.ui32p[i]);
499 PyList_Append(metao, o);
500 Py_DECREF(o);
501 }
502 o = metao;
503 } else {
504 o = PyInt_FromLong(he->p.ui32p[0]);
505 }
506 break;
507
508 case RPM_UINT64_TYPE:
509 if (he->c != 1 || forceArray) {
510 metao = PyList_New(0);
511 for (i = 0; i < he->c; i++) {
512 o = PyInt_FromLong(he->p.ui64p[i]);
513 PyList_Append(metao, o);
514 Py_DECREF(o);
515 }
516 o = metao;
517 } else {
518 o = PyInt_FromLong(he->p.ui64p[0]);
519 }
520 break;
521
522 case RPM_STRING_ARRAY_TYPE:
523 metao = PyList_New(0);
524 for (i = 0; i < he->c; i++) {
525 o = PyString_FromString(he->p.argv[i]);
526 PyList_Append(metao, o);
527 Py_DECREF(o);
528 }
529 o = metao;
530 break;
531
532 case RPM_STRING_TYPE:
533 if (he->p.str != NULL)
534 o = PyString_FromString(he->p.str);
535 else
536 o = PyString_FromString("");
537 break;
538
539 default:
540 PyErr_SetString(PyExc_TypeError, "unsupported type in header");
541 return NULL;
542 }
543 if (he->freeData)
544 he->p.ptr = _free(he->p.ptr);
545
546 return o;
547 }
548
551 /*@unchecked@*/ /*@observer@*/
552 static PyMappingMethods hdr_as_mapping = {
553 (lenfunc) 0, /* mp_length */
554 (binaryfunc) hdr_subscript, /* mp_subscript */
555 (objobjargproc) 0, /* mp_ass_subscript */
556 };
557
558 static PyObject * hdr_getattro(hdrObject * o, PyObject * n)
559 /*@*/
560 {
561 PyObject * res;
562 res = PyObject_GenericGetAttr((PyObject *)o, n);
563 if (res == NULL)
564 res = hdr_subscript(o, n);
565 return res;
566 }
567
568 static int hdr_setattro(hdrObject * o, PyObject * n, PyObject * v)
569 /*@*/
570 {
571 return PyObject_GenericSetAttr((PyObject *)o, n, v);
572 }
573
576 static char hdr_doc[] =
577 "";
578
581 /*@unchecked@*/ /*@observer@*/
582 PyTypeObject hdr_Type = {
583 PyObject_HEAD_INIT(&PyType_Type)
584 0, /* ob_size */
585 "rpm.hdr", /* tp_name */
586 sizeof(hdrObject), /* tp_size */
587 0, /* tp_itemsize */
588 (destructor) hdr_dealloc, /* tp_dealloc */
589 0, /* tp_print */
590 (getattrfunc) 0, /* tp_getattr */
591 0, /* tp_setattr */
592 (cmpfunc) hdr_compare, /* tp_compare */
593 0, /* tp_repr */
594 0, /* tp_as_number */
595 0, /* tp_as_sequence */
596 &hdr_as_mapping, /* tp_as_mapping */
597 hdr_hash, /* tp_hash */
598 0, /* tp_call */
599 0, /* tp_str */
600 (getattrofunc) hdr_getattro, /* tp_getattro */
601 (setattrofunc) hdr_setattro, /* tp_setattro */
602 0, /* tp_as_buffer */
603 Py_TPFLAGS_DEFAULT, /* tp_flags */
604 hdr_doc, /* tp_doc */
605 #if Py_TPFLAGS_HAVE_ITER
606 0, /* tp_traverse */
607 0, /* tp_clear */
608 0, /* tp_richcompare */
609 0, /* tp_weaklistoffset */
610 0, /* tp_iter */
611 0, /* tp_iternext */
612 hdr_methods, /* tp_methods */
613 0, /* tp_members */
614 0, /* tp_getset */
615 0, /* tp_base */
616 0, /* tp_dict */
617 0, /* tp_descr_get */
618 0, /* tp_descr_set */
619 0, /* tp_dictoffset */
620 0, /* tp_init */
621 0, /* tp_alloc */
622 0, /* tp_new */
623 0, /* tp_free */
624 0, /* tp_is_gc */
625 #endif
626 };
627
628 hdrObject * hdr_Wrap(Header h)
629 {
630 hdrObject * hdr = PyObject_New(hdrObject, &hdr_Type);
631 hdr->h = headerLink(h);
632 return hdr;
633 }
634
635 Header hdrGetHeader(hdrObject * s)
636 {
637 return s->h;
638 }
639
642 PyObject * hdrLoad(PyObject * self, PyObject * args, PyObject * kwds)
643 {
644 hdrObject * hdr;
645 char * copy = NULL;
646 char * obj;
647 Header h;
648 int len;
649 char * kwlist[] = {"headers", NULL};
650
651 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwlist, &obj, &len))
652 return NULL;
653
654 /* malloc is needed to avoid surprises from data swab in headerLoad(). */
655 copy = malloc(len);
656 if (copy == NULL) {
657 PyErr_SetString(pyrpmError, "out of memory");
658 return NULL;
659 }
660 memcpy (copy, obj, len);
661
662 h = headerLoad(copy);
663 if (!h) {
664 PyErr_SetString(pyrpmError, "bad header");
665 return NULL;
666 }
667 headerAllocated(h);
668
669 hdr = hdr_Wrap(h);
670 (void)headerFree(h); /* XXX ref held by hdr */
671 h = NULL;
672
673 return (PyObject *) hdr;
674 }
675
678 PyObject * rpmReadHeaders (FD_t fd)
679 {
680 PyObject * list;
681 Header h;
682 hdrObject * hdr;
683
684 if (!fd) {
685 PyErr_SetFromErrno(pyrpmError);
686 return NULL;
687 }
688
689 list = PyList_New(0);
690 Py_BEGIN_ALLOW_THREADS
691 { const char item[] = "Header";
692 const char * msg = NULL;
693 rpmRC rc = rpmpkgRead(item, fd, &h, &msg);
694 if(rc == RPMRC_NOTFOUND) {
695 Py_INCREF(Py_None);
696 list = Py_None;
697 }
698 else if (rc != RPMRC_OK)
699 rpmlog(RPMLOG_ERR, "%s: %s: %s : error code: %d\n", "rpmpkgRead", item, msg, rc);
700 msg = _free(msg);
701 }
702 Py_END_ALLOW_THREADS
703
704 while (h) {
705 hdr = hdr_Wrap(h);
706 if (PyList_Append(list, (PyObject *) hdr)) {
707 Py_DECREF(list);
708 Py_DECREF(hdr);
709 return NULL;
710 }
711 Py_DECREF(hdr);
712
713 (void)headerFree(h); /* XXX ref held by hdr */
714 h = NULL;
715
716 Py_BEGIN_ALLOW_THREADS
717 { const char item[] = "Header";
718 const char * msg = NULL;
719 rpmRC rc = rpmpkgRead(item, fd, &h, &msg);
720 if(rc == RPMRC_NOTFOUND) {
721 Py_INCREF(Py_None);
722 list = Py_None;
723 }
724 else if (rc != RPMRC_OK)
725 rpmlog(RPMLOG_ERR, "%s: %s: %s : error code: %d\n", "rpmpkgRead", item, msg, rc);
726 msg = _free(msg);
727 }
728 Py_END_ALLOW_THREADS
729 }
730
731 return list;
732 }
733
736 PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args,
737 PyObject * kwds)
738 {
739 FD_t fd;
740 int fileno;
741 PyObject * list;
742 char * kwlist[] = {"fd", NULL};
743
744 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
745 return NULL;
746
747 fd = fdDup(fileno);
748
749 list = rpmReadHeaders (fd);
750 Fclose(fd);
751
752 return list;
753 }
754
757 PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args,
758 PyObject *kwds)
759 {
760 char * filespec;
761 FD_t fd;
762 PyObject * list;
763 char * kwlist[] = {"file", NULL};
764
765 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &filespec))
766 return NULL;
767
768 fd = Fopen(filespec, "r.fdio");
769
770 if (!fd) {
771 PyErr_SetFromErrno(pyrpmError);
772 return NULL;
773 }
774
775 list = rpmReadHeaders (fd);
776 Fclose(fd);
777
778 return list;
779 }
780
783 PyObject *
784 rpmSingleHeaderFromFD(PyObject * self, PyObject * args,
785 PyObject * kwds)
786 {
787 FD_t fd;
788 int fileno;
789 off_t offset;
790 PyObject * tuple;
791 Header h;
792 char * kwlist[] = {"fd", NULL};
793
794 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
795 return NULL;
796
797 offset = lseek(fileno, 0, SEEK_CUR);
798
799 fd = fdDup(fileno);
800
801 if (!fd) {
802 PyErr_SetFromErrno(pyrpmError);
803 return NULL;
804 }
805
806 Py_BEGIN_ALLOW_THREADS
807 { const char item[] = "Header";
808 const char * msg = NULL;
809 rpmRC rc = rpmpkgRead(item, fd, &h, &msg);
810 if(rc == RPMRC_NOTFOUND) {
811 Py_INCREF(Py_None);
812 tuple = Py_None;
813 }
814 else if (rc != RPMRC_OK)
815 rpmlog(RPMLOG_ERR, "%s: %s: %s : error code: %d\n", "rpmpkgRead", item, msg, rc);
816 msg = _free(msg);
817 }
818 Py_END_ALLOW_THREADS
819
820 Fclose(fd);
821
822 tuple = PyTuple_New(2);
823
824 if (h && tuple) {
825 PyTuple_SET_ITEM(tuple, 0, (PyObject *) hdr_Wrap(h));
826 PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(offset));
827 (void)headerFree(h);
828 h = NULL;
829 } else {
830 Py_INCREF(Py_None);
831 Py_INCREF(Py_None);
832 PyTuple_SET_ITEM(tuple, 0, Py_None);
833 PyTuple_SET_ITEM(tuple, 1, Py_None);
834 }
835
836 return tuple;
837 }
838
841 PyObject * rpmWriteHeaders (PyObject * list, FD_t fd)
842 {
843 int count;
844
845 if (!fd) {
846 PyErr_SetFromErrno(pyrpmError);
847 return NULL;
848 }
849
850 for(count = 0; count < PyList_Size(list); count++){
851 Py_BEGIN_ALLOW_THREADS
852 const char item[] = "Header";
853 const char * msg = NULL;
854 hdrObject * hdr = (hdrObject *)PyList_GetItem(list, count);
855 rpmRC rc = rpmpkgWrite(item, fd, hdr->h, &msg);
856 if (rc != RPMRC_OK)
857 rpmlog(RPMLOG_ERR, "%s: %s: %s : error code: %d\n", "rpmpkgWrite", item, msg, rc);
858 msg = _free(msg);
859 Py_END_ALLOW_THREADS
860 }
861
862 Py_RETURN_TRUE;
863 }
864
867 PyObject * rpmHeaderToFD(PyObject * self, PyObject * args,
868 PyObject * kwds)
869 {
870 FD_t fd;
871 int fileno;
872 PyObject * list;
873 PyObject * ret;
874 char * kwlist[] = {"headers", "fd", NULL};
875
876 if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi", kwlist, &list, &fileno))
877 return NULL;
878
879 fd = fdDup(fileno);
880
881 ret = rpmWriteHeaders (list, fd);
882 Fclose(fd);
883
884 return list;
885 }
886
889 PyObject * rpmHeaderToFile(PyObject * self, PyObject * args,
890 PyObject *kwds)
891 {
892 char * filespec;
893 FD_t fd;
894 PyObject * list;
895 PyObject * ret;
896 char * kwlist[] = {"headers", "file", NULL};
897
898 if (!PyArg_ParseTupleAndKeywords(args, kwds, "Os", kwlist, &list, &filespec))
899 return NULL;
900
901 fd = Fopen(filespec, "w.fdio");
902 if (!fd) {
903 PyErr_SetFromErrno(pyrpmError);
904 return NULL;
905 }
906
907 ret = rpmWriteHeaders (list, fd);
908 Fclose(fd);
909
910 return ret;
911 }
912
915 PyObject * versionCompare (PyObject * self, PyObject * args,
916 PyObject * kwds)
917 {
918 hdrObject * h1, * h2;
919 char * kwlist[] = {"version0", "version1", NULL};
920
921 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!", kwlist, &hdr_Type,
922 &h1, &hdr_Type, &h2))
923 return NULL;
924
925 return Py_BuildValue("i", hdr_compare(h1, h2));
926 }
927
928 PyObject * labelCompare (PyObject * self, PyObject * args)
929 {
930 EVR_t a = rpmEVRnew(RPMSENSE_EQUAL, 1);
931 EVR_t b = rpmEVRnew(RPMSENSE_EQUAL, 1);
932 int rc;
933 PyObject *aTuple, *bTuple;
934
935 if (!PyArg_ParseTuple(args, "OO", &aTuple, &bTuple) ||
936 !PyArg_ParseTuple(aTuple, "zzz|z",
937 &a->F[RPMEVR_E], &a->F[RPMEVR_V], &a->F[RPMEVR_R], &a->F[RPMEVR_D]) ||
938 !PyArg_ParseTuple(bTuple, "zzz|z",
939 &b->F[RPMEVR_E], &b->F[RPMEVR_V], &b->F[RPMEVR_R], &b->F[RPMEVR_D]))
940 {
941 a = rpmEVRfree(a);
942 b = rpmEVRfree(b);
943 return NULL;
944 }
945
946 /* XXX HACK: postpone committing to single "missing" value for now. */
947 if (a->F[RPMEVR_E] == NULL) a->F[RPMEVR_E] = "0";
948 if (b->F[RPMEVR_E] == NULL) b->F[RPMEVR_E] = "0";
949 if (a->F[RPMEVR_V] == NULL) a->F[RPMEVR_V] = "";
950 if (b->F[RPMEVR_V] == NULL) b->F[RPMEVR_V] = "";
951 if (a->F[RPMEVR_R] == NULL) a->F[RPMEVR_R] = "";
952 if (b->F[RPMEVR_R] == NULL) b->F[RPMEVR_R] = "";
953 if (a->F[RPMEVR_D] == NULL) a->F[RPMEVR_D] = "";
954 if (b->F[RPMEVR_D] == NULL) b->F[RPMEVR_D] = "";
955
956 rc = rpmEVRcompare(a, b);
957
958 a = rpmEVRfree(a);
959 b = rpmEVRfree(b);
960
961 return Py_BuildValue("i", rc);
962 }