00001
00005 #include "system.h"
00006
00007 #include "rpmio_internal.h"
00008 #include "rpmcli.h"
00009
00010 #include "legacy.h"
00011 #include "misc.h"
00012 #include "header_internal.h"
00013
00014 #include "rpmts.h"
00015 #define _RPMEVR_INTERNAL
00016 #include "rpmevr.h"
00017
00018 #include "header-py.h"
00019 #include "rpmds-py.h"
00020 #include "rpmfi-py.h"
00021
00022 #include "debug.h"
00023
00135 struct hdrObject_s {
00136 PyObject_HEAD
00137 Header h;
00138 char ** md5list;
00139 char ** fileList;
00140 char ** linkList;
00141 int_32 * fileSizes;
00142 int_32 * mtimes;
00143 int_32 * uids, * gids;
00144 unsigned short * rdevs;
00145 unsigned short * modes;
00146 } ;
00147
00150 static inline Header headerAllocated(Header h)
00151
00152 {
00153 h->flags |= HEADERFLAG_ALLOCATED;
00154 return 0;
00155 }
00156
00157
00158 static int dncmp(const void * a, const void * b)
00159
00160 {
00161 const char *const * first = a;
00162 const char *const * second = b;
00163 return strcmp(*first, *second);
00164 }
00165
00166
00171 static void expandFilelist(Header h)
00172
00173 {
00174 HAE_t hae = (HAE_t)headerAddEntry;
00175 HRE_t hre = (HRE_t)headerRemoveEntry;
00176 const char ** fileNames = NULL;
00177 int count = 0;
00178 int xx;
00179
00180
00181 if (!headerIsEntry(h, RPMTAG_OLDFILENAMES)) {
00182 rpmfiBuildFNames(h, RPMTAG_BASENAMES, &fileNames, &count);
00183 if (fileNames == NULL || count <= 0)
00184 return;
00185 xx = hae(h, RPMTAG_OLDFILENAMES, RPM_STRING_ARRAY_TYPE,
00186 fileNames, count);
00187 fileNames = _free(fileNames);
00188 }
00189
00190
00191 xx = hre(h, RPMTAG_DIRNAMES);
00192 xx = hre(h, RPMTAG_BASENAMES);
00193 xx = hre(h, RPMTAG_DIRINDEXES);
00194 }
00195
00196
00201 static void compressFilelist(Header h)
00202
00203 {
00204 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00205 HAE_t hae = (HAE_t)headerAddEntry;
00206 HRE_t hre = (HRE_t)headerRemoveEntry;
00207 HFD_t hfd = headerFreeData;
00208 char ** fileNames;
00209 const char ** dirNames;
00210 const char ** baseNames;
00211 int_32 * dirIndexes;
00212 rpmTagType fnt;
00213 int count;
00214 int i, xx;
00215 int dirIndex = -1;
00216
00217
00218
00219
00220
00221
00222
00223 if (headerIsEntry(h, RPMTAG_DIRNAMES)) {
00224 xx = hre(h, RPMTAG_OLDFILENAMES);
00225 return;
00226 }
00227
00228 if (!hge(h, RPMTAG_OLDFILENAMES, &fnt, &fileNames, &count))
00229 return;
00230 if (fileNames == NULL || count <= 0)
00231 return;
00232
00233 dirNames = alloca(sizeof(*dirNames) * count);
00234 baseNames = alloca(sizeof(*dirNames) * count);
00235 dirIndexes = alloca(sizeof(*dirIndexes) * count);
00236
00237 if (fileNames[0][0] != '/') {
00238
00239 dirIndex = 0;
00240 dirNames[dirIndex] = "";
00241 for (i = 0; i < count; i++) {
00242 dirIndexes[i] = dirIndex;
00243 baseNames[i] = fileNames[i];
00244 }
00245 goto exit;
00246 }
00247
00248
00249 for (i = 0; i < count; i++) {
00250 const char ** needle;
00251 char savechar;
00252 char * baseName;
00253 int len;
00254
00255 if (fileNames[i] == NULL)
00256 continue;
00257 baseName = strrchr(fileNames[i], '/') + 1;
00258 len = baseName - fileNames[i];
00259 needle = dirNames;
00260 savechar = *baseName;
00261 *baseName = '\0';
00262
00263 if (dirIndex < 0 ||
00264 (needle = bsearch(&fileNames[i], dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL) {
00265 char *s = alloca(len + 1);
00266 memcpy(s, fileNames[i], len + 1);
00267 s[len] = '\0';
00268 dirIndexes[i] = ++dirIndex;
00269 dirNames[dirIndex] = s;
00270 } else
00271 dirIndexes[i] = needle - dirNames;
00272
00273
00274 *baseName = savechar;
00275 baseNames[i] = baseName;
00276 }
00277
00278
00279 exit:
00280 if (count > 0) {
00281 xx = hae(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, dirIndexes, count);
00282 xx = hae(h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE,
00283 baseNames, count);
00284 xx = hae(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
00285 dirNames, dirIndex + 1);
00286 }
00287
00288 fileNames = hfd(fileNames, fnt);
00289
00290 xx = hre(h, RPMTAG_OLDFILENAMES);
00291 }
00292
00293
00296 static void mungeFilelist(Header h)
00297
00298 {
00299 const char ** fileNames = NULL;
00300 int count = 0;
00301
00302 if (!headerIsEntry (h, RPMTAG_BASENAMES)
00303 || !headerIsEntry (h, RPMTAG_DIRNAMES)
00304 || !headerIsEntry (h, RPMTAG_DIRINDEXES))
00305 compressFilelist(h);
00306
00307 rpmfiBuildFNames(h, RPMTAG_BASENAMES, &fileNames, &count);
00308
00309 if (fileNames == NULL || count <= 0)
00310 return;
00311
00312
00313 headerAddEntry(h, RPMTAG_OLDFILENAMES, RPM_STRING_ARRAY_TYPE,
00314 fileNames, count);
00315
00316 fileNames = _free(fileNames);
00317 }
00318
00324 static void providePackageNVR(Header h)
00325 {
00326 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00327 HFD_t hfd = headerFreeData;
00328 const char *name, *version, *release;
00329 int_32 * epoch;
00330 const char *pEVR;
00331 char *p;
00332 int_32 pFlags = RPMSENSE_EQUAL;
00333 const char ** provides = NULL;
00334 const char ** providesEVR = NULL;
00335 rpmTagType pnt, pvt;
00336 int_32 * provideFlags = NULL;
00337 int providesCount;
00338 int i, xx;
00339 int bingo = 1;
00340
00341
00342 xx = headerNVR(h, &name, &version, &release);
00343 if (!(name && version && release))
00344 return;
00345 pEVR = p = alloca(21 + strlen(version) + 1 + strlen(release) + 1);
00346 *p = '\0';
00347 if (hge(h, RPMTAG_EPOCH, NULL, &epoch, NULL)) {
00348 sprintf(p, "%d:", *epoch);
00349 while (*p != '\0')
00350 p++;
00351 }
00352 (void) stpcpy( stpcpy( stpcpy(p, version) , "-") , release);
00353
00354
00355
00356
00357
00358 if (!hge(h, RPMTAG_PROVIDENAME, &pnt, &provides, &providesCount))
00359 goto exit;
00360
00361
00362
00363
00364 if (!hge(h, RPMTAG_PROVIDEVERSION, &pvt, &providesEVR, NULL)) {
00365 for (i = 0; i < providesCount; i++) {
00366 char * vdummy = "";
00367 int_32 fdummy = RPMSENSE_ANY;
00368 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE,
00369 &vdummy, 1);
00370 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
00371 &fdummy, 1);
00372 }
00373 goto exit;
00374 }
00375
00376 xx = hge(h, RPMTAG_PROVIDEFLAGS, NULL, &provideFlags, NULL);
00377
00378
00379 if (provides && providesEVR && provideFlags)
00380 for (i = 0; i < providesCount; i++) {
00381 if (!(provides[i] && providesEVR[i]))
00382 continue;
00383 if (!(provideFlags[i] == RPMSENSE_EQUAL &&
00384 !strcmp(name, provides[i]) && !strcmp(pEVR, providesEVR[i])))
00385 continue;
00386 bingo = 0;
00387 break;
00388 }
00389
00390
00391 exit:
00392 provides = hfd(provides, pnt);
00393 providesEVR = hfd(providesEVR, pvt);
00394
00395 if (bingo) {
00396 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME, RPM_STRING_ARRAY_TYPE,
00397 &name, 1);
00398 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
00399 &pFlags, 1);
00400 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE,
00401 &pEVR, 1);
00402 }
00403 }
00404
00409
00412 static PyObject * hdrKeyList(hdrObject * s)
00413
00414 {
00415 PyObject * list, *o;
00416 HeaderIterator hi;
00417 int tag, type;
00418
00419 list = PyList_New(0);
00420
00421 hi = headerInitIterator(s->h);
00422 while (headerNextIterator(hi, &tag, &type, NULL, NULL)) {
00423 if (tag == HEADER_I18NTABLE) continue;
00424
00425 switch (type) {
00426 case RPM_OPENPGP_TYPE:
00427 case RPM_ASN1_TYPE:
00428 case RPM_BIN_TYPE:
00429 case RPM_INT64_TYPE:
00430 case RPM_INT32_TYPE:
00431 case RPM_INT16_TYPE:
00432 case RPM_INT8_TYPE:
00433 case RPM_CHAR_TYPE:
00434 case RPM_STRING_ARRAY_TYPE:
00435 case RPM_STRING_TYPE:
00436 PyList_Append(list, o=PyInt_FromLong(tag));
00437 Py_DECREF(o);
00438 }
00439 }
00440 headerFreeIterator(hi);
00441
00442 return list;
00443 }
00444
00447 static PyObject * hdrUnload(hdrObject * s, PyObject * args, PyObject *keywords)
00448
00449 {
00450 char * buf;
00451 PyObject * rc;
00452 int len, legacy = 0;
00453 Header h;
00454 static char *kwlist[] = { "legacyHeader", NULL};
00455
00456 if (!PyArg_ParseTupleAndKeywords(args, keywords, "|i", kwlist, &legacy))
00457 return NULL;
00458
00459 h = headerLink(s->h);
00460
00461 if (legacy) {
00462 h = headerCopy(s->h);
00463 headerFree(s->h);
00464 }
00465 len = headerSizeof(h, 0);
00466 buf = headerUnload(h);
00467 h = headerFree(h);
00468
00469 if (buf == NULL || len == 0) {
00470 PyErr_SetString(pyrpmError, "can't unload bad header\n");
00471 return NULL;
00472 }
00473
00474 rc = PyString_FromStringAndSize(buf, len);
00475 buf = _free(buf);
00476
00477 return rc;
00478 }
00479
00482 static PyObject * hdrExpandFilelist(hdrObject * s)
00483
00484 {
00485 expandFilelist (s->h);
00486
00487 Py_INCREF(Py_None);
00488 return Py_None;
00489 }
00490
00493 static PyObject * hdrCompressFilelist(hdrObject * s)
00494
00495 {
00496 compressFilelist (s->h);
00497
00498 Py_INCREF(Py_None);
00499 return Py_None;
00500 }
00501
00504 static PyObject * hdrGetOrigin(hdrObject * s)
00505
00506 {
00507 const char * origin = NULL;
00508 if (s->h != NULL)
00509
00510 origin = headerGetOrigin(s->h);
00511 if (origin != NULL)
00512 return Py_BuildValue("s", origin);
00513 Py_INCREF(Py_None);
00514 return Py_None;
00515 }
00516
00519 static PyObject * hdrSetOrigin(hdrObject * s, PyObject * args, PyObject * kwds)
00520
00521 {
00522 char * kwlist[] = {"origin", NULL};
00523 const char * origin = NULL;
00524
00525 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:SetOrigin", kwlist, &origin))
00526 return NULL;
00527
00528 if (s->h != NULL && origin != NULL)
00529 headerSetOrigin(s->h, origin);
00530
00531 Py_INCREF(Py_None);
00532 return Py_None;
00533 }
00534
00537 static PyObject * hdrFullFilelist(hdrObject * s)
00538
00539 {
00540 mungeFilelist (s->h);
00541
00542 Py_INCREF(Py_None);
00543 return Py_None;
00544 }
00545
00548 static PyObject * hdrSprintf(hdrObject * s, PyObject * args, PyObject * kwds)
00549
00550 {
00551 char * fmt;
00552 char * r;
00553 errmsg_t err;
00554 PyObject * result;
00555 char * kwlist[] = {"format", NULL};
00556
00557 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &fmt))
00558 return NULL;
00559
00560 r = headerSprintf(s->h, fmt, rpmTagTable, rpmHeaderFormats, &err);
00561 if (!r) {
00562 PyErr_SetString(pyrpmError, err);
00563 return NULL;
00564 }
00565
00566 result = Py_BuildValue("s", r);
00567 r = _free(r);
00568
00569 return result;
00570 }
00571
00576
00577 static struct PyMethodDef hdr_methods[] = {
00578 {"keys", (PyCFunction) hdrKeyList, METH_NOARGS,
00579 NULL },
00580 {"unload", (PyCFunction) hdrUnload, METH_VARARGS|METH_KEYWORDS,
00581 NULL },
00582 {"expandFilelist", (PyCFunction) hdrExpandFilelist,METH_NOARGS,
00583 NULL },
00584 {"compressFilelist",(PyCFunction) hdrCompressFilelist,METH_NOARGS,
00585 NULL },
00586 {"fullFilelist", (PyCFunction) hdrFullFilelist, METH_NOARGS,
00587 NULL },
00588 {"getorigin", (PyCFunction) hdrGetOrigin, METH_NOARGS,
00589 NULL },
00590 {"setorigin", (PyCFunction) hdrSetOrigin, METH_NOARGS,
00591 NULL },
00592 {"sprintf", (PyCFunction) hdrSprintf, METH_VARARGS|METH_KEYWORDS,
00593 NULL },
00594
00595 {"dsOfHeader", (PyCFunction)hdr_dsOfHeader, METH_NOARGS,
00596 NULL},
00597 {"dsFromHeader", (PyCFunction)hdr_dsFromHeader, METH_VARARGS|METH_KEYWORDS,
00598 NULL},
00599 {"fiFromHeader", (PyCFunction)hdr_fiFromHeader, METH_VARARGS|METH_KEYWORDS,
00600 NULL},
00601
00602 {NULL, NULL}
00603 };
00604
00607 static int hdr_compare(hdrObject * a, hdrObject * b)
00608
00609 {
00610 return rpmVersionCompare(a->h, b->h);
00611 }
00612
00613 static long hdr_hash(PyObject * h)
00614 {
00615 return (long) h;
00616 }
00617
00618
00621 static void hdr_dealloc(hdrObject * s)
00622
00623 {
00624 if (s->h) headerFree(s->h);
00625 s->md5list = _free(s->md5list);
00626 s->fileList = _free(s->fileList);
00627 s->linkList = _free(s->linkList);
00628 PyObject_Del(s);
00629 }
00630
00633 long tagNumFromPyObject (PyObject *item)
00634 {
00635 char * str;
00636 int i;
00637
00638 if (PyInt_Check(item)) {
00639 return PyInt_AsLong(item);
00640 } else if (PyString_Check(item) || PyUnicode_Check(item)) {
00641 str = PyString_AsString(item);
00642 for (i = 0; i < rpmTagTableSize; i++)
00643 if (!xstrcasecmp(rpmTagTable[i].name + 7, str)) break;
00644 if (i < rpmTagTableSize) return rpmTagTable[i].val;
00645 }
00646 return -1;
00647 }
00648
00662 static int rpmHeaderGetEntry(Header h, int_32 tag, int_32 *type,
00663 void **p, int_32 *c)
00664
00665 {
00666 switch (tag) {
00667 case RPMTAG_OLDFILENAMES:
00668 { const char ** fl = NULL;
00669 int count;
00670 rpmfiBuildFNames(h, RPMTAG_BASENAMES, &fl, &count);
00671 if (count > 0) {
00672 *p = fl;
00673 if (c) *c = count;
00674 if (type) *type = RPM_STRING_ARRAY_TYPE;
00675 return 1;
00676 }
00677 if (c) *c = 0;
00678 return 0;
00679 } break;
00680
00681 case RPMTAG_GROUP:
00682 case RPMTAG_DESCRIPTION:
00683 case RPMTAG_SUMMARY:
00684 { char fmt[128];
00685 const char * msgstr;
00686 const char * errstr;
00687
00688 fmt[0] = '\0';
00689 (void) stpcpy( stpcpy( stpcpy( fmt, "%{"), tagName(tag)), "}\n");
00690
00691
00692 msgstr = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, &errstr);
00693 if (msgstr) {
00694 *p = (void *) msgstr;
00695 if (type) *type = RPM_STRING_TYPE;
00696 if (c) *c = 1;
00697 return 1;
00698 } else {
00699 if (c) *c = 0;
00700 return 0;
00701 }
00702 } break;
00703
00704 default:
00705 return headerGetEntry(h, tag, type, p, c);
00706 break;
00707 }
00708
00709 }
00710
00713 static PyObject * hdr_subscript(hdrObject * s, PyObject * item)
00714
00715 {
00716 int type, count, i, tag = -1;
00717 void * data;
00718 PyObject * o, * metao;
00719 char ** stringArray;
00720 int forceArray = 0;
00721 int freeData = 0;
00722 char * str;
00723 const struct headerSprintfExtension_s * ext = NULL;
00724 const struct headerSprintfExtension_s * extensions = rpmHeaderFormats;
00725
00726 if (PyCObject_Check (item))
00727 ext = PyCObject_AsVoidPtr(item);
00728 else
00729 tag = tagNumFromPyObject (item);
00730 if (tag == -1 && (PyString_Check(item) || PyUnicode_Check(item))) {
00731
00732
00733 str = PyString_AsString(item);
00734 while (extensions->name) {
00735 if (extensions->type == HEADER_EXT_TAG
00736 && !xstrcasecmp(extensions->name + 7, str)) {
00737 ext = extensions;
00738 }
00739 extensions++;
00740 }
00741 }
00742
00743
00744 if (ext) {
00745 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00746 ext->u.tagFunction(s->h, he);
00747 type = he->t;
00748 data = he->p.ptr;
00749 count = he->c;
00750 freeData = he->freeData;
00751 } else {
00752 if (tag == -1) {
00753 PyErr_SetString(PyExc_KeyError, "unknown header tag");
00754 return NULL;
00755 }
00756
00757 if (!rpmHeaderGetEntry(s->h, tag, &type, &data, &count)) {
00758 switch (tag) {
00759 case RPMTAG_EPOCH:
00760 case RPMTAG_NAME:
00761 case RPMTAG_VERSION:
00762 case RPMTAG_RELEASE:
00763 case RPMTAG_ARCH:
00764 case RPMTAG_OS:
00765 Py_INCREF(Py_None);
00766 return Py_None;
00767 break;
00768 default:
00769 return PyList_New(0);
00770 break;
00771 }
00772 }
00773 }
00774
00775 switch (tag) {
00776 case RPMTAG_OLDFILENAMES:
00777 case RPMTAG_FILESIZES:
00778 case RPMTAG_FILESTATES:
00779 case RPMTAG_FILEMODES:
00780 case RPMTAG_FILEUIDS:
00781 case RPMTAG_FILEGIDS:
00782 case RPMTAG_FILERDEVS:
00783 case RPMTAG_FILEMTIMES:
00784 case RPMTAG_FILEMD5S:
00785 case RPMTAG_FILELINKTOS:
00786 case RPMTAG_FILEFLAGS:
00787 case RPMTAG_ROOT:
00788 case RPMTAG_FILEUSERNAME:
00789 case RPMTAG_FILEGROUPNAME:
00790 case RPMTAG_REQUIRENAME:
00791 case RPMTAG_REQUIREFLAGS:
00792 case RPMTAG_REQUIREVERSION:
00793 case RPMTAG_PROVIDENAME:
00794 case RPMTAG_PROVIDEFLAGS:
00795 case RPMTAG_PROVIDEVERSION:
00796 case RPMTAG_OBSOLETENAME:
00797 case RPMTAG_OBSOLETEFLAGS:
00798 case RPMTAG_OBSOLETEVERSION:
00799 case RPMTAG_CONFLICTNAME:
00800 case RPMTAG_CONFLICTFLAGS:
00801 case RPMTAG_CONFLICTVERSION:
00802 case RPMTAG_CHANGELOGTIME:
00803 case RPMTAG_FILEVERIFYFLAGS:
00804 forceArray = 1;
00805 break;
00806 case RPMTAG_SUMMARY:
00807 case RPMTAG_GROUP:
00808 case RPMTAG_DESCRIPTION:
00809 freeData = 1;
00810 break;
00811 default:
00812 break;
00813 }
00814
00815 switch (type) {
00816 case RPM_OPENPGP_TYPE:
00817 case RPM_ASN1_TYPE:
00818 case RPM_BIN_TYPE:
00819 o = PyString_FromStringAndSize(data, count);
00820 break;
00821
00822 case RPM_INT64_TYPE:
00823 if (count != 1 || forceArray) {
00824 metao = PyList_New(0);
00825 for (i = 0; i < count; i++) {
00826 o = PyInt_FromLong(((long long *) data)[i]);
00827 PyList_Append(metao, o);
00828 Py_DECREF(o);
00829 }
00830 o = metao;
00831 } else {
00832 o = PyInt_FromLong(*((long long *) data));
00833 }
00834 break;
00835 case RPM_INT32_TYPE:
00836 if (count != 1 || forceArray) {
00837 metao = PyList_New(0);
00838 for (i = 0; i < count; i++) {
00839 o = PyInt_FromLong(((int *) data)[i]);
00840 PyList_Append(metao, o);
00841 Py_DECREF(o);
00842 }
00843 o = metao;
00844 } else {
00845 o = PyInt_FromLong(*((int *) data));
00846 }
00847 break;
00848
00849 case RPM_CHAR_TYPE:
00850 case RPM_INT8_TYPE:
00851 if (count != 1 || forceArray) {
00852 metao = PyList_New(0);
00853 for (i = 0; i < count; i++) {
00854 o = PyInt_FromLong(((char *) data)[i]);
00855 PyList_Append(metao, o);
00856 Py_DECREF(o);
00857 }
00858 o = metao;
00859 } else {
00860 o = PyInt_FromLong(*((char *) data));
00861 }
00862 break;
00863
00864 case RPM_INT16_TYPE:
00865 if (count != 1 || forceArray) {
00866 metao = PyList_New(0);
00867 for (i = 0; i < count; i++) {
00868 o = PyInt_FromLong(((short *) data)[i]);
00869 PyList_Append(metao, o);
00870 Py_DECREF(o);
00871 }
00872 o = metao;
00873 } else {
00874 o = PyInt_FromLong(*((short *) data));
00875 }
00876 break;
00877
00878 case RPM_STRING_ARRAY_TYPE:
00879 stringArray = data;
00880
00881 metao = PyList_New(0);
00882 for (i = 0; i < count; i++) {
00883 o = PyString_FromString(stringArray[i]);
00884 PyList_Append(metao, o);
00885 Py_DECREF(o);
00886 }
00887 free (stringArray);
00888 o = metao;
00889 break;
00890
00891 case RPM_STRING_TYPE:
00892 if (count != 1 || forceArray) {
00893 stringArray = data;
00894
00895 metao = PyList_New(0);
00896 for (i=0; i < count; i++) {
00897 o = PyString_FromString(stringArray[i]);
00898 PyList_Append(metao, o);
00899 Py_DECREF(o);
00900 }
00901 o = metao;
00902 } else {
00903 o = PyString_FromString(data);
00904 if (freeData)
00905 free (data);
00906 }
00907 break;
00908
00909 default:
00910 PyErr_SetString(PyExc_TypeError, "unsupported type in header");
00911 return NULL;
00912 }
00913
00914 return o;
00915 }
00916
00917 static PyObject * hdr_getattro(PyObject * o, PyObject * n)
00918
00919 {
00920 PyObject * res = PyObject_GenericGetAttr(o, n);
00921 if (res == NULL)
00922 res = hdr_subscript(o, n);
00923 return res;
00924 }
00925
00926 static int hdr_setattro(PyObject * o, PyObject * n, PyObject * v)
00927
00928 {
00929 return PyObject_GenericSetAttr(o, n, v);
00930 }
00931
00934
00935 static PyMappingMethods hdr_as_mapping = {
00936 (inquiry) 0,
00937 (binaryfunc) hdr_subscript,
00938 (objobjargproc)0,
00939 };
00940
00943 static char hdr_doc[] =
00944 "";
00945
00948
00949 PyTypeObject hdr_Type = {
00950 PyObject_HEAD_INIT(&PyType_Type)
00951 0,
00952 "rpm.hdr",
00953 sizeof(hdrObject),
00954 0,
00955 (destructor) hdr_dealloc,
00956 0,
00957 (getattrfunc) 0,
00958 0,
00959 (cmpfunc) hdr_compare,
00960 0,
00961 0,
00962 0,
00963 &hdr_as_mapping,
00964 hdr_hash,
00965 0,
00966 0,
00967 (getattrofunc) hdr_getattro,
00968 (setattrofunc) hdr_setattro,
00969 0,
00970 Py_TPFLAGS_DEFAULT,
00971 hdr_doc,
00972 #if Py_TPFLAGS_HAVE_ITER
00973 0,
00974 0,
00975 0,
00976 0,
00977 0,
00978 0,
00979 hdr_methods,
00980 0,
00981 0,
00982 0,
00983 0,
00984 0,
00985 0,
00986 0,
00987 0,
00988 0,
00989 0,
00990 0,
00991 0,
00992 #endif
00993 };
00994
00995 hdrObject * hdr_Wrap(Header h)
00996 {
00997 hdrObject * hdr = PyObject_New(hdrObject, &hdr_Type);
00998 hdr->h = headerLink(h);
00999 hdr->fileList = hdr->linkList = hdr->md5list = NULL;
01000 hdr->uids = hdr->gids = hdr->mtimes = hdr->fileSizes = NULL;
01001 hdr->modes = hdr->rdevs = NULL;
01002 return hdr;
01003 }
01004
01005 Header hdrGetHeader(hdrObject * s)
01006 {
01007 return s->h;
01008 }
01009
01012 PyObject * hdrLoad(PyObject * self, PyObject * args, PyObject * kwds)
01013 {
01014 hdrObject * hdr;
01015 char * copy = NULL;
01016 char * obj;
01017 Header h;
01018 int len;
01019 char * kwlist[] = {"headers", NULL};
01020
01021 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwlist, &obj, &len))
01022 return NULL;
01023
01024
01025 copy = malloc(len);
01026 if (copy == NULL) {
01027 PyErr_SetString(pyrpmError, "out of memory");
01028 return NULL;
01029 }
01030 memcpy (copy, obj, len);
01031
01032 h = headerLoad(copy);
01033 if (!h) {
01034 PyErr_SetString(pyrpmError, "bad header");
01035 return NULL;
01036 }
01037 headerAllocated(h);
01038 compressFilelist (h);
01039 providePackageNVR (h);
01040
01041 hdr = hdr_Wrap(h);
01042 h = headerFree(h);
01043
01044 return (PyObject *) hdr;
01045 }
01046
01049 PyObject * rpmReadHeaders (FD_t fd)
01050 {
01051 PyObject * list;
01052 Header h;
01053 hdrObject * hdr;
01054
01055 if (!fd) {
01056 PyErr_SetFromErrno(pyrpmError);
01057 return NULL;
01058 }
01059
01060 list = PyList_New(0);
01061 Py_BEGIN_ALLOW_THREADS
01062 h = headerRead(fd, HEADER_MAGIC_YES);
01063 Py_END_ALLOW_THREADS
01064
01065 while (h) {
01066 compressFilelist(h);
01067 providePackageNVR(h);
01068 hdr = hdr_Wrap(h);
01069 if (PyList_Append(list, (PyObject *) hdr)) {
01070 Py_DECREF(list);
01071 Py_DECREF(hdr);
01072 return NULL;
01073 }
01074 Py_DECREF(hdr);
01075
01076 h = headerFree(h);
01077
01078 Py_BEGIN_ALLOW_THREADS
01079 h = headerRead(fd, HEADER_MAGIC_YES);
01080 Py_END_ALLOW_THREADS
01081 }
01082
01083 return list;
01084 }
01085
01088 PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args, PyObject * kwds)
01089 {
01090 FD_t fd;
01091 int fileno;
01092 PyObject * list;
01093 char * kwlist[] = {"fd", NULL};
01094
01095 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
01096 return NULL;
01097
01098 fd = fdDup(fileno);
01099
01100 list = rpmReadHeaders (fd);
01101 Fclose(fd);
01102
01103 return list;
01104 }
01105
01108 PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args, PyObject *kwds)
01109 {
01110 char * filespec;
01111 FD_t fd;
01112 PyObject * list;
01113 char * kwlist[] = {"file", NULL};
01114
01115 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &filespec))
01116 return NULL;
01117
01118 fd = Fopen(filespec, "r.fdio");
01119
01120 if (!fd) {
01121 PyErr_SetFromErrno(pyrpmError);
01122 return NULL;
01123 }
01124
01125 list = rpmReadHeaders (fd);
01126 Fclose(fd);
01127
01128 return list;
01129 }
01130
01135 int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag)
01136 {
01137 Header h;
01138 HeaderIterator hi;
01139 int_32 * newMatch;
01140 int_32 * oldMatch;
01141 hdrObject * hdr;
01142 int count = 0;
01143 int type, c, tag;
01144 void * p;
01145
01146 Py_BEGIN_ALLOW_THREADS
01147 h = headerRead(fd, HEADER_MAGIC_YES);
01148 Py_END_ALLOW_THREADS
01149
01150 while (h) {
01151 if (!headerGetEntry(h, matchTag, NULL, &newMatch, NULL)) {
01152 PyErr_SetString(pyrpmError, "match tag missing in new header");
01153 return 1;
01154 }
01155
01156 hdr = (hdrObject *) PyList_GetItem(list, count++);
01157 if (!hdr) return 1;
01158
01159 if (!headerGetEntry(hdr->h, matchTag, NULL, &oldMatch, NULL)) {
01160 PyErr_SetString(pyrpmError, "match tag missing in new header");
01161 return 1;
01162 }
01163
01164 if (*newMatch != *oldMatch) {
01165 PyErr_SetString(pyrpmError, "match tag mismatch");
01166 return 1;
01167 }
01168
01169 hdr->md5list = _free(hdr->md5list);
01170 hdr->fileList = _free(hdr->fileList);
01171 hdr->linkList = _free(hdr->linkList);
01172
01173 for (hi = headerInitIterator(h);
01174 headerNextIterator(hi, &tag, &type, (void *) &p, &c);
01175 p = headerFreeData(p, type))
01176 {
01177
01178 headerRemoveEntry(hdr->h, tag);
01179 headerAddEntry(hdr->h, tag, type, p, c);
01180 }
01181
01182 headerFreeIterator(hi);
01183 h = headerFree(h);
01184
01185 Py_BEGIN_ALLOW_THREADS
01186 h = headerRead(fd, HEADER_MAGIC_YES);
01187 Py_END_ALLOW_THREADS
01188 }
01189
01190 return 0;
01191 }
01192
01193 PyObject *
01194 rpmMergeHeadersFromFD(PyObject * self, PyObject * args, PyObject * kwds)
01195 {
01196 FD_t fd;
01197 int fileno;
01198 PyObject * list;
01199 int rc;
01200 int matchTag;
01201 char * kwlist[] = {"list", "fd", "matchTag", NULL};
01202
01203 if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oii", kwlist, &list,
01204 &fileno, &matchTag))
01205 return NULL;
01206
01207 if (!PyList_Check(list)) {
01208 PyErr_SetString(PyExc_TypeError, "first parameter must be a list");
01209 return NULL;
01210 }
01211
01212 fd = fdDup(fileno);
01213
01214 rc = rpmMergeHeaders (list, fd, matchTag);
01215 Fclose(fd);
01216
01217 if (rc) {
01218 return NULL;
01219 }
01220
01221 Py_INCREF(Py_None);
01222 return Py_None;
01223 }
01224
01227 PyObject *
01228 rpmSingleHeaderFromFD(PyObject * self, PyObject * args, PyObject * kwds)
01229 {
01230 FD_t fd;
01231 int fileno;
01232 off_t offset;
01233 PyObject * tuple;
01234 Header h;
01235 char * kwlist[] = {"fd", NULL};
01236
01237 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
01238 return NULL;
01239
01240 offset = lseek(fileno, 0, SEEK_CUR);
01241
01242 fd = fdDup(fileno);
01243
01244 if (!fd) {
01245 PyErr_SetFromErrno(pyrpmError);
01246 return NULL;
01247 }
01248
01249 Py_BEGIN_ALLOW_THREADS
01250 h = headerRead(fd, HEADER_MAGIC_YES);
01251 Py_END_ALLOW_THREADS
01252
01253 Fclose(fd);
01254
01255 tuple = PyTuple_New(2);
01256
01257 if (h && tuple) {
01258 PyTuple_SET_ITEM(tuple, 0, (PyObject *) hdr_Wrap(h));
01259 PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(offset));
01260 h = headerFree(h);
01261 } else {
01262 Py_INCREF(Py_None);
01263 Py_INCREF(Py_None);
01264 PyTuple_SET_ITEM(tuple, 0, Py_None);
01265 PyTuple_SET_ITEM(tuple, 1, Py_None);
01266 }
01267
01268 return tuple;
01269 }
01270
01273 PyObject * versionCompare (PyObject * self, PyObject * args, PyObject * kwds)
01274 {
01275 hdrObject * h1, * h2;
01276 char * kwlist[] = {"version0", "version1", NULL};
01277
01278 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!", kwlist, &hdr_Type,
01279 &h1, &hdr_Type, &h2))
01280 return NULL;
01281
01282 return Py_BuildValue("i", hdr_compare(h1, h2));
01283 }
01284
01285 PyObject * labelCompare (PyObject * self, PyObject * args)
01286 {
01287 EVR_t A = memset(alloca(sizeof(*A)), 0, sizeof(*A));
01288 EVR_t B = memset(alloca(sizeof(*B)), 0, sizeof(*B));
01289 int rc;
01290
01291 if (!PyArg_ParseTuple(args, "(zzz)(zzz)",
01292 &A->E, &A->V, &A->R, &B->E, &B->V, &B->R))
01293 return NULL;
01294
01295 if (A->E == NULL) A->E = "0";
01296 if (B->E == NULL) B->E = "0";
01297 if (A->V == NULL) A->E = "";
01298 if (B->V == NULL) B->E = "";
01299 if (A->R == NULL) A->E = "";
01300 if (B->R == NULL) B->E = "";
01301
01302 rc = rpmEVRcompare(A, B);
01303
01304 return Py_BuildValue("i", rc);
01305 }