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 ext->u.tagFunction(s->h, &type, (const void **) &data, &count, &freeData);
00746 } else {
00747 if (tag == -1) {
00748 PyErr_SetString(PyExc_KeyError, "unknown header tag");
00749 return NULL;
00750 }
00751
00752 if (!rpmHeaderGetEntry(s->h, tag, &type, &data, &count)) {
00753 switch (tag) {
00754 case RPMTAG_EPOCH:
00755 case RPMTAG_NAME:
00756 case RPMTAG_VERSION:
00757 case RPMTAG_RELEASE:
00758 case RPMTAG_ARCH:
00759 case RPMTAG_OS:
00760 Py_INCREF(Py_None);
00761 return Py_None;
00762 break;
00763 default:
00764 return PyList_New(0);
00765 break;
00766 }
00767 }
00768 }
00769
00770 switch (tag) {
00771 case RPMTAG_OLDFILENAMES:
00772 case RPMTAG_FILESIZES:
00773 case RPMTAG_FILESTATES:
00774 case RPMTAG_FILEMODES:
00775 case RPMTAG_FILEUIDS:
00776 case RPMTAG_FILEGIDS:
00777 case RPMTAG_FILERDEVS:
00778 case RPMTAG_FILEMTIMES:
00779 case RPMTAG_FILEMD5S:
00780 case RPMTAG_FILELINKTOS:
00781 case RPMTAG_FILEFLAGS:
00782 case RPMTAG_ROOT:
00783 case RPMTAG_FILEUSERNAME:
00784 case RPMTAG_FILEGROUPNAME:
00785 case RPMTAG_REQUIRENAME:
00786 case RPMTAG_REQUIREFLAGS:
00787 case RPMTAG_REQUIREVERSION:
00788 case RPMTAG_PROVIDENAME:
00789 case RPMTAG_PROVIDEFLAGS:
00790 case RPMTAG_PROVIDEVERSION:
00791 case RPMTAG_OBSOLETENAME:
00792 case RPMTAG_OBSOLETEFLAGS:
00793 case RPMTAG_OBSOLETEVERSION:
00794 case RPMTAG_CONFLICTNAME:
00795 case RPMTAG_CONFLICTFLAGS:
00796 case RPMTAG_CONFLICTVERSION:
00797 case RPMTAG_CHANGELOGTIME:
00798 case RPMTAG_FILEVERIFYFLAGS:
00799 forceArray = 1;
00800 break;
00801 case RPMTAG_SUMMARY:
00802 case RPMTAG_GROUP:
00803 case RPMTAG_DESCRIPTION:
00804 freeData = 1;
00805 break;
00806 default:
00807 break;
00808 }
00809
00810 switch (type) {
00811 case RPM_OPENPGP_TYPE:
00812 case RPM_ASN1_TYPE:
00813 case RPM_BIN_TYPE:
00814 o = PyString_FromStringAndSize(data, count);
00815 break;
00816
00817 case RPM_INT64_TYPE:
00818 if (count != 1 || forceArray) {
00819 metao = PyList_New(0);
00820 for (i = 0; i < count; i++) {
00821 o = PyInt_FromLong(((long long *) data)[i]);
00822 PyList_Append(metao, o);
00823 Py_DECREF(o);
00824 }
00825 o = metao;
00826 } else {
00827 o = PyInt_FromLong(*((long long *) data));
00828 }
00829 break;
00830 case RPM_INT32_TYPE:
00831 if (count != 1 || forceArray) {
00832 metao = PyList_New(0);
00833 for (i = 0; i < count; i++) {
00834 o = PyInt_FromLong(((int *) data)[i]);
00835 PyList_Append(metao, o);
00836 Py_DECREF(o);
00837 }
00838 o = metao;
00839 } else {
00840 o = PyInt_FromLong(*((int *) data));
00841 }
00842 break;
00843
00844 case RPM_CHAR_TYPE:
00845 case RPM_INT8_TYPE:
00846 if (count != 1 || forceArray) {
00847 metao = PyList_New(0);
00848 for (i = 0; i < count; i++) {
00849 o = PyInt_FromLong(((char *) data)[i]);
00850 PyList_Append(metao, o);
00851 Py_DECREF(o);
00852 }
00853 o = metao;
00854 } else {
00855 o = PyInt_FromLong(*((char *) data));
00856 }
00857 break;
00858
00859 case RPM_INT16_TYPE:
00860 if (count != 1 || forceArray) {
00861 metao = PyList_New(0);
00862 for (i = 0; i < count; i++) {
00863 o = PyInt_FromLong(((short *) data)[i]);
00864 PyList_Append(metao, o);
00865 Py_DECREF(o);
00866 }
00867 o = metao;
00868 } else {
00869 o = PyInt_FromLong(*((short *) data));
00870 }
00871 break;
00872
00873 case RPM_STRING_ARRAY_TYPE:
00874 stringArray = data;
00875
00876 metao = PyList_New(0);
00877 for (i = 0; i < count; i++) {
00878 o = PyString_FromString(stringArray[i]);
00879 PyList_Append(metao, o);
00880 Py_DECREF(o);
00881 }
00882 free (stringArray);
00883 o = metao;
00884 break;
00885
00886 case RPM_STRING_TYPE:
00887 if (count != 1 || forceArray) {
00888 stringArray = data;
00889
00890 metao = PyList_New(0);
00891 for (i=0; i < count; i++) {
00892 o = PyString_FromString(stringArray[i]);
00893 PyList_Append(metao, o);
00894 Py_DECREF(o);
00895 }
00896 o = metao;
00897 } else {
00898 o = PyString_FromString(data);
00899 if (freeData)
00900 free (data);
00901 }
00902 break;
00903
00904 default:
00905 PyErr_SetString(PyExc_TypeError, "unsupported type in header");
00906 return NULL;
00907 }
00908
00909 return o;
00910 }
00911
00912 static PyObject * hdr_getattro(PyObject * o, PyObject * n)
00913
00914 {
00915 PyObject * res = PyObject_GenericGetAttr(o, n);
00916 if (res == NULL)
00917 res = hdr_subscript(o, n);
00918 return res;
00919 }
00920
00921 static int hdr_setattro(PyObject * o, PyObject * n, PyObject * v)
00922
00923 {
00924 return PyObject_GenericSetAttr(o, n, v);
00925 }
00926
00929
00930 static PyMappingMethods hdr_as_mapping = {
00931 (inquiry) 0,
00932 (binaryfunc) hdr_subscript,
00933 (objobjargproc)0,
00934 };
00935
00938 static char hdr_doc[] =
00939 "";
00940
00943
00944 PyTypeObject hdr_Type = {
00945 PyObject_HEAD_INIT(&PyType_Type)
00946 0,
00947 "rpm.hdr",
00948 sizeof(hdrObject),
00949 0,
00950 (destructor) hdr_dealloc,
00951 0,
00952 (getattrfunc) 0,
00953 0,
00954 (cmpfunc) hdr_compare,
00955 0,
00956 0,
00957 0,
00958 &hdr_as_mapping,
00959 hdr_hash,
00960 0,
00961 0,
00962 (getattrofunc) hdr_getattro,
00963 (setattrofunc) hdr_setattro,
00964 0,
00965 Py_TPFLAGS_DEFAULT,
00966 hdr_doc,
00967 #if Py_TPFLAGS_HAVE_ITER
00968 0,
00969 0,
00970 0,
00971 0,
00972 0,
00973 0,
00974 hdr_methods,
00975 0,
00976 0,
00977 0,
00978 0,
00979 0,
00980 0,
00981 0,
00982 0,
00983 0,
00984 0,
00985 0,
00986 0,
00987 #endif
00988 };
00989
00990 hdrObject * hdr_Wrap(Header h)
00991 {
00992 hdrObject * hdr = PyObject_New(hdrObject, &hdr_Type);
00993 hdr->h = headerLink(h);
00994 hdr->fileList = hdr->linkList = hdr->md5list = NULL;
00995 hdr->uids = hdr->gids = hdr->mtimes = hdr->fileSizes = NULL;
00996 hdr->modes = hdr->rdevs = NULL;
00997 return hdr;
00998 }
00999
01000 Header hdrGetHeader(hdrObject * s)
01001 {
01002 return s->h;
01003 }
01004
01007 PyObject * hdrLoad(PyObject * self, PyObject * args, PyObject * kwds)
01008 {
01009 hdrObject * hdr;
01010 char * copy = NULL;
01011 char * obj;
01012 Header h;
01013 int len;
01014 char * kwlist[] = {"headers", NULL};
01015
01016 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwlist, &obj, &len))
01017 return NULL;
01018
01019
01020 copy = malloc(len);
01021 if (copy == NULL) {
01022 PyErr_SetString(pyrpmError, "out of memory");
01023 return NULL;
01024 }
01025 memcpy (copy, obj, len);
01026
01027 h = headerLoad(copy);
01028 if (!h) {
01029 PyErr_SetString(pyrpmError, "bad header");
01030 return NULL;
01031 }
01032 headerAllocated(h);
01033 compressFilelist (h);
01034 providePackageNVR (h);
01035
01036 hdr = hdr_Wrap(h);
01037 h = headerFree(h);
01038
01039 return (PyObject *) hdr;
01040 }
01041
01044 PyObject * rpmReadHeaders (FD_t fd)
01045 {
01046 PyObject * list;
01047 Header h;
01048 hdrObject * hdr;
01049
01050 if (!fd) {
01051 PyErr_SetFromErrno(pyrpmError);
01052 return NULL;
01053 }
01054
01055 list = PyList_New(0);
01056 Py_BEGIN_ALLOW_THREADS
01057 h = headerRead(fd, HEADER_MAGIC_YES);
01058 Py_END_ALLOW_THREADS
01059
01060 while (h) {
01061 compressFilelist(h);
01062 providePackageNVR(h);
01063 hdr = hdr_Wrap(h);
01064 if (PyList_Append(list, (PyObject *) hdr)) {
01065 Py_DECREF(list);
01066 Py_DECREF(hdr);
01067 return NULL;
01068 }
01069 Py_DECREF(hdr);
01070
01071 h = headerFree(h);
01072
01073 Py_BEGIN_ALLOW_THREADS
01074 h = headerRead(fd, HEADER_MAGIC_YES);
01075 Py_END_ALLOW_THREADS
01076 }
01077
01078 return list;
01079 }
01080
01083 PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args, PyObject * kwds)
01084 {
01085 FD_t fd;
01086 int fileno;
01087 PyObject * list;
01088 char * kwlist[] = {"fd", NULL};
01089
01090 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
01091 return NULL;
01092
01093 fd = fdDup(fileno);
01094
01095 list = rpmReadHeaders (fd);
01096 Fclose(fd);
01097
01098 return list;
01099 }
01100
01103 PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args, PyObject *kwds)
01104 {
01105 char * filespec;
01106 FD_t fd;
01107 PyObject * list;
01108 char * kwlist[] = {"file", NULL};
01109
01110 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &filespec))
01111 return NULL;
01112
01113 fd = Fopen(filespec, "r.fdio");
01114
01115 if (!fd) {
01116 PyErr_SetFromErrno(pyrpmError);
01117 return NULL;
01118 }
01119
01120 list = rpmReadHeaders (fd);
01121 Fclose(fd);
01122
01123 return list;
01124 }
01125
01130 int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag)
01131 {
01132 Header h;
01133 HeaderIterator hi;
01134 int_32 * newMatch;
01135 int_32 * oldMatch;
01136 hdrObject * hdr;
01137 int count = 0;
01138 int type, c, tag;
01139 void * p;
01140
01141 Py_BEGIN_ALLOW_THREADS
01142 h = headerRead(fd, HEADER_MAGIC_YES);
01143 Py_END_ALLOW_THREADS
01144
01145 while (h) {
01146 if (!headerGetEntry(h, matchTag, NULL, &newMatch, NULL)) {
01147 PyErr_SetString(pyrpmError, "match tag missing in new header");
01148 return 1;
01149 }
01150
01151 hdr = (hdrObject *) PyList_GetItem(list, count++);
01152 if (!hdr) return 1;
01153
01154 if (!headerGetEntry(hdr->h, matchTag, NULL, &oldMatch, NULL)) {
01155 PyErr_SetString(pyrpmError, "match tag missing in new header");
01156 return 1;
01157 }
01158
01159 if (*newMatch != *oldMatch) {
01160 PyErr_SetString(pyrpmError, "match tag mismatch");
01161 return 1;
01162 }
01163
01164 hdr->md5list = _free(hdr->md5list);
01165 hdr->fileList = _free(hdr->fileList);
01166 hdr->linkList = _free(hdr->linkList);
01167
01168 for (hi = headerInitIterator(h);
01169 headerNextIterator(hi, &tag, &type, (void *) &p, &c);
01170 p = headerFreeData(p, type))
01171 {
01172
01173 headerRemoveEntry(hdr->h, tag);
01174 headerAddEntry(hdr->h, tag, type, p, c);
01175 }
01176
01177 headerFreeIterator(hi);
01178 h = headerFree(h);
01179
01180 Py_BEGIN_ALLOW_THREADS
01181 h = headerRead(fd, HEADER_MAGIC_YES);
01182 Py_END_ALLOW_THREADS
01183 }
01184
01185 return 0;
01186 }
01187
01188 PyObject *
01189 rpmMergeHeadersFromFD(PyObject * self, PyObject * args, PyObject * kwds)
01190 {
01191 FD_t fd;
01192 int fileno;
01193 PyObject * list;
01194 int rc;
01195 int matchTag;
01196 char * kwlist[] = {"list", "fd", "matchTag", NULL};
01197
01198 if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oii", kwlist, &list,
01199 &fileno, &matchTag))
01200 return NULL;
01201
01202 if (!PyList_Check(list)) {
01203 PyErr_SetString(PyExc_TypeError, "first parameter must be a list");
01204 return NULL;
01205 }
01206
01207 fd = fdDup(fileno);
01208
01209 rc = rpmMergeHeaders (list, fd, matchTag);
01210 Fclose(fd);
01211
01212 if (rc) {
01213 return NULL;
01214 }
01215
01216 Py_INCREF(Py_None);
01217 return Py_None;
01218 }
01219
01222 PyObject *
01223 rpmSingleHeaderFromFD(PyObject * self, PyObject * args, PyObject * kwds)
01224 {
01225 FD_t fd;
01226 int fileno;
01227 off_t offset;
01228 PyObject * tuple;
01229 Header h;
01230 char * kwlist[] = {"fd", NULL};
01231
01232 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
01233 return NULL;
01234
01235 offset = lseek(fileno, 0, SEEK_CUR);
01236
01237 fd = fdDup(fileno);
01238
01239 if (!fd) {
01240 PyErr_SetFromErrno(pyrpmError);
01241 return NULL;
01242 }
01243
01244 Py_BEGIN_ALLOW_THREADS
01245 h = headerRead(fd, HEADER_MAGIC_YES);
01246 Py_END_ALLOW_THREADS
01247
01248 Fclose(fd);
01249
01250 tuple = PyTuple_New(2);
01251
01252 if (h && tuple) {
01253 PyTuple_SET_ITEM(tuple, 0, (PyObject *) hdr_Wrap(h));
01254 PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(offset));
01255 h = headerFree(h);
01256 } else {
01257 Py_INCREF(Py_None);
01258 Py_INCREF(Py_None);
01259 PyTuple_SET_ITEM(tuple, 0, Py_None);
01260 PyTuple_SET_ITEM(tuple, 1, Py_None);
01261 }
01262
01263 return tuple;
01264 }
01265
01268 PyObject * versionCompare (PyObject * self, PyObject * args, PyObject * kwds)
01269 {
01270 hdrObject * h1, * h2;
01271 char * kwlist[] = {"version0", "version1", NULL};
01272
01273 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!", kwlist, &hdr_Type,
01274 &h1, &hdr_Type, &h2))
01275 return NULL;
01276
01277 return Py_BuildValue("i", hdr_compare(h1, h2));
01278 }
01279
01280 PyObject * labelCompare (PyObject * self, PyObject * args)
01281 {
01282 EVR_t A = memset(alloca(sizeof(*A)), 0, sizeof(*A));
01283 EVR_t B = memset(alloca(sizeof(*B)), 0, sizeof(*B));
01284 int rc;
01285
01286 if (!PyArg_ParseTuple(args, "(zzz)(zzz)",
01287 &A->E, &A->V, &A->R, &B->E, &B->V, &B->R))
01288 return NULL;
01289
01290 if (A->E == NULL) A->E = "0";
01291 if (B->E == NULL) B->E = "0";
01292 if (A->V == NULL) A->E = "";
01293 if (B->V == NULL) B->E = "";
01294 if (A->R == NULL) A->E = "";
01295 if (B->R == NULL) B->E = "";
01296
01297 rc = rpmEVRcompare(A, B);
01298
01299 return Py_BuildValue("i", rc);
01300 }