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     rpmfiBuildFNames(h, RPMTAG_BASENAMES, &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 
00339 static long hdr_hash(PyObject * h)
00340 {
00341     return (long) h;
00342 }
00343 
00346 /*@unchecked@*/ /*@observer@*/
00347 static struct PyMethodDef hdr_methods[] = {
00348     {"keys",            (PyCFunction) hdrKeyList,       METH_VARARGS,
00349         NULL },
00350     {"unload",          (PyCFunction) hdrUnload,        METH_VARARGS|METH_KEYWORDS,
00351         NULL },
00352     {"expandFilelist",  (PyCFunction) hdrExpandFilelist,METH_VARARGS,
00353         NULL },
00354     {"compressFilelist",(PyCFunction) hdrCompressFilelist,METH_VARARGS,
00355         NULL },
00356     {"fullFilelist",    (PyCFunction) hdrFullFilelist,  METH_VARARGS,
00357         NULL },
00358     {"rhnUnload",       (PyCFunction) rhnUnload,        METH_VARARGS,
00359         NULL },
00360     {"sprintf",         (PyCFunction) hdrSprintf,       METH_VARARGS,
00361         NULL },
00362 
00363     {"dsOfHeader",      (PyCFunction)hdr_dsOfHeader,    METH_VARARGS,
00364         NULL},
00365     {"dsFromHeader",    (PyCFunction)hdr_dsFromHeader,  METH_VARARGS,
00366         NULL},
00367     {"fiFromHeader",    (PyCFunction)hdr_fiFromHeader,  METH_VARARGS,
00368         NULL},
00369 
00370     {NULL,              NULL}           /* sentinel */
00371 };
00372 
00375 static PyObject * hdr_getattr(hdrObject * s, char * name)
00376         /*@*/
00377 {
00378     return Py_FindMethod(hdr_methods, (PyObject * ) s, name);
00379 }
00380 
00383 static void hdr_dealloc(hdrObject * s)
00384         /*@*/
00385 {
00386     if (s->h) headerFree(s->h);
00387     s->md5list = _free(s->md5list);
00388     s->fileList = _free(s->fileList);
00389     s->linkList = _free(s->linkList);
00390     PyObject_Del(s);
00391 }
00392 
00395 long tagNumFromPyObject (PyObject *item)
00396 {
00397     char * str;
00398     int i;
00399 
00400     if (PyInt_Check(item)) {
00401         return PyInt_AsLong(item);
00402     } else if (PyString_Check(item)) {
00403         str = PyString_AsString(item);
00404         for (i = 0; i < rpmTagTableSize; i++)
00405             if (!xstrcasecmp(rpmTagTable[i].name + 7, str)) break;
00406         if (i < rpmTagTableSize) return rpmTagTable[i].val;
00407     }
00408     return -1;
00409 }
00410 
00413 static PyObject * hdr_subscript(hdrObject * s, PyObject * item)
00414         /*@*/
00415 {
00416     int type, count, i, tag = -1;
00417     void * data;
00418     PyObject * o, * metao;
00419     char ** stringArray;
00420     int forceArray = 0;
00421     int freeData = 0;
00422     char * str;
00423     struct headerSprintfExtension_s * ext = NULL;
00424     const struct headerSprintfExtension_s * extensions = rpmHeaderFormats;
00425 
00426     if (PyCObject_Check (item))
00427         ext = PyCObject_AsVoidPtr(item);
00428     else
00429         tag = tagNumFromPyObject (item);
00430     if (tag == -1 && PyString_Check(item)) {
00431         /* if we still don't have the tag, go looking for the header
00432            extensions */
00433         str = PyString_AsString(item);
00434         while (extensions->name) {
00435             if (extensions->type == HEADER_EXT_TAG
00436                 && !xstrcasecmp(extensions->name + 7, str)) {
00437                 (const struct headerSprintfExtension *) ext = extensions;
00438             }
00439             extensions++;
00440         }
00441     }
00442 
00443     if (ext) {
00444         ext->u.tagFunction(s->h, &type, (const void **) &data, &count, &freeData);
00445     } else {
00446         if (tag == -1) {
00447             PyErr_SetString(PyExc_KeyError, "unknown header tag");
00448             return NULL;
00449         }
00450 
00451         if (!rpmHeaderGetEntry(s->h, tag, &type, &data, &count)) {
00452             Py_INCREF(Py_None);
00453             return Py_None;
00454         }
00455     }
00456 
00457     switch (tag) {
00458     case RPMTAG_OLDFILENAMES:
00459     case RPMTAG_FILESIZES:
00460     case RPMTAG_FILESTATES:
00461     case RPMTAG_FILEMODES:
00462     case RPMTAG_FILEUIDS:
00463     case RPMTAG_FILEGIDS:
00464     case RPMTAG_FILERDEVS:
00465     case RPMTAG_FILEMTIMES:
00466     case RPMTAG_FILEMD5S:
00467     case RPMTAG_FILELINKTOS:
00468     case RPMTAG_FILEFLAGS:
00469     case RPMTAG_ROOT:
00470     case RPMTAG_FILEUSERNAME:
00471     case RPMTAG_FILEGROUPNAME:
00472         forceArray = 1;
00473         break;
00474     case RPMTAG_SUMMARY:
00475     case RPMTAG_GROUP:
00476     case RPMTAG_DESCRIPTION:
00477         freeData = 1;
00478         break;
00479     default:
00480         break;
00481     }
00482 
00483     switch (type) {
00484     case RPM_BIN_TYPE:
00485         o = PyString_FromStringAndSize(data, count);
00486         break;
00487 
00488     case RPM_INT32_TYPE:
00489         if (count != 1 || forceArray) {
00490             metao = PyList_New(0);
00491             for (i = 0; i < count; i++) {
00492                 o = PyInt_FromLong(((int *) data)[i]);
00493                 PyList_Append(metao, o);
00494                 Py_DECREF(o);
00495             }
00496             o = metao;
00497         } else {
00498             o = PyInt_FromLong(*((int *) data));
00499         }
00500         break;
00501 
00502     case RPM_CHAR_TYPE:
00503     case RPM_INT8_TYPE:
00504         if (count != 1 || forceArray) {
00505             metao = PyList_New(0);
00506             for (i = 0; i < count; i++) {
00507                 o = PyInt_FromLong(((char *) data)[i]);
00508                 PyList_Append(metao, o);
00509                 Py_DECREF(o);
00510             }
00511             o = metao;
00512         } else {
00513             o = PyInt_FromLong(*((char *) data));
00514         }
00515         break;
00516 
00517     case RPM_INT16_TYPE:
00518         if (count != 1 || forceArray) {
00519             metao = PyList_New(0);
00520             for (i = 0; i < count; i++) {
00521                 o = PyInt_FromLong(((short *) data)[i]);
00522                 PyList_Append(metao, o);
00523                 Py_DECREF(o);
00524             }
00525             o = metao;
00526         } else {
00527             o = PyInt_FromLong(*((short *) data));
00528         }
00529         break;
00530 
00531     case RPM_STRING_ARRAY_TYPE:
00532         stringArray = data;
00533 
00534         metao = PyList_New(0);
00535         for (i = 0; i < count; i++) {
00536             o = PyString_FromString(stringArray[i]);
00537             PyList_Append(metao, o);
00538             Py_DECREF(o);
00539         }
00540         free (stringArray);
00541         o = metao;
00542         break;
00543 
00544     case RPM_STRING_TYPE:
00545         if (count != 1 || forceArray) {
00546             stringArray = data;
00547 
00548             metao = PyList_New(0);
00549             for (i=0; i < count; i++) {
00550                 o = PyString_FromString(stringArray[i]);
00551                 PyList_Append(metao, o);
00552                 Py_DECREF(o);
00553             }
00554             o = metao;
00555         } else {
00556             o = PyString_FromString(data);
00557             if (freeData)
00558                 free (data);
00559         }
00560         break;
00561 
00562     default:
00563         PyErr_SetString(PyExc_TypeError, "unsupported type in header");
00564         return NULL;
00565     }
00566 
00567     return o;
00568 }
00569 
00572 /*@unchecked@*/ /*@observer@*/
00573 static PyMappingMethods hdr_as_mapping = {
00574         (inquiry) 0,                    /* mp_length */
00575         (binaryfunc) hdr_subscript,     /* mp_subscript */
00576         (objobjargproc)0,               /* mp_ass_subscript */
00577 };
00578 
00581 static char hdr_doc[] =
00582 "";
00583 
00586 /*@unchecked@*/ /*@observer@*/
00587 PyTypeObject hdr_Type = {
00588         PyObject_HEAD_INIT(&PyType_Type)
00589         0,                              /* ob_size */
00590         "rpm.hdr",                      /* tp_name */
00591         sizeof(hdrObject),              /* tp_size */
00592         0,                              /* tp_itemsize */
00593         (destructor) hdr_dealloc,       /* tp_dealloc */
00594         0,                              /* tp_print */
00595         (getattrfunc) hdr_getattr,      /* tp_getattr */
00596         0,                              /* tp_setattr */
00597         (cmpfunc) hdr_compare,          /* tp_compare */
00598         0,                              /* tp_repr */
00599         0,                              /* tp_as_number */
00600         0,                              /* tp_as_sequence */
00601         &hdr_as_mapping,                /* tp_as_mapping */
00602         hdr_hash,                       /* tp_hash */
00603         0,                              /* tp_call */
00604         0,                              /* tp_str */
00605         0,                              /* tp_getattro */
00606         0,                              /* tp_setattro */
00607         0,                              /* tp_as_buffer */
00608         Py_TPFLAGS_DEFAULT,             /* tp_flags */
00609         hdr_doc,                        /* tp_doc */
00610 #if Py_TPFLAGS_HAVE_ITER
00611         0,                              /* tp_traverse */
00612         0,                              /* tp_clear */
00613         0,                              /* tp_richcompare */
00614         0,                              /* tp_weaklistoffset */
00615         0,                              /* tp_iter */
00616         0,                              /* tp_iternext */
00617         hdr_methods,                    /* tp_methods */
00618         0,                              /* tp_members */
00619         0,                              /* tp_getset */
00620         0,                              /* tp_base */
00621         0,                              /* tp_dict */
00622         0,                              /* tp_descr_get */
00623         0,                              /* tp_descr_set */
00624         0,                              /* tp_dictoffset */
00625         0,                              /* tp_init */
00626         0,                              /* tp_alloc */
00627         0,                              /* tp_new */
00628         0,                              /* tp_free */
00629         0,                              /* tp_is_gc */
00630 #endif
00631 };
00632 
00633 hdrObject * hdr_Wrap(Header h)
00634 {
00635     hdrObject * hdr = PyObject_New(hdrObject, &hdr_Type);
00636     hdr->h = headerLink(h);
00637     hdr->fileList = hdr->linkList = hdr->md5list = NULL;
00638     hdr->uids = hdr->gids = hdr->mtimes = hdr->fileSizes = NULL;
00639     hdr->modes = hdr->rdevs = NULL;
00640     return hdr;
00641 }
00642 
00643 Header hdrGetHeader(hdrObject * s)
00644 {
00645     return s->h;
00646 }
00647 
00650 PyObject * hdrLoad(PyObject * self, PyObject * args)
00651 {
00652     hdrObject * hdr;
00653     char * copy = NULL;
00654     char * obj;
00655     Header h;
00656     int len;
00657 
00658     if (!PyArg_ParseTuple(args, "s#", &obj, &len)) return NULL;
00659 
00660     /* malloc is needed to avoid surprises from data swab in headerLoad(). */
00661     copy = malloc(len);
00662     if (copy == NULL) {
00663         PyErr_SetString(pyrpmError, "out of memory");
00664         return NULL;
00665     }
00666     memcpy (copy, obj, len);
00667 
00668     h = headerLoad(copy);
00669     if (!h) {
00670         PyErr_SetString(pyrpmError, "bad header");
00671         return NULL;
00672     }
00673     headerAllocated(h);
00674     compressFilelist (h);
00675     providePackageNVR (h);
00676 
00677     hdr = hdr_Wrap(h);
00678     h = headerFree(h);  /* XXX ref held by hdr */
00679 
00680     return (PyObject *) hdr;
00681 }
00682 
00685 PyObject * rhnLoad(PyObject * self, PyObject * args)
00686 {
00687     char * obj, * copy=NULL;
00688     Header h;
00689     int len;
00690 
00691     if (!PyArg_ParseTuple(args, "s#", &obj, &len)) return NULL;
00692 
00693     /* malloc is needed to avoid surprises from data swab in headerLoad(). */
00694     copy = malloc(len);
00695     if (copy == NULL) {
00696         PyErr_SetString(pyrpmError, "out of memory");
00697         return NULL;
00698     }
00699     memcpy (copy, obj, len);
00700 
00701     h = headerLoad(copy);
00702     if (!h) {
00703         PyErr_SetString(pyrpmError, "bad header");
00704         return NULL;
00705     }
00706     headerAllocated(h);
00707 
00708     /* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
00709     if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
00710         PyErr_SetString(pyrpmError, "bad header, not immutable");
00711         headerFree(h);
00712         return NULL;
00713     }
00714 
00715     /* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
00716     if (!headerIsEntry(h, RPMTAG_SHA1HEADER)
00717     &&  !headerIsEntry(h, RPMTAG_SHA1RHN)) {
00718         PyErr_SetString(pyrpmError, "bad header, no digest");
00719         headerFree(h);
00720         return NULL;
00721     }
00722 
00723     /* Retrofit a RHNPlatform: tag. */
00724     if (!headerIsEntry(h, RPMTAG_RHNPLATFORM)) {
00725         const char * arch;
00726         int_32 at;
00727         if (headerGetEntry(h, RPMTAG_ARCH, &at, (void **)&arch, NULL))
00728             headerAddEntry(h, RPMTAG_RHNPLATFORM, at, arch, 1);
00729     }
00730 
00731     return (PyObject *) hdr_Wrap(h);
00732 }
00733 
00736 PyObject * rpmReadHeaders (FD_t fd)
00737 {
00738     PyObject * list;
00739     Header h;
00740     hdrObject * hdr;
00741 
00742     if (!fd) {
00743         PyErr_SetFromErrno(pyrpmError);
00744         return NULL;
00745     }
00746 
00747     list = PyList_New(0);
00748     Py_BEGIN_ALLOW_THREADS
00749     h = headerRead(fd, HEADER_MAGIC_YES);
00750     Py_END_ALLOW_THREADS
00751 
00752     while (h) {
00753         compressFilelist(h);
00754         providePackageNVR(h);
00755         hdr = hdr_Wrap(h);
00756         if (PyList_Append(list, (PyObject *) hdr)) {
00757             Py_DECREF(list);
00758             Py_DECREF(hdr);
00759             return NULL;
00760         }
00761         Py_DECREF(hdr);
00762 
00763         h = headerFree(h);      /* XXX ref held by hdr */
00764 
00765         Py_BEGIN_ALLOW_THREADS
00766         h = headerRead(fd, HEADER_MAGIC_YES);
00767         Py_END_ALLOW_THREADS
00768     }
00769 
00770     return list;
00771 }
00772 
00775 PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args)
00776 {
00777     FD_t fd;
00778     int fileno;
00779     PyObject * list;
00780 
00781     if (!PyArg_ParseTuple(args, "i", &fileno)) return NULL;
00782     fd = fdDup(fileno);
00783 
00784     list = rpmReadHeaders (fd);
00785     Fclose(fd);
00786 
00787     return list;
00788 }
00789 
00792 PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args)
00793 {
00794     char * filespec;
00795     FD_t fd;
00796     PyObject * list;
00797 
00798     if (!PyArg_ParseTuple(args, "s", &filespec)) return NULL;
00799     fd = Fopen(filespec, "r.fdio");
00800 
00801     if (!fd) {
00802         PyErr_SetFromErrno(pyrpmError);
00803         return NULL;
00804     }
00805 
00806     list = rpmReadHeaders (fd);
00807     Fclose(fd);
00808 
00809     return list;
00810 }
00811 
00816 int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag)
00817 {
00818     Header h;
00819     HeaderIterator hi;
00820     int_32 * newMatch;
00821     int_32 * oldMatch;
00822     hdrObject * hdr;
00823     int count = 0;
00824     int type, c, tag;
00825     void * p;
00826 
00827     Py_BEGIN_ALLOW_THREADS
00828     h = headerRead(fd, HEADER_MAGIC_YES);
00829     Py_END_ALLOW_THREADS
00830 
00831     while (h) {
00832         if (!headerGetEntry(h, matchTag, NULL, (void **) &newMatch, NULL)) {
00833             PyErr_SetString(pyrpmError, "match tag missing in new header");
00834             return 1;
00835         }
00836 
00837         hdr = (hdrObject *) PyList_GetItem(list, count++);
00838         if (!hdr) return 1;
00839 
00840         if (!headerGetEntry(hdr->h, matchTag, NULL, (void **) &oldMatch, NULL)) {
00841             PyErr_SetString(pyrpmError, "match tag missing in new header");
00842             return 1;
00843         }
00844 
00845         if (*newMatch != *oldMatch) {
00846             PyErr_SetString(pyrpmError, "match tag mismatch");
00847             return 1;
00848         }
00849 
00850         hdr->md5list = _free(hdr->md5list);
00851         hdr->fileList = _free(hdr->fileList);
00852         hdr->linkList = _free(hdr->linkList);
00853 
00854         for (hi = headerInitIterator(h);
00855             headerNextIterator(hi, &tag, &type, (void *) &p, &c);
00856             p = headerFreeData(p, type))
00857         {
00858             /* could be dupes */
00859             headerRemoveEntry(hdr->h, tag);
00860             headerAddEntry(hdr->h, tag, type, p, c);
00861         }
00862 
00863         headerFreeIterator(hi);
00864         h = headerFree(h);
00865 
00866         Py_BEGIN_ALLOW_THREADS
00867         h = headerRead(fd, HEADER_MAGIC_YES);
00868         Py_END_ALLOW_THREADS
00869     }
00870 
00871     return 0;
00872 }
00873 
00874 PyObject * rpmMergeHeadersFromFD(PyObject * self, PyObject * args)
00875 {
00876     FD_t fd;
00877     int fileno;
00878     PyObject * list;
00879     int rc;
00880     int matchTag;
00881 
00882     if (!PyArg_ParseTuple(args, "Oii", &list, &fileno, &matchTag))
00883         return NULL;
00884 
00885     if (!PyList_Check(list)) {
00886         PyErr_SetString(PyExc_TypeError, "first parameter must be a list");
00887         return NULL;
00888     }
00889 
00890     fd = fdDup(fileno);
00891 
00892     rc = rpmMergeHeaders (list, fd, matchTag);
00893     Fclose(fd);
00894 
00895     if (rc) {
00896         return NULL;
00897     }
00898 
00899     Py_INCREF(Py_None);
00900     return Py_None;
00901 }
00902 
00905 PyObject * versionCompare (PyObject * self, PyObject * args)
00906 {
00907     hdrObject * h1, * h2;
00908 
00909     if (!PyArg_ParseTuple(args, "O!O!", &hdr_Type, &h1, &hdr_Type, &h2))
00910         return NULL;
00911 
00912     return Py_BuildValue("i", hdr_compare(h1, h2));
00913 }
00914 
00917 PyObject * labelCompare (PyObject * self, PyObject * args)
00918 {
00919     char *v1, *r1, *e1, *v2, *r2, *e2;
00920     int rc;
00921 
00922     if (!PyArg_ParseTuple(args, "(zzz)(zzz)",
00923                           &e1, &v1, &r1,
00924                           &e2, &v2, &r2)) return NULL;
00925 
00926     if (e1 && !e2)
00927         return Py_BuildValue("i", 1);
00928     else if (!e1 && e2)
00929         return Py_BuildValue("i", -1);
00930     else if (e1 && e2) {
00931         int ep1, ep2;
00932         ep1 = atoi (e1);
00933         ep2 = atoi (e2);
00934         if (ep1 < ep2)
00935             return Py_BuildValue("i", -1);
00936         else if (ep1 > ep2)
00937             return Py_BuildValue("i", 1);
00938     }
00939 
00940     rc = rpmvercmp(v1, v2);
00941     if (rc)
00942         return Py_BuildValue("i", rc);
00943 
00944     return Py_BuildValue("i", rpmvercmp(r1, r2));
00945 }
00946 

Generated on Sun Oct 26 13:02:02 2003 for rpm by doxygen1.2.18