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, (void **) &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, (void **) &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, (void **) &provides, &providesCount))
00359 goto exit;
00360
00361
00362
00363
00364 if (!hge(h, RPMTAG_PROVIDEVERSION, &pvt, (void **) &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, (void **) &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 static PyObject * hdr_getattro(PyObject * o, PyObject * n)
00619
00620 {
00621 return PyObject_GenericGetAttr(o, n);
00622 }
00623
00624 static int hdr_setattro(PyObject * o, PyObject * n, PyObject * v)
00625
00626 {
00627 return PyObject_GenericSetAttr(o, n, v);
00628 }
00629
00630
00633 static void hdr_dealloc(hdrObject * s)
00634
00635 {
00636 if (s->h) headerFree(s->h);
00637 s->md5list = _free(s->md5list);
00638 s->fileList = _free(s->fileList);
00639 s->linkList = _free(s->linkList);
00640 PyObject_Del(s);
00641 }
00642
00645 long tagNumFromPyObject (PyObject *item)
00646 {
00647 char * str;
00648 int i;
00649
00650 if (PyInt_Check(item)) {
00651 return PyInt_AsLong(item);
00652 } else if (PyString_Check(item) || PyUnicode_Check(item)) {
00653 str = PyString_AsString(item);
00654 for (i = 0; i < rpmTagTableSize; i++)
00655 if (!xstrcasecmp(rpmTagTable[i].name + 7, str)) break;
00656 if (i < rpmTagTableSize) return rpmTagTable[i].val;
00657 }
00658 return -1;
00659 }
00660
00674 static int rpmHeaderGetEntry(Header h, int_32 tag, int_32 *type,
00675 void **p, int_32 *c)
00676
00677 {
00678 switch (tag) {
00679 case RPMTAG_OLDFILENAMES:
00680 { const char ** fl = NULL;
00681 int count;
00682 rpmfiBuildFNames(h, RPMTAG_BASENAMES, &fl, &count);
00683 if (count > 0) {
00684 *p = fl;
00685 if (c) *c = count;
00686 if (type) *type = RPM_STRING_ARRAY_TYPE;
00687 return 1;
00688 }
00689 if (c) *c = 0;
00690 return 0;
00691 } break;
00692
00693 case RPMTAG_GROUP:
00694 case RPMTAG_DESCRIPTION:
00695 case RPMTAG_SUMMARY:
00696 { char fmt[128];
00697 const char * msgstr;
00698 const char * errstr;
00699
00700 fmt[0] = '\0';
00701 (void) stpcpy( stpcpy( stpcpy( fmt, "%{"), tagName(tag)), "}\n");
00702
00703
00704 msgstr = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, &errstr);
00705 if (msgstr) {
00706 *p = (void *) msgstr;
00707 if (type) *type = RPM_STRING_TYPE;
00708 if (c) *c = 1;
00709 return 1;
00710 } else {
00711 if (c) *c = 0;
00712 return 0;
00713 }
00714 } break;
00715
00716 default:
00717 return headerGetEntry(h, tag, type, p, c);
00718 break;
00719 }
00720
00721 }
00722
00725 static PyObject * hdr_subscript(hdrObject * s, PyObject * item)
00726
00727 {
00728 int type, count, i, tag = -1;
00729 void * data;
00730 PyObject * o, * metao;
00731 char ** stringArray;
00732 int forceArray = 0;
00733 int freeData = 0;
00734 char * str;
00735 const struct headerSprintfExtension_s * ext = NULL;
00736 const struct headerSprintfExtension_s * extensions = rpmHeaderFormats;
00737
00738 if (PyCObject_Check (item))
00739 ext = PyCObject_AsVoidPtr(item);
00740 else
00741 tag = tagNumFromPyObject (item);
00742 if (tag == -1 && (PyString_Check(item) || PyUnicode_Check(item))) {
00743
00744
00745 str = PyString_AsString(item);
00746 while (extensions->name) {
00747 if (extensions->type == HEADER_EXT_TAG
00748 && !xstrcasecmp(extensions->name + 7, str)) {
00749 ext = extensions;
00750 }
00751 extensions++;
00752 }
00753 }
00754
00755
00756 if (ext) {
00757 ext->u.tagFunction(s->h, &type, (const void **) &data, &count, &freeData);
00758 } else {
00759 if (tag == -1) {
00760 PyErr_SetString(PyExc_KeyError, "unknown header tag");
00761 return NULL;
00762 }
00763
00764 if (!rpmHeaderGetEntry(s->h, tag, &type, &data, &count)) {
00765 switch (tag) {
00766 case RPMTAG_EPOCH:
00767 case RPMTAG_NAME:
00768 case RPMTAG_VERSION:
00769 case RPMTAG_RELEASE:
00770 case RPMTAG_ARCH:
00771 case RPMTAG_OS:
00772 Py_INCREF(Py_None);
00773 return Py_None;
00774 break;
00775 default:
00776 return PyList_New(0);
00777 break;
00778 }
00779 }
00780 }
00781
00782 switch (tag) {
00783 case RPMTAG_OLDFILENAMES:
00784 case RPMTAG_FILESIZES:
00785 case RPMTAG_FILESTATES:
00786 case RPMTAG_FILEMODES:
00787 case RPMTAG_FILEUIDS:
00788 case RPMTAG_FILEGIDS:
00789 case RPMTAG_FILERDEVS:
00790 case RPMTAG_FILEMTIMES:
00791 case RPMTAG_FILEMD5S:
00792 case RPMTAG_FILELINKTOS:
00793 case RPMTAG_FILEFLAGS:
00794 case RPMTAG_ROOT:
00795 case RPMTAG_FILEUSERNAME:
00796 case RPMTAG_FILEGROUPNAME:
00797 case RPMTAG_REQUIRENAME:
00798 case RPMTAG_REQUIREFLAGS:
00799 case RPMTAG_REQUIREVERSION:
00800 case RPMTAG_PROVIDENAME:
00801 case RPMTAG_PROVIDEFLAGS:
00802 case RPMTAG_PROVIDEVERSION:
00803 case RPMTAG_OBSOLETENAME:
00804 case RPMTAG_OBSOLETEFLAGS:
00805 case RPMTAG_OBSOLETEVERSION:
00806 case RPMTAG_CONFLICTNAME:
00807 case RPMTAG_CONFLICTFLAGS:
00808 case RPMTAG_CONFLICTVERSION:
00809 case RPMTAG_CHANGELOGTIME:
00810 forceArray = 1;
00811 break;
00812 case RPMTAG_SUMMARY:
00813 case RPMTAG_GROUP:
00814 case RPMTAG_DESCRIPTION:
00815 freeData = 1;
00816 break;
00817 default:
00818 break;
00819 }
00820
00821 switch (type) {
00822 case RPM_OPENPGP_TYPE:
00823 case RPM_ASN1_TYPE:
00824 case RPM_BIN_TYPE:
00825 o = PyString_FromStringAndSize(data, count);
00826 break;
00827
00828 case RPM_INT64_TYPE:
00829 if (count != 1 || forceArray) {
00830 metao = PyList_New(0);
00831 for (i = 0; i < count; i++) {
00832 o = PyInt_FromLong(((long long *) data)[i]);
00833 PyList_Append(metao, o);
00834 Py_DECREF(o);
00835 }
00836 o = metao;
00837 } else {
00838 o = PyInt_FromLong(*((long long *) data));
00839 }
00840 break;
00841 case RPM_INT32_TYPE:
00842 if (count != 1 || forceArray) {
00843 metao = PyList_New(0);
00844 for (i = 0; i < count; i++) {
00845 o = PyInt_FromLong(((int *) data)[i]);
00846 PyList_Append(metao, o);
00847 Py_DECREF(o);
00848 }
00849 o = metao;
00850 } else {
00851 o = PyInt_FromLong(*((int *) data));
00852 }
00853 break;
00854
00855 case RPM_CHAR_TYPE:
00856 case RPM_INT8_TYPE:
00857 if (count != 1 || forceArray) {
00858 metao = PyList_New(0);
00859 for (i = 0; i < count; i++) {
00860 o = PyInt_FromLong(((char *) data)[i]);
00861 PyList_Append(metao, o);
00862 Py_DECREF(o);
00863 }
00864 o = metao;
00865 } else {
00866 o = PyInt_FromLong(*((char *) data));
00867 }
00868 break;
00869
00870 case RPM_INT16_TYPE:
00871 if (count != 1 || forceArray) {
00872 metao = PyList_New(0);
00873 for (i = 0; i < count; i++) {
00874 o = PyInt_FromLong(((short *) data)[i]);
00875 PyList_Append(metao, o);
00876 Py_DECREF(o);
00877 }
00878 o = metao;
00879 } else {
00880 o = PyInt_FromLong(*((short *) data));
00881 }
00882 break;
00883
00884 case RPM_STRING_ARRAY_TYPE:
00885 stringArray = data;
00886
00887 metao = PyList_New(0);
00888 for (i = 0; i < count; i++) {
00889 o = PyString_FromString(stringArray[i]);
00890 PyList_Append(metao, o);
00891 Py_DECREF(o);
00892 }
00893 free (stringArray);
00894 o = metao;
00895 break;
00896
00897 case RPM_STRING_TYPE:
00898 if (count != 1 || forceArray) {
00899 stringArray = data;
00900
00901 metao = PyList_New(0);
00902 for (i=0; i < count; i++) {
00903 o = PyString_FromString(stringArray[i]);
00904 PyList_Append(metao, o);
00905 Py_DECREF(o);
00906 }
00907 o = metao;
00908 } else {
00909 o = PyString_FromString(data);
00910 if (freeData)
00911 free (data);
00912 }
00913 break;
00914
00915 default:
00916 PyErr_SetString(PyExc_TypeError, "unsupported type in header");
00917 return NULL;
00918 }
00919
00920 return o;
00921 }
00922
00925
00926 static PyMappingMethods hdr_as_mapping = {
00927 (inquiry) 0,
00928 (binaryfunc) hdr_subscript,
00929 (objobjargproc)0,
00930 };
00931
00934 static char hdr_doc[] =
00935 "";
00936
00939
00940 PyTypeObject hdr_Type = {
00941 PyObject_HEAD_INIT(&PyType_Type)
00942 0,
00943 "rpm.hdr",
00944 sizeof(hdrObject),
00945 0,
00946 (destructor) hdr_dealloc,
00947 0,
00948 (getattrfunc) 0,
00949 0,
00950 (cmpfunc) hdr_compare,
00951 0,
00952 0,
00953 0,
00954 &hdr_as_mapping,
00955 hdr_hash,
00956 0,
00957 0,
00958 (getattrofunc) hdr_getattro,
00959 (setattrofunc) hdr_setattro,
00960 0,
00961 Py_TPFLAGS_DEFAULT,
00962 hdr_doc,
00963 #if Py_TPFLAGS_HAVE_ITER
00964 0,
00965 0,
00966 0,
00967 0,
00968 0,
00969 0,
00970 hdr_methods,
00971 0,
00972 0,
00973 0,
00974 0,
00975 0,
00976 0,
00977 0,
00978 0,
00979 0,
00980 0,
00981 0,
00982 0,
00983 #endif
00984 };
00985
00986 hdrObject * hdr_Wrap(Header h)
00987 {
00988 hdrObject * hdr = PyObject_New(hdrObject, &hdr_Type);
00989 hdr->h = headerLink(h);
00990 hdr->fileList = hdr->linkList = hdr->md5list = NULL;
00991 hdr->uids = hdr->gids = hdr->mtimes = hdr->fileSizes = NULL;
00992 hdr->modes = hdr->rdevs = NULL;
00993 return hdr;
00994 }
00995
00996 Header hdrGetHeader(hdrObject * s)
00997 {
00998 return s->h;
00999 }
01000
01003 PyObject * hdrLoad(PyObject * self, PyObject * args, PyObject * kwds)
01004 {
01005 hdrObject * hdr;
01006 char * copy = NULL;
01007 char * obj;
01008 Header h;
01009 int len;
01010 char * kwlist[] = {"headers", NULL};
01011
01012 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwlist, &obj, &len))
01013 return NULL;
01014
01015
01016 copy = malloc(len);
01017 if (copy == NULL) {
01018 PyErr_SetString(pyrpmError, "out of memory");
01019 return NULL;
01020 }
01021 memcpy (copy, obj, len);
01022
01023 h = headerLoad(copy);
01024 if (!h) {
01025 PyErr_SetString(pyrpmError, "bad header");
01026 return NULL;
01027 }
01028 headerAllocated(h);
01029 compressFilelist (h);
01030 providePackageNVR (h);
01031
01032 hdr = hdr_Wrap(h);
01033 h = headerFree(h);
01034
01035 return (PyObject *) hdr;
01036 }
01037
01040 PyObject * rpmReadHeaders (FD_t fd)
01041 {
01042 PyObject * list;
01043 Header h;
01044 hdrObject * hdr;
01045
01046 if (!fd) {
01047 PyErr_SetFromErrno(pyrpmError);
01048 return NULL;
01049 }
01050
01051 list = PyList_New(0);
01052 Py_BEGIN_ALLOW_THREADS
01053 h = headerRead(fd, HEADER_MAGIC_YES);
01054 Py_END_ALLOW_THREADS
01055
01056 while (h) {
01057 compressFilelist(h);
01058 providePackageNVR(h);
01059 hdr = hdr_Wrap(h);
01060 if (PyList_Append(list, (PyObject *) hdr)) {
01061 Py_DECREF(list);
01062 Py_DECREF(hdr);
01063 return NULL;
01064 }
01065 Py_DECREF(hdr);
01066
01067 h = headerFree(h);
01068
01069 Py_BEGIN_ALLOW_THREADS
01070 h = headerRead(fd, HEADER_MAGIC_YES);
01071 Py_END_ALLOW_THREADS
01072 }
01073
01074 return list;
01075 }
01076
01079 PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args, PyObject * kwds)
01080 {
01081 FD_t fd;
01082 int fileno;
01083 PyObject * list;
01084 char * kwlist[] = {"fd", NULL};
01085
01086 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
01087 return NULL;
01088
01089 fd = fdDup(fileno);
01090
01091 list = rpmReadHeaders (fd);
01092 Fclose(fd);
01093
01094 return list;
01095 }
01096
01099 PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args, PyObject *kwds)
01100 {
01101 char * filespec;
01102 FD_t fd;
01103 PyObject * list;
01104 char * kwlist[] = {"file", NULL};
01105
01106 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &filespec))
01107 return NULL;
01108
01109 fd = Fopen(filespec, "r.fdio");
01110
01111 if (!fd) {
01112 PyErr_SetFromErrno(pyrpmError);
01113 return NULL;
01114 }
01115
01116 list = rpmReadHeaders (fd);
01117 Fclose(fd);
01118
01119 return list;
01120 }
01121
01126 int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag)
01127 {
01128 Header h;
01129 HeaderIterator hi;
01130 int_32 * newMatch;
01131 int_32 * oldMatch;
01132 hdrObject * hdr;
01133 int count = 0;
01134 int type, c, tag;
01135 void * p;
01136
01137 Py_BEGIN_ALLOW_THREADS
01138 h = headerRead(fd, HEADER_MAGIC_YES);
01139 Py_END_ALLOW_THREADS
01140
01141 while (h) {
01142 if (!headerGetEntry(h, matchTag, NULL, (void **) &newMatch, NULL)) {
01143 PyErr_SetString(pyrpmError, "match tag missing in new header");
01144 return 1;
01145 }
01146
01147 hdr = (hdrObject *) PyList_GetItem(list, count++);
01148 if (!hdr) return 1;
01149
01150 if (!headerGetEntry(hdr->h, matchTag, NULL, (void **) &oldMatch, NULL)) {
01151 PyErr_SetString(pyrpmError, "match tag missing in new header");
01152 return 1;
01153 }
01154
01155 if (*newMatch != *oldMatch) {
01156 PyErr_SetString(pyrpmError, "match tag mismatch");
01157 return 1;
01158 }
01159
01160 hdr->md5list = _free(hdr->md5list);
01161 hdr->fileList = _free(hdr->fileList);
01162 hdr->linkList = _free(hdr->linkList);
01163
01164 for (hi = headerInitIterator(h);
01165 headerNextIterator(hi, &tag, &type, (void *) &p, &c);
01166 p = headerFreeData(p, type))
01167 {
01168
01169 headerRemoveEntry(hdr->h, tag);
01170 headerAddEntry(hdr->h, tag, type, p, c);
01171 }
01172
01173 headerFreeIterator(hi);
01174 h = headerFree(h);
01175
01176 Py_BEGIN_ALLOW_THREADS
01177 h = headerRead(fd, HEADER_MAGIC_YES);
01178 Py_END_ALLOW_THREADS
01179 }
01180
01181 return 0;
01182 }
01183
01184 PyObject *
01185 rpmMergeHeadersFromFD(PyObject * self, PyObject * args, PyObject * kwds)
01186 {
01187 FD_t fd;
01188 int fileno;
01189 PyObject * list;
01190 int rc;
01191 int matchTag;
01192 char * kwlist[] = {"list", "fd", "matchTag", NULL};
01193
01194 if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oii", kwlist, &list,
01195 &fileno, &matchTag))
01196 return NULL;
01197
01198 if (!PyList_Check(list)) {
01199 PyErr_SetString(PyExc_TypeError, "first parameter must be a list");
01200 return NULL;
01201 }
01202
01203 fd = fdDup(fileno);
01204
01205 rc = rpmMergeHeaders (list, fd, matchTag);
01206 Fclose(fd);
01207
01208 if (rc) {
01209 return NULL;
01210 }
01211
01212 Py_INCREF(Py_None);
01213 return Py_None;
01214 }
01215
01218 PyObject *
01219 rpmSingleHeaderFromFD(PyObject * self, PyObject * args, PyObject * kwds)
01220 {
01221 FD_t fd;
01222 int fileno;
01223 off_t offset;
01224 PyObject * tuple;
01225 Header h;
01226 char * kwlist[] = {"fd", NULL};
01227
01228 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
01229 return NULL;
01230
01231 offset = lseek(fileno, 0, SEEK_CUR);
01232
01233 fd = fdDup(fileno);
01234
01235 if (!fd) {
01236 PyErr_SetFromErrno(pyrpmError);
01237 return NULL;
01238 }
01239
01240 Py_BEGIN_ALLOW_THREADS
01241 h = headerRead(fd, HEADER_MAGIC_YES);
01242 Py_END_ALLOW_THREADS
01243
01244 Fclose(fd);
01245
01246 tuple = PyTuple_New(2);
01247
01248 if (h && tuple) {
01249 PyTuple_SET_ITEM(tuple, 0, (PyObject *) hdr_Wrap(h));
01250 PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(offset));
01251 h = headerFree(h);
01252 } else {
01253 Py_INCREF(Py_None);
01254 Py_INCREF(Py_None);
01255 PyTuple_SET_ITEM(tuple, 0, Py_None);
01256 PyTuple_SET_ITEM(tuple, 1, Py_None);
01257 }
01258
01259 return tuple;
01260 }
01261
01264 PyObject * versionCompare (PyObject * self, PyObject * args, PyObject * kwds)
01265 {
01266 hdrObject * h1, * h2;
01267 char * kwlist[] = {"version0", "version1", NULL};
01268
01269 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!", kwlist, &hdr_Type,
01270 &h1, &hdr_Type, &h2))
01271 return NULL;
01272
01273 return Py_BuildValue("i", hdr_compare(h1, h2));
01274 }
01275
01276 PyObject * labelCompare (PyObject * self, PyObject * args)
01277 {
01278 EVR_t A = memset(alloca(sizeof(*A)), 0, sizeof(*A));
01279 EVR_t B = memset(alloca(sizeof(*B)), 0, sizeof(*B));
01280 int rc;
01281
01282 if (!PyArg_ParseTuple(args, "(zzz)(zzz)",
01283 &A->E, &A->V, &A->R, &B->E, &B->V, &B->R))
01284 return NULL;
01285
01286 if (A->E == NULL) A->E = "0";
01287 if (B->E == NULL) B->E = "0";
01288 if (A->V == NULL) A->E = "";
01289 if (B->V == NULL) B->E = "";
01290 if (A->R == NULL) A->E = "";
01291 if (B->R == NULL) B->E = "";
01292
01293 rc = rpmEVRcompare(A, B);
01294
01295 return Py_BuildValue("i", rc);
01296 }