Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

python/header-py.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include "Python.h"
00008 #ifdef __LCLINT__
00009 #undef  PyObject_HEAD
00010 #define PyObject_HEAD   int _PyObjectHead;
00011 #endif
00012 
00013 #include "rpmio_internal.h"
00014 #include "rpmcli.h"     /* XXX for rpmCheckSig */
00015 
00016 #include "legacy.h"
00017 #include "misc.h"
00018 #include "header_internal.h"
00019 
00020 #include "rpmts.h"      /* XXX rpmtsCreate/rpmtsFree */
00021 
00022 #include "header-py.h"
00023 #include "rpmds-py.h"
00024 #include "rpmfi-py.h"
00025 
00026 #include "debug.h"
00027 
00090 
00093 struct hdrObject_s {
00094     PyObject_HEAD
00095     Header h;
00096     char ** md5list;
00097     char ** fileList;
00098     char ** linkList;
00099     int_32 * fileSizes;
00100     int_32 * mtimes;
00101     int_32 * uids, * gids;      /* XXX these tags are not used anymore */
00102     unsigned short * rdevs;
00103     unsigned short * modes;
00104 } ;
00105 
00106 /*@unused@*/ static inline Header headerAllocated(Header h)
00107         /*@modifies h @*/
00108 {
00109     h->flags |= HEADERFLAG_ALLOCATED;
00110     return 0;
00111 }
00112 
00115 static PyObject * hdrKeyList(hdrObject * s, PyObject * args)
00116         /*@*/
00117 {
00118     PyObject * list, *o;
00119     HeaderIterator hi;
00120     int tag, type;
00121 
00122     if (!PyArg_ParseTuple(args, "")) return NULL;
00123 
00124     list = PyList_New(0);
00125 
00126     hi = headerInitIterator(s->h);
00127     while (headerNextIterator(hi, &tag, &type, NULL, NULL)) {
00128         if (tag == HEADER_I18NTABLE) continue;
00129 
00130         switch (type) {
00131         case RPM_BIN_TYPE:
00132         case RPM_INT32_TYPE:
00133         case RPM_CHAR_TYPE:
00134         case RPM_INT8_TYPE:
00135         case RPM_INT16_TYPE:
00136         case RPM_STRING_ARRAY_TYPE:
00137         case RPM_STRING_TYPE:
00138             PyList_Append(list, o=PyInt_FromLong(tag));
00139             Py_DECREF(o);
00140         }
00141     }
00142     headerFreeIterator(hi);
00143 
00144     return list;
00145 }
00146 
00149 static PyObject * hdrUnload(hdrObject * s, PyObject * args, PyObject *keywords)
00150         /*@*/
00151 {
00152     char * buf;
00153     PyObject * rc;
00154     int len, legacy = 0;
00155     Header h;
00156     static char *kwlist[] = { "legacyHeader", NULL};
00157 
00158     if (!PyArg_ParseTupleAndKeywords(args, keywords, "|i", kwlist, &legacy))
00159         return NULL; 
00160 
00161     h = headerLink(s->h);
00162     /* XXX this legacy switch is a hack, needs to be removed. */
00163     if (legacy) {
00164         h = headerCopy(s->h);   /* XXX strip region tags, etc */
00165         headerFree(s->h);
00166     }
00167     len = headerSizeof(h, 0);
00168     buf = headerUnload(h);
00169     h = headerFree(h);
00170 
00171     if (buf == NULL || len == 0) {
00172         PyErr_SetString(pyrpmError, "can't unload bad header\n");
00173         return NULL;
00174     }
00175 
00176     rc = PyString_FromStringAndSize(buf, len);
00177     buf = _free(buf);
00178 
00179     return rc;
00180 }
00181 
00184 static PyObject * hdrExpandFilelist(hdrObject * s, PyObject * args)
00185         /*@*/
00186 {
00187     expandFilelist (s->h);
00188 
00189     Py_INCREF(Py_None);
00190     return Py_None;
00191 }
00192 
00195 static PyObject * hdrCompressFilelist(hdrObject * s, PyObject * args)
00196         /*@*/
00197 {
00198     compressFilelist (s->h);
00199 
00200     Py_INCREF(Py_None);
00201     return Py_None;
00202 }
00203 
00204 /* make a header with _all_ the tags we need */
00207 static void mungeFilelist(Header h)
00208         /*@*/
00209 {
00210     const char ** fileNames = NULL;
00211     int count = 0;
00212 
00213     if (!headerIsEntry (h, RPMTAG_BASENAMES)
00214         || !headerIsEntry (h, RPMTAG_DIRNAMES)
00215         || !headerIsEntry (h, RPMTAG_DIRINDEXES))
00216         compressFilelist(h);
00217     
00218     rpmBuildFileList(h, &fileNames, &count);
00219 
00220     if (fileNames == NULL || count <= 0)
00221         return;
00222 
00223     /* XXX Legacy tag needs to go away. */
00224     headerAddEntry(h, RPMTAG_OLDFILENAMES, RPM_STRING_ARRAY_TYPE,
00225                         fileNames, count);
00226 
00227     fileNames = _free(fileNames);
00228 }
00229 
00232 static PyObject * rhnUnload(hdrObject * s, PyObject * args)
00233         /*@*/
00234 {
00235     int len;
00236     char * uh;
00237     PyObject * rc;
00238     Header h;
00239 
00240     if (!PyArg_ParseTuple(args, ""))
00241         return NULL;
00242 
00243     h = headerLink(s->h);
00244 
00245     /* Retrofit a RHNPlatform: tag. */
00246     if (!headerIsEntry(h, RPMTAG_RHNPLATFORM)) {
00247         const char * arch;
00248         int_32 at;
00249         if (headerGetEntry(h, RPMTAG_ARCH, &at, (void **)&arch, NULL))
00250             headerAddEntry(h, RPMTAG_RHNPLATFORM, at, arch, 1);
00251     }
00252 
00253     /* Legacy headers are forced into immutable region. */
00254     if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
00255         Header nh = headerReload(h, RPMTAG_HEADERIMMUTABLE);
00256         /* XXX Another unload/load cycle to "seal" the immutable region. */
00257         uh = headerUnload(nh);
00258         headerFree(nh);
00259         h = headerLoad(uh);
00260         headerAllocated(h);
00261     }
00262 
00263     /* All headers have SHA1 digest, compute and add if necessary. */
00264     if (!headerIsEntry(h, RPMTAG_SHA1HEADER)) {
00265         int_32 uht, uhc;
00266         const char * digest;
00267         size_t digestlen;
00268         DIGEST_CTX ctx;
00269 
00270         headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, (void **)&uh, &uhc);
00271 
00272         ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
00273         rpmDigestUpdate(ctx, uh, uhc);
00274         rpmDigestFinal(ctx, (void **)&digest, &digestlen, 1);
00275 
00276         headerAddEntry(h, RPMTAG_SHA1RHN, RPM_STRING_TYPE, digest, 1);
00277 
00278         uh = headerFreeData(uh, uht);
00279         digest = _free(digest);
00280     }
00281 
00282     len = headerSizeof(h, 0);
00283     uh = headerUnload(h);
00284     headerFree(h);
00285 
00286     rc = PyString_FromStringAndSize(uh, len);
00287     uh = _free(uh);
00288 
00289     return rc;
00290 }
00291 
00294 static PyObject * hdrFullFilelist(hdrObject * s, PyObject * args)
00295         /*@*/
00296 {
00297     if (!PyArg_ParseTuple(args, ""))
00298         return NULL;
00299 
00300     mungeFilelist (s->h);
00301 
00302     Py_INCREF(Py_None);
00303     return Py_None;
00304 }
00305 
00308 static PyObject * hdrSprintf(hdrObject * s, PyObject * args)
00309         /*@*/
00310 {
00311     char * fmt;
00312     char * r;
00313     errmsg_t err;
00314     PyObject * result;
00315 
00316     if (!PyArg_ParseTuple(args, "s", &fmt))
00317         return NULL;
00318 
00319     r = headerSprintf(s->h, fmt, rpmTagTable, rpmHeaderFormats, &err);
00320     if (!r) {
00321         PyErr_SetString(pyrpmError, err);
00322         return NULL;
00323     }
00324 
00325     result = Py_BuildValue("s", r);
00326     r = _free(r);
00327 
00328     return result;
00329 }
00330 
00333 static int hdr_compare(hdrObject * a, hdrObject * b)
00334         /*@*/
00335 {
00336     return rpmVersionCompare(a->h, b->h);
00337 }
00338 
00341 /*@unchecked@*/ /*@observer@*/
00342 static struct PyMethodDef hdr_methods[] = {
00343     {"keys",            (PyCFunction) hdrKeyList,       METH_VARARGS,
00344         NULL },
00345     {"unload",          (PyCFunction) hdrUnload,        METH_VARARGS|METH_KEYWORDS,
00346         NULL },
00347     {"expandFilelist",  (PyCFunction) hdrExpandFilelist,METH_VARARGS,
00348         NULL },
00349     {"compressFilelist",(PyCFunction) hdrCompressFilelist,METH_VARARGS,
00350         NULL },
00351     {"fullFilelist",    (PyCFunction) hdrFullFilelist,  METH_VARARGS,
00352         NULL },
00353     {"rhnUnload",       (PyCFunction) rhnUnload,        METH_VARARGS,
00354         NULL },
00355     {"sprintf",         (PyCFunction) hdrSprintf,       METH_VARARGS,
00356         NULL },
00357 
00358     {"dsOfHeader",      (PyCFunction)hdr_dsOfHeader,    METH_VARARGS,
00359         NULL},
00360     {"dsFromHeader",    (PyCFunction)hdr_dsFromHeader,  METH_VARARGS,
00361         NULL},
00362     {"fiFromHeader",    (PyCFunction)hdr_fiFromHeader,  METH_VARARGS,
00363         NULL},
00364 
00365     {NULL,              NULL}           /* sentinel */
00366 };
00367 
00370 static PyObject * hdr_getattr(hdrObject * s, char * name)
00371         /*@*/
00372 {
00373     return Py_FindMethod(hdr_methods, (PyObject * ) s, name);
00374 }
00375 
00378 static void hdr_dealloc(hdrObject * s)
00379         /*@*/
00380 {
00381     if (s->h) headerFree(s->h);
00382     s->md5list = _free(s->md5list);
00383     s->fileList = _free(s->fileList);
00384     s->linkList = _free(s->linkList);
00385     PyMem_DEL(s);
00386 }
00387 
00390 long tagNumFromPyObject (PyObject *item)
00391 {
00392     char * str;
00393     int i;
00394 
00395     if (PyInt_Check(item)) {
00396         return PyInt_AsLong(item);
00397     } else if (PyString_Check(item)) {
00398         str = PyString_AsString(item);
00399         for (i = 0; i < rpmTagTableSize; i++)
00400             if (!xstrcasecmp(rpmTagTable[i].name + 7, str)) break;
00401         if (i < rpmTagTableSize) return rpmTagTable[i].val;
00402     }
00403     return -1;
00404 }
00405 
00408 static PyObject * hdr_subscript(hdrObject * s, PyObject * item)
00409         /*@*/
00410 {
00411     int type, count, i, tag = -1;
00412     void * data;
00413     PyObject * o, * metao;
00414     char ** stringArray;
00415     int forceArray = 0;
00416     int freeData = 0;
00417     char * str;
00418     struct headerSprintfExtension_s * ext = NULL;
00419     const struct headerSprintfExtension_s * extensions = rpmHeaderFormats;
00420 
00421     if (PyCObject_Check (item))
00422         ext = PyCObject_AsVoidPtr(item);
00423     else
00424         tag = tagNumFromPyObject (item);
00425     if (tag == -1 && PyString_Check(item)) {
00426         /* if we still don't have the tag, go looking for the header
00427            extensions */
00428         str = PyString_AsString(item);
00429         while (extensions->name) {
00430             if (extensions->type == HEADER_EXT_TAG
00431                 && !xstrcasecmp(extensions->name + 7, str)) {
00432                 (const struct headerSprintfExtension *) ext = extensions;
00433             }
00434             extensions++;
00435         }
00436     }
00437 
00438     if (ext) {
00439         ext->u.tagFunction(s->h, &type, (const void **) &data, &count, &freeData);
00440     } else {
00441         if (tag == -1) {
00442             PyErr_SetString(PyExc_KeyError, "unknown header tag");
00443             return NULL;
00444         }
00445         
00446         if (!rpmHeaderGetEntry(s->h, tag, &type, &data, &count)) {
00447             Py_INCREF(Py_None);
00448             return Py_None;
00449         }
00450     }
00451 
00452     switch (tag) {
00453     case RPMTAG_OLDFILENAMES:
00454     case RPMTAG_FILESIZES:
00455     case RPMTAG_FILESTATES:
00456     case RPMTAG_FILEMODES:
00457     case RPMTAG_FILEUIDS:
00458     case RPMTAG_FILEGIDS:
00459     case RPMTAG_FILERDEVS:
00460     case RPMTAG_FILEMTIMES:
00461     case RPMTAG_FILEMD5S:
00462     case RPMTAG_FILELINKTOS:
00463     case RPMTAG_FILEFLAGS:
00464     case RPMTAG_ROOT:
00465     case RPMTAG_FILEUSERNAME:
00466     case RPMTAG_FILEGROUPNAME:
00467         forceArray = 1;
00468         break;
00469     case RPMTAG_SUMMARY:
00470     case RPMTAG_GROUP:
00471     case RPMTAG_DESCRIPTION:
00472         freeData = 1;
00473         break;
00474     default:
00475         break;
00476     }
00477 
00478     switch (type) {
00479     case RPM_BIN_TYPE:
00480         o = PyString_FromStringAndSize(data, count);
00481         break;
00482 
00483     case RPM_INT32_TYPE:
00484         if (count != 1 || forceArray) {
00485             metao = PyList_New(0);
00486             for (i = 0; i < count; i++) {
00487                 o = PyInt_FromLong(((int *) data)[i]);
00488                 PyList_Append(metao, o);
00489                 Py_DECREF(o);
00490             }
00491             o = metao;
00492         } else {
00493             o = PyInt_FromLong(*((int *) data));
00494         }
00495         break;
00496 
00497     case RPM_CHAR_TYPE:
00498     case RPM_INT8_TYPE:
00499         if (count != 1 || forceArray) {
00500             metao = PyList_New(0);
00501             for (i = 0; i < count; i++) {
00502                 o = PyInt_FromLong(((char *) data)[i]);
00503                 PyList_Append(metao, o);
00504                 Py_DECREF(o);
00505             }
00506             o = metao;
00507         } else {
00508             o = PyInt_FromLong(*((char *) data));
00509         }
00510         break;
00511 
00512     case RPM_INT16_TYPE:
00513         if (count != 1 || forceArray) {
00514             metao = PyList_New(0);
00515             for (i = 0; i < count; i++) {
00516                 o = PyInt_FromLong(((short *) data)[i]);
00517                 PyList_Append(metao, o);
00518                 Py_DECREF(o);
00519             }
00520             o = metao;
00521         } else {
00522             o = PyInt_FromLong(*((short *) data));
00523         }
00524         break;
00525 
00526     case RPM_STRING_ARRAY_TYPE:
00527         stringArray = data;
00528 
00529         metao = PyList_New(0);
00530         for (i = 0; i < count; i++) {
00531             o = PyString_FromString(stringArray[i]);
00532             PyList_Append(metao, o);
00533             Py_DECREF(o);
00534         }
00535         free (stringArray);
00536         o = metao;
00537         break;
00538 
00539     case RPM_STRING_TYPE:
00540         if (count != 1 || forceArray) {
00541             stringArray = data;
00542 
00543             metao = PyList_New(0);
00544             for (i=0; i < count; i++) {
00545                 o = PyString_FromString(stringArray[i]);
00546                 PyList_Append(metao, o);
00547                 Py_DECREF(o);
00548             }
00549             o = metao;
00550         } else {
00551             o = PyString_FromString(data);
00552             if (freeData)
00553                 free (data);
00554         }
00555         break;
00556 
00557     default:
00558         PyErr_SetString(PyExc_TypeError, "unsupported type in header");
00559         return NULL;
00560     }
00561 
00562     return o;
00563 }
00564 
00567 /*@unchecked@*/ /*@observer@*/
00568 static PyMappingMethods hdr_as_mapping = {
00569         (inquiry) 0,                    /* mp_length */
00570         (binaryfunc) hdr_subscript,     /* mp_subscript */
00571         (objobjargproc)0,               /* mp_ass_subscript */
00572 };
00573 
00576 static char hdr_doc[] =
00577 "";
00578 
00581 /*@unchecked@*/ /*@observer@*/
00582 PyTypeObject hdr_Type = {
00583         PyObject_HEAD_INIT(NULL)
00584         0,                              /* ob_size */
00585         "rpm.hdr",                      /* tp_name */
00586         sizeof(hdrObject),              /* tp_size */
00587         0,                              /* tp_itemsize */
00588         (destructor) hdr_dealloc,       /* tp_dealloc */
00589         0,                              /* tp_print */
00590         (getattrfunc) hdr_getattr,      /* tp_getattr */
00591         0,                              /* tp_setattr */
00592         (cmpfunc) hdr_compare,          /* tp_compare */
00593         0,                              /* tp_repr */
00594         0,                              /* tp_as_number */
00595         0,                              /* tp_as_sequence */
00596         &hdr_as_mapping,                /* tp_as_mapping */
00597         0,                              /* tp_hash */
00598         0,                              /* tp_call */
00599         0,                              /* tp_str */
00600         0,                              /* tp_getattro */
00601         0,                              /* tp_setattro */
00602         0,                              /* tp_as_buffer */
00603         Py_TPFLAGS_DEFAULT,             /* tp_flags */
00604         hdr_doc,                        /* tp_doc */
00605 #if Py_TPFLAGS_HAVE_ITER
00606         0,                              /* tp_traverse */
00607         0,                              /* tp_clear */
00608         0,                              /* tp_richcompare */
00609         0,                              /* tp_weaklistoffset */
00610         0,                              /* tp_iter */
00611         0,                              /* tp_iternext */
00612         hdr_methods,                    /* tp_methods */
00613         0,                              /* tp_members */
00614         0,                              /* tp_getset */
00615         0,                              /* tp_base */
00616         0,                              /* tp_dict */
00617         0,                              /* tp_descr_get */
00618         0,                              /* tp_descr_set */
00619         0,                              /* tp_dictoffset */
00620         0,                              /* tp_init */
00621         0,                              /* tp_alloc */
00622         0,                              /* tp_new */
00623         0,                              /* tp_free */
00624         0,                              /* tp_is_gc */
00625 #endif
00626 };
00627 
00628 hdrObject * hdr_Wrap(Header h)
00629 {
00630     hdrObject * hdr = PyObject_NEW(hdrObject, &hdr_Type);
00631     hdr->h = headerLink(h);
00632     hdr->fileList = hdr->linkList = hdr->md5list = NULL;
00633     hdr->uids = hdr->gids = hdr->mtimes = hdr->fileSizes = NULL;
00634     hdr->modes = hdr->rdevs = NULL;
00635     return hdr;
00636 }
00637 
00638 Header hdrGetHeader(hdrObject * s)
00639 {
00640     return s->h;
00641 }
00642 
00645 PyObject * hdrLoad(PyObject * self, PyObject * args)
00646 {
00647     hdrObject * hdr;
00648     char * copy = NULL;
00649     char * obj;
00650     Header h;
00651     int len;
00652 
00653     if (!PyArg_ParseTuple(args, "s#", &obj, &len)) return NULL;
00654     
00655     /* malloc is needed to avoid surprises from data swab in headerLoad(). */
00656     copy = malloc(len);
00657     if (copy == NULL) {
00658         PyErr_SetString(pyrpmError, "out of memory");
00659         return NULL;
00660     }
00661     memcpy (copy, obj, len);
00662 
00663     h = headerLoad(copy);
00664     if (!h) {
00665         PyErr_SetString(pyrpmError, "bad header");
00666         return NULL;
00667     }
00668     headerAllocated(h);
00669     compressFilelist (h);
00670     providePackageNVR (h);
00671 
00672     hdr = hdr_Wrap(h);
00673     h = headerFree(h);  /* XXX ref held by hdr */
00674 
00675     return (PyObject *) hdr;
00676 }
00677 
00680 PyObject * rhnLoad(PyObject * self, PyObject * args)
00681 {
00682     char * obj, * copy=NULL;
00683     Header h;
00684     int len;
00685 
00686     if (!PyArg_ParseTuple(args, "s#", &obj, &len)) return NULL;
00687     
00688     /* malloc is needed to avoid surprises from data swab in headerLoad(). */
00689     copy = malloc(len);
00690     if (copy == NULL) {
00691         PyErr_SetString(pyrpmError, "out of memory");
00692         return NULL;
00693     }
00694     memcpy (copy, obj, len);
00695 
00696     h = headerLoad(copy);
00697     if (!h) {
00698         PyErr_SetString(pyrpmError, "bad header");
00699         return NULL;
00700     }
00701     headerAllocated(h);
00702 
00703     /* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
00704     if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
00705         PyErr_SetString(pyrpmError, "bad header, not immutable");
00706         headerFree(h);
00707         return NULL;
00708     }
00709 
00710     /* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
00711     if (!headerIsEntry(h, RPMTAG_SHA1HEADER)
00712     &&  !headerIsEntry(h, RPMTAG_SHA1RHN)) {
00713         PyErr_SetString(pyrpmError, "bad header, no digest");
00714         headerFree(h);
00715         return NULL;
00716     }
00717 
00718     /* Retrofit a RHNPlatform: tag. */
00719     if (!headerIsEntry(h, RPMTAG_RHNPLATFORM)) {
00720         const char * arch;
00721         int_32 at;
00722         if (headerGetEntry(h, RPMTAG_ARCH, &at, (void **)&arch, NULL))
00723             headerAddEntry(h, RPMTAG_RHNPLATFORM, at, arch, 1);
00724     }
00725 
00726     return (PyObject *) hdr_Wrap(h);
00727 }
00728 
00731 PyObject * rpmReadHeaders (FD_t fd)
00732 {
00733     PyObject * list;
00734     Header h;
00735     hdrObject * hdr;
00736 
00737     if (!fd) {
00738         PyErr_SetFromErrno(pyrpmError);
00739         return NULL;
00740     }
00741 
00742     list = PyList_New(0);
00743     Py_BEGIN_ALLOW_THREADS
00744     h = headerRead(fd, HEADER_MAGIC_YES);
00745     Py_END_ALLOW_THREADS
00746 
00747     while (h) {
00748         compressFilelist(h);
00749         providePackageNVR(h);
00750         hdr = hdr_Wrap(h);
00751         if (PyList_Append(list, (PyObject *) hdr)) {
00752             Py_DECREF(list);
00753             Py_DECREF(hdr);
00754             return NULL;
00755         }
00756         Py_DECREF(hdr);
00757 
00758         h = headerFree(h);      /* XXX ref held by hdr */
00759 
00760         Py_BEGIN_ALLOW_THREADS
00761         h = headerRead(fd, HEADER_MAGIC_YES);
00762         Py_END_ALLOW_THREADS
00763     }
00764 
00765     return list;
00766 }
00767 
00770 PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args)
00771 {
00772     FD_t fd;
00773     int fileno;
00774     PyObject * list;
00775 
00776     if (!PyArg_ParseTuple(args, "i", &fileno)) return NULL;
00777     fd = fdDup(fileno);
00778 
00779     list = rpmReadHeaders (fd);
00780     Fclose(fd);
00781 
00782     return list;
00783 }
00784 
00787 PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args)
00788 {
00789     char * filespec;
00790     FD_t fd;
00791     PyObject * list;
00792 
00793     if (!PyArg_ParseTuple(args, "s", &filespec)) return NULL;
00794     fd = Fopen(filespec, "r.fdio");
00795 
00796     if (!fd) {
00797         PyErr_SetFromErrno(pyrpmError);
00798         return NULL;
00799     }
00800 
00801     list = rpmReadHeaders (fd);
00802     Fclose(fd);
00803 
00804     return list;
00805 }
00806 
00811 int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag)
00812 {
00813     Header h;
00814     HeaderIterator hi;
00815     int_32 * newMatch;
00816     int_32 * oldMatch;
00817     hdrObject * hdr;
00818     int count = 0;
00819     int type, c, tag;
00820     void * p;
00821 
00822     Py_BEGIN_ALLOW_THREADS
00823     h = headerRead(fd, HEADER_MAGIC_YES);
00824     Py_END_ALLOW_THREADS
00825 
00826     while (h) {
00827         if (!headerGetEntry(h, matchTag, NULL, (void **) &newMatch, NULL)) {
00828             PyErr_SetString(pyrpmError, "match tag missing in new header");
00829             return 1;
00830         }
00831 
00832         hdr = (hdrObject *) PyList_GetItem(list, count++);
00833         if (!hdr) return 1;
00834 
00835         if (!headerGetEntry(hdr->h, matchTag, NULL, (void **) &oldMatch, NULL)) {
00836             PyErr_SetString(pyrpmError, "match tag missing in new header");
00837             return 1;
00838         }
00839 
00840         if (*newMatch != *oldMatch) {
00841             PyErr_SetString(pyrpmError, "match tag mismatch");
00842             return 1;
00843         }
00844 
00845         hdr->md5list = _free(hdr->md5list);
00846         hdr->fileList = _free(hdr->fileList);
00847         hdr->linkList = _free(hdr->linkList);
00848 
00849         for (hi = headerInitIterator(h);
00850             headerNextIterator(hi, &tag, &type, (void *) &p, &c);
00851             p = headerFreeData(p, type))
00852         {
00853             /* could be dupes */
00854             headerRemoveEntry(hdr->h, tag);
00855             headerAddEntry(hdr->h, tag, type, p, c);
00856         }
00857 
00858         headerFreeIterator(hi);
00859 
00860         Py_BEGIN_ALLOW_THREADS
00861         h = headerRead(fd, HEADER_MAGIC_YES);
00862         Py_END_ALLOW_THREADS
00863     }
00864 
00865     return 0;
00866 }
00867 
00868 PyObject * rpmMergeHeadersFromFD(PyObject * self, PyObject * args)
00869 {
00870     FD_t fd;
00871     int fileno;
00872     PyObject * list;
00873     int rc;
00874     int matchTag;
00875 
00876     if (!PyArg_ParseTuple(args, "Oii", &list, &fileno, &matchTag))
00877         return NULL;
00878 
00879     if (!PyList_Check(list)) {
00880         PyErr_SetString(PyExc_TypeError, "first parameter must be a list");
00881         return NULL;
00882     }
00883 
00884     fd = fdDup(fileno);
00885 
00886     rc = rpmMergeHeaders (list, fd, matchTag);
00887     Fclose(fd);
00888 
00889     if (rc) {
00890         return NULL;
00891     }
00892 
00893     Py_INCREF(Py_None);
00894     return Py_None;
00895 }
00896 
00899 PyObject * versionCompare (PyObject * self, PyObject * args)
00900 {
00901     hdrObject * h1, * h2;
00902 
00903     if (!PyArg_ParseTuple(args, "O!O!", &hdr_Type, &h1, &hdr_Type, &h2))
00904         return NULL;
00905 
00906     return Py_BuildValue("i", hdr_compare(h1, h2));
00907 }
00908 
00911 PyObject * labelCompare (PyObject * self, PyObject * args)
00912 {
00913     char *v1, *r1, *e1, *v2, *r2, *e2;
00914     int rc;
00915 
00916     if (!PyArg_ParseTuple(args, "(zzz)(zzz)",
00917                           &e1, &v1, &r1,
00918                           &e2, &v2, &r2)) return NULL;
00919 
00920     if (e1 && !e2)
00921         return Py_BuildValue("i", 1);
00922     else if (!e1 && e2)
00923         return Py_BuildValue("i", -1);
00924     else if (e1 && e2) {
00925         int ep1, ep2;
00926         ep1 = atoi (e1);
00927         ep2 = atoi (e2);
00928         if (ep1 < ep2)
00929             return Py_BuildValue("i", -1);
00930         else if (ep1 > ep2)
00931             return Py_BuildValue("i", 1);
00932     }
00933 
00934     rc = rpmvercmp(v1, v2);
00935     if (rc)
00936         return Py_BuildValue("i", rc);
00937 
00938     return Py_BuildValue("i", rpmvercmp(r1, r2));
00939 }
00940 

Generated on Wed Sep 4 12:49:54 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002