00001
00005 #include "system.h"
00006
00007 #include "rpmio_internal.h"
00008
00009 #include "legacy.h"
00010 #define _RPMTAG_INTERNAL
00011 #include "header_internal.h"
00012 #include "rpmcli.h"
00013 #include "pkgio.h"
00014
00015 #include "rpmts.h"
00016 #define _RPMEVR_INTERNAL
00017 #include "rpmevr.h"
00018
00019 #include "header-py.h"
00020 #include "rpmds-py.h"
00021 #include "rpmfi-py.h"
00022
00023 #include "debug.h"
00024
00135 struct hdrObject_s {
00136 PyObject_HEAD
00137 Header h;
00138 } ;
00139
00142 static inline Header headerAllocated(Header h)
00143
00144 {
00145 h->flags |= HEADERFLAG_ALLOCATED;
00146 return 0;
00147 }
00148
00153
00156 static PyObject * hdrKeyList(hdrObject * s)
00157
00158 {
00159 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00160 PyObject * list, *o;
00161 HeaderIterator hi;
00162
00163 list = PyList_New(0);
00164
00165 for (hi = headerInit(s->h);
00166 headerNext(hi, he, 0);
00167 he->p.ptr = _free(he->p.ptr))
00168 {
00169 if (he->tag == HEADER_I18NTABLE) continue;
00170 switch (he->t) {
00171 case RPM_I18NSTRING_TYPE:
00172 break;
00173 case RPM_BIN_TYPE:
00174 case RPM_UINT64_TYPE:
00175 case RPM_UINT32_TYPE:
00176 case RPM_UINT16_TYPE:
00177 case RPM_UINT8_TYPE:
00178 case RPM_STRING_ARRAY_TYPE:
00179 case RPM_STRING_TYPE:
00180 PyList_Append(list, o=PyInt_FromLong(he->tag));
00181 Py_DECREF(o);
00182 break;
00183 }
00184 }
00185 hi = headerFini(hi);
00186
00187 return list;
00188 }
00189
00192 static PyObject * hdrUnload(hdrObject * s, PyObject * args, PyObject *keywords)
00193
00194 {
00195 char * buf;
00196 PyObject * rc;
00197 int legacy = 0;
00198 int nb;
00199 Header h;
00200 static char *kwlist[] = { "legacyHeader", NULL};
00201
00202 if (!PyArg_ParseTupleAndKeywords(args, keywords, "|i", kwlist, &legacy))
00203 return NULL;
00204
00205 h = headerLink(s->h);
00206
00207 if (legacy) {
00208 h = headerCopy(s->h);
00209 headerFree(s->h);
00210 }
00211 { size_t len;
00212 buf = headerUnload(h, &len);
00213 nb = len;
00214 nb -= 8;
00215 }
00216 h = headerFree(h);
00217
00218 if (buf == NULL || nb == 0) {
00219 PyErr_SetString(pyrpmError, "can't unload bad header\n");
00220 return NULL;
00221 }
00222
00223 rc = PyString_FromStringAndSize(buf, nb);
00224 buf = _free(buf);
00225
00226 return rc;
00227 }
00228
00231 static PyObject * hdrGetOrigin(hdrObject * s)
00232
00233 {
00234 const char * origin = NULL;
00235 if (s->h != NULL)
00236
00237 origin = headerGetOrigin(s->h);
00238 if (origin != NULL)
00239 return Py_BuildValue("s", origin);
00240 Py_INCREF(Py_None);
00241 return Py_None;
00242 }
00243
00246 static PyObject * hdrSetOrigin(hdrObject * s, PyObject * args, PyObject * kwds)
00247
00248 {
00249 char * kwlist[] = {"origin", NULL};
00250 const char * origin = NULL;
00251
00252 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:SetOrigin", kwlist, &origin))
00253 return NULL;
00254
00255 if (s->h != NULL && origin != NULL)
00256 headerSetOrigin(s->h, origin);
00257
00258 Py_INCREF(Py_None);
00259 return Py_None;
00260 }
00261
00264 static PyObject * hdrSprintf(hdrObject * s, PyObject * args, PyObject * kwds)
00265
00266 {
00267 char * fmt;
00268 char * r;
00269 errmsg_t err;
00270 PyObject * result;
00271 char * kwlist[] = {"format", NULL};
00272
00273 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &fmt))
00274 return NULL;
00275
00276 r = headerSprintf(s->h, fmt, NULL, rpmHeaderFormats, &err);
00277 if (!r) {
00278 PyErr_SetString(pyrpmError, err);
00279 return NULL;
00280 }
00281
00282 result = Py_BuildValue("s", r);
00283 r = _free(r);
00284
00285 return result;
00286 }
00287
00292
00293 static struct PyMethodDef hdr_methods[] = {
00294 {"keys", (PyCFunction) hdrKeyList, METH_NOARGS,
00295 NULL },
00296 {"unload", (PyCFunction) hdrUnload, METH_VARARGS|METH_KEYWORDS,
00297 NULL },
00298 {"getorigin", (PyCFunction) hdrGetOrigin, METH_NOARGS,
00299 NULL },
00300 {"setorigin", (PyCFunction) hdrSetOrigin, METH_NOARGS,
00301 NULL },
00302 {"sprintf", (PyCFunction) hdrSprintf, METH_VARARGS|METH_KEYWORDS,
00303 NULL },
00304
00305 {"dsOfHeader", (PyCFunction)hdr_dsOfHeader, METH_NOARGS,
00306 NULL},
00307 {"dsFromHeader", (PyCFunction)hdr_dsFromHeader, METH_VARARGS|METH_KEYWORDS,
00308 NULL},
00309 {"fiFromHeader", (PyCFunction)hdr_fiFromHeader, METH_VARARGS|METH_KEYWORDS,
00310 NULL},
00311
00312 {NULL, NULL}
00313 };
00314
00317 static int hdr_compare(hdrObject * a, hdrObject * b)
00318
00319 {
00320 return rpmVersionCompare(a->h, b->h);
00321 }
00322
00323 static long hdr_hash(PyObject * h)
00324 {
00325 return (long) h;
00326 }
00327
00330 static void hdr_dealloc(hdrObject * s)
00331
00332 {
00333 if (s->h) headerFree(s->h);
00334 PyObject_Del(s);
00335 }
00336
00339 long tagNumFromPyObject (PyObject *item)
00340 {
00341 char * str;
00342
00343 if (PyInt_Check(item)) {
00344 return PyInt_AsLong(item);
00345 } else if (PyString_Check(item) || PyUnicode_Check(item)) {
00346 str = PyString_AsString(item);
00347 return tagValue(str);
00348 }
00349 return -1;
00350 }
00351
00354 static PyObject * hdr_subscript(hdrObject * s, PyObject * item)
00355
00356 {
00357 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00358 uint32_t tag = 0xffffffff;
00359 int i;
00360 PyObject * o, * metao;
00361 int forceArray = 0;
00362 const struct headerSprintfExtension_s * ext = NULL;
00363 int xx;
00364
00365 if (PyCObject_Check (item))
00366 ext = PyCObject_AsVoidPtr(item);
00367 else
00368 tag = tagNumFromPyObject (item);
00369
00370 if (tag == 0xffffffff && (PyString_Check(item) || PyUnicode_Check(item))) {
00371 const struct headerSprintfExtension_s * extensions = rpmHeaderFormats;
00372 char * str;
00373
00374
00375 str = PyString_AsString(item);
00376 while (extensions->name) {
00377 if (extensions->type == HEADER_EXT_TAG
00378 && !xstrcasecmp(extensions->name + 7, str)) {
00379 ext = extensions;
00380 }
00381 extensions++;
00382 if (extensions->type == HEADER_EXT_MORE)
00383 extensions = *extensions->u.more;
00384 }
00385 }
00386
00387
00388 if (ext) {
00389 ext->u.tagFunction(s->h, he);
00390 } else {
00391 if (tag == 0xffffffff) {
00392 PyErr_SetString(PyExc_KeyError, "unknown header tag");
00393 return NULL;
00394 }
00395
00396 he->tag = tag;
00397 xx = headerGet(s->h, he, 0);
00398 if (!xx) {
00399 he->p.ptr = _free(he->p.ptr);
00400 switch (tag) {
00401 case RPMTAG_EPOCH:
00402 case RPMTAG_NAME:
00403 case RPMTAG_VERSION:
00404 case RPMTAG_RELEASE:
00405 case RPMTAG_ARCH:
00406 case RPMTAG_OS:
00407 Py_INCREF(Py_None);
00408 return Py_None;
00409 break;
00410 default:
00411 return PyList_New(0);
00412 break;
00413 }
00414 }
00415 }
00416
00417 switch (tag) {
00418 case RPMTAG_FILEPATHS:
00419 case RPMTAG_ORIGPATHS:
00420 case RPMTAG_OLDFILENAMES:
00421 case RPMTAG_FILESIZES:
00422 case RPMTAG_FILESTATES:
00423 case RPMTAG_FILEMODES:
00424 case RPMTAG_FILEUIDS:
00425 case RPMTAG_FILEGIDS:
00426 case RPMTAG_FILERDEVS:
00427 case RPMTAG_FILEMTIMES:
00428 case RPMTAG_FILEMD5S:
00429 case RPMTAG_FILELINKTOS:
00430 case RPMTAG_FILEFLAGS:
00431 case RPMTAG_ROOT:
00432 case RPMTAG_FILEUSERNAME:
00433 case RPMTAG_FILEGROUPNAME:
00434 case RPMTAG_REQUIRENAME:
00435 case RPMTAG_REQUIREFLAGS:
00436 case RPMTAG_REQUIREVERSION:
00437 case RPMTAG_PROVIDENAME:
00438 case RPMTAG_PROVIDEFLAGS:
00439 case RPMTAG_PROVIDEVERSION:
00440 case RPMTAG_OBSOLETENAME:
00441 case RPMTAG_OBSOLETEFLAGS:
00442 case RPMTAG_OBSOLETEVERSION:
00443 case RPMTAG_CONFLICTNAME:
00444 case RPMTAG_CONFLICTFLAGS:
00445 case RPMTAG_CONFLICTVERSION:
00446 case RPMTAG_CHANGELOGTIME:
00447 case RPMTAG_FILEVERIFYFLAGS:
00448 forceArray = 1;
00449 break;
00450 default:
00451 break;
00452 }
00453
00454 switch (he->t) {
00455 case RPM_BIN_TYPE:
00456 o = PyString_FromStringAndSize(he->p.str, he->c);
00457 break;
00458
00459 case RPM_UINT8_TYPE:
00460 if (he->c != 1 || forceArray) {
00461 metao = PyList_New(0);
00462 for (i = 0; i < he->c; i++) {
00463 o = PyInt_FromLong(he->p.ui8p[i]);
00464 PyList_Append(metao, o);
00465 Py_DECREF(o);
00466 }
00467 o = metao;
00468 } else {
00469 o = PyInt_FromLong(he->p.ui8p[0]);
00470 }
00471 break;
00472
00473 case RPM_UINT16_TYPE:
00474 if (he->c != 1 || forceArray) {
00475 metao = PyList_New(0);
00476 for (i = 0; i < he->c; i++) {
00477 o = PyInt_FromLong(he->p.ui16p[i]);
00478 PyList_Append(metao, o);
00479 Py_DECREF(o);
00480 }
00481 o = metao;
00482 } else {
00483 o = PyInt_FromLong(he->p.ui16p[0]);
00484 }
00485 break;
00486
00487 case RPM_UINT32_TYPE:
00488 if (he->c != 1 || forceArray) {
00489 metao = PyList_New(0);
00490 for (i = 0; i < he->c; i++) {
00491 o = PyInt_FromLong(he->p.ui32p[i]);
00492 PyList_Append(metao, o);
00493 Py_DECREF(o);
00494 }
00495 o = metao;
00496 } else {
00497 o = PyInt_FromLong(he->p.ui32p[0]);
00498 }
00499 break;
00500
00501 case RPM_UINT64_TYPE:
00502 if (he->c != 1 || forceArray) {
00503 metao = PyList_New(0);
00504 for (i = 0; i < he->c; i++) {
00505 o = PyInt_FromLong(he->p.ui64p[i]);
00506 PyList_Append(metao, o);
00507 Py_DECREF(o);
00508 }
00509 o = metao;
00510 } else {
00511 o = PyInt_FromLong(he->p.ui64p[0]);
00512 }
00513 break;
00514
00515 case RPM_STRING_ARRAY_TYPE:
00516 metao = PyList_New(0);
00517 for (i = 0; i < he->c; i++) {
00518 o = PyString_FromString(he->p.argv[i]);
00519 PyList_Append(metao, o);
00520 Py_DECREF(o);
00521 }
00522 o = metao;
00523 break;
00524
00525 case RPM_STRING_TYPE:
00526 o = PyString_FromString(he->p.str);
00527 break;
00528
00529 default:
00530 PyErr_SetString(PyExc_TypeError, "unsupported type in header");
00531 return NULL;
00532 }
00533 if (he->freeData)
00534 he->p.ptr = _free(he->p.ptr);
00535
00536 return o;
00537 }
00538
00541
00542 static PyMappingMethods hdr_as_mapping = {
00543 (inquiry) 0,
00544 (binaryfunc) hdr_subscript,
00545 (objobjargproc)0,
00546 };
00547
00548 static PyObject * hdr_getattro(hdrObject * o, PyObject * n)
00549
00550 {
00551 PyObject * res;
00552 res = PyObject_GenericGetAttr((PyObject *)o, n);
00553 if (res == NULL)
00554 res = hdr_subscript(o, n);
00555 return res;
00556 }
00557
00558 static int hdr_setattro(hdrObject * o, PyObject * n, PyObject * v)
00559
00560 {
00561 return PyObject_GenericSetAttr((PyObject *)o, n, v);
00562 }
00563
00566 static char hdr_doc[] =
00567 "";
00568
00571
00572 PyTypeObject hdr_Type = {
00573 PyObject_HEAD_INIT(&PyType_Type)
00574 0,
00575 "rpm.hdr",
00576 sizeof(hdrObject),
00577 0,
00578 (destructor) hdr_dealloc,
00579 0,
00580 (getattrfunc) 0,
00581 0,
00582 (cmpfunc) hdr_compare,
00583 0,
00584 0,
00585 0,
00586 &hdr_as_mapping,
00587 hdr_hash,
00588 0,
00589 0,
00590 (getattrofunc) hdr_getattro,
00591 (setattrofunc) hdr_setattro,
00592 0,
00593 Py_TPFLAGS_DEFAULT,
00594 hdr_doc,
00595 #if Py_TPFLAGS_HAVE_ITER
00596 0,
00597 0,
00598 0,
00599 0,
00600 0,
00601 0,
00602 hdr_methods,
00603 0,
00604 0,
00605 0,
00606 0,
00607 0,
00608 0,
00609 0,
00610 0,
00611 0,
00612 0,
00613 0,
00614 0,
00615 #endif
00616 };
00617
00618 hdrObject * hdr_Wrap(Header h)
00619 {
00620 hdrObject * hdr = PyObject_New(hdrObject, &hdr_Type);
00621 hdr->h = headerLink(h);
00622 return hdr;
00623 }
00624
00625 Header hdrGetHeader(hdrObject * s)
00626 {
00627 return s->h;
00628 }
00629
00632 PyObject * hdrLoad(PyObject * self, PyObject * args, PyObject * kwds)
00633 {
00634 hdrObject * hdr;
00635 char * copy = NULL;
00636 char * obj;
00637 Header h;
00638 int len;
00639 char * kwlist[] = {"headers", NULL};
00640
00641 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwlist, &obj, &len))
00642 return NULL;
00643
00644
00645 copy = malloc(len);
00646 if (copy == NULL) {
00647 PyErr_SetString(pyrpmError, "out of memory");
00648 return NULL;
00649 }
00650 memcpy (copy, obj, len);
00651
00652 h = headerLoad(copy);
00653 if (!h) {
00654 PyErr_SetString(pyrpmError, "bad header");
00655 return NULL;
00656 }
00657 headerAllocated(h);
00658
00659 hdr = hdr_Wrap(h);
00660 h = headerFree(h);
00661
00662 return (PyObject *) hdr;
00663 }
00664
00667 PyObject * rpmReadHeaders (FD_t fd)
00668 {
00669 PyObject * list;
00670 Header h;
00671 hdrObject * hdr;
00672
00673 if (!fd) {
00674 PyErr_SetFromErrno(pyrpmError);
00675 return NULL;
00676 }
00677
00678 list = PyList_New(0);
00679 Py_BEGIN_ALLOW_THREADS
00680 { const char item[] = "Header";
00681 const char * msg = NULL;
00682 rpmRC rc = rpmpkgRead(item, fd, &h, &msg);
00683 if (rc != RPMRC_OK)
00684 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", "rpmpkgRead", item, msg);
00685 msg = _free(msg);
00686 }
00687 Py_END_ALLOW_THREADS
00688
00689 while (h) {
00690 hdr = hdr_Wrap(h);
00691 if (PyList_Append(list, (PyObject *) hdr)) {
00692 Py_DECREF(list);
00693 Py_DECREF(hdr);
00694 return NULL;
00695 }
00696 Py_DECREF(hdr);
00697
00698 h = headerFree(h);
00699
00700 Py_BEGIN_ALLOW_THREADS
00701 { const char item[] = "Header";
00702 const char * msg = NULL;
00703 rpmRC rc = rpmpkgRead(item, fd, &h, &msg);
00704 if (rc != RPMRC_OK && rc != RPMRC_NOTFOUND)
00705 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", "rpmpkgRead", item, msg);
00706 msg = _free(msg);
00707 }
00708 Py_END_ALLOW_THREADS
00709 }
00710
00711 return list;
00712 }
00713
00716 PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args, PyObject * kwds)
00717 {
00718 FD_t fd;
00719 int fileno;
00720 PyObject * list;
00721 char * kwlist[] = {"fd", NULL};
00722
00723 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
00724 return NULL;
00725
00726 fd = fdDup(fileno);
00727
00728 list = rpmReadHeaders (fd);
00729 Fclose(fd);
00730
00731 return list;
00732 }
00733
00736 PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args, PyObject *kwds)
00737 {
00738 char * filespec;
00739 FD_t fd;
00740 PyObject * list;
00741 char * kwlist[] = {"file", NULL};
00742
00743 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &filespec))
00744 return NULL;
00745
00746 fd = Fopen(filespec, "r.fdio");
00747
00748 if (!fd) {
00749 PyErr_SetFromErrno(pyrpmError);
00750 return NULL;
00751 }
00752
00753 list = rpmReadHeaders (fd);
00754 Fclose(fd);
00755
00756 return list;
00757 }
00758
00761 PyObject *
00762 rpmSingleHeaderFromFD(PyObject * self, PyObject * args, PyObject * kwds)
00763 {
00764 FD_t fd;
00765 int fileno;
00766 off_t offset;
00767 PyObject * tuple;
00768 Header h;
00769 char * kwlist[] = {"fd", NULL};
00770
00771 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
00772 return NULL;
00773
00774 offset = lseek(fileno, 0, SEEK_CUR);
00775
00776 fd = fdDup(fileno);
00777
00778 if (!fd) {
00779 PyErr_SetFromErrno(pyrpmError);
00780 return NULL;
00781 }
00782
00783 Py_BEGIN_ALLOW_THREADS
00784 { const char item[] = "Header";
00785 const char * msg = NULL;
00786 rpmRC rc = rpmpkgRead(item, fd, &h, &msg);
00787 if (rc != RPMRC_OK)
00788 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", "rpmpkgRead", item, msg);
00789 msg = _free(msg);
00790 }
00791 Py_END_ALLOW_THREADS
00792
00793 Fclose(fd);
00794
00795 tuple = PyTuple_New(2);
00796
00797 if (h && tuple) {
00798 PyTuple_SET_ITEM(tuple, 0, (PyObject *) hdr_Wrap(h));
00799 PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(offset));
00800 h = headerFree(h);
00801 } else {
00802 Py_INCREF(Py_None);
00803 Py_INCREF(Py_None);
00804 PyTuple_SET_ITEM(tuple, 0, Py_None);
00805 PyTuple_SET_ITEM(tuple, 1, Py_None);
00806 }
00807
00808 return tuple;
00809 }
00810
00813 PyObject * versionCompare (PyObject * self, PyObject * args, PyObject * kwds)
00814 {
00815 hdrObject * h1, * h2;
00816 char * kwlist[] = {"version0", "version1", NULL};
00817
00818 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!", kwlist, &hdr_Type,
00819 &h1, &hdr_Type, &h2))
00820 return NULL;
00821
00822 return Py_BuildValue("i", hdr_compare(h1, h2));
00823 }
00824
00825 PyObject * labelCompare (PyObject * self, PyObject * args)
00826 {
00827 EVR_t A = memset(alloca(sizeof(*A)), 0, sizeof(*A));
00828 EVR_t B = memset(alloca(sizeof(*B)), 0, sizeof(*B));
00829 int rc;
00830
00831 if (!PyArg_ParseTuple(args, "(zzz)(zzz)",
00832 &A->E, &A->V, &A->R, &B->E, &B->V, &B->R))
00833 return NULL;
00834
00835 if (A->E == NULL) A->E = "0";
00836 if (B->E == NULL) B->E = "0";
00837 if (A->V == NULL) A->E = "";
00838 if (B->V == NULL) B->E = "";
00839 if (A->R == NULL) A->E = "";
00840 if (B->R == NULL) B->E = "";
00841
00842 rc = rpmEVRcompare(A, B);
00843
00844 return Py_BuildValue("i", rc);
00845 }