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 
00141 
00144 struct hdrObject_s {
00145     PyObject_HEAD
00146     Header h;
00147     char ** md5list;
00148     char ** fileList;
00149     char ** linkList;
00150     int_32 * fileSizes;
00151     int_32 * mtimes;
00152     int_32 * uids, * gids;      /* XXX these tags are not used anymore */
00153     unsigned short * rdevs;
00154     unsigned short * modes;
00155 } ;
00156 
00157 /*@unused@*/ static inline Header headerAllocated(Header h)
00158         /*@modifies h @*/
00159 {
00160     h->flags |= HEADERFLAG_ALLOCATED;
00161     return 0;
00162 }
00163 
00166 static PyObject * hdrKeyList(hdrObject * s, PyObject * args)
00167         /*@*/
00168 {
00169     PyObject * list, *o;
00170     HeaderIterator hi;
00171     int tag, type;
00172 
00173     if (!PyArg_ParseTuple(args, "")) return NULL;
00174 
00175     list = PyList_New(0);
00176 
00177     hi = headerInitIterator(s->h);
00178     while (headerNextIterator(hi, &tag, &type, NULL, NULL)) {
00179         if (tag == HEADER_I18NTABLE) continue;
00180 
00181         switch (type) {
00182         case RPM_BIN_TYPE:
00183         case RPM_INT32_TYPE:
00184         case RPM_CHAR_TYPE:
00185         case RPM_INT8_TYPE:
00186         case RPM_INT16_TYPE:
00187         case RPM_STRING_ARRAY_TYPE:
00188         case RPM_STRING_TYPE:
00189             PyList_Append(list, o=PyInt_FromLong(tag));
00190             Py_DECREF(o);
00191         }
00192     }
00193     headerFreeIterator(hi);
00194 
00195     return list;
00196 }
00197 
00200 static PyObject * hdrUnload(hdrObject * s, PyObject * args, PyObject *keywords)
00201         /*@*/
00202 {
00203     char * buf;
00204     PyObject * rc;
00205     int len, legacy = 0;
00206     Header h;
00207     static char *kwlist[] = { "legacyHeader", NULL};
00208 
00209     if (!PyArg_ParseTupleAndKeywords(args, keywords, "|i", kwlist, &legacy))
00210         return NULL;
00211 
00212     h = headerLink(s->h);
00213     /* XXX this legacy switch is a hack, needs to be removed. */
00214     if (legacy) {
00215         h = headerCopy(s->h);   /* XXX strip region tags, etc */
00216         headerFree(s->h);
00217     }
00218     len = headerSizeof(h, 0);
00219     buf = headerUnload(h);
00220     h = headerFree(h);
00221 
00222     if (buf == NULL || len == 0) {
00223         PyErr_SetString(pyrpmError, "can't unload bad header\n");
00224         return NULL;
00225     }
00226 
00227     rc = PyString_FromStringAndSize(buf, len);
00228     buf = _free(buf);
00229 
00230     return rc;
00231 }
00232 
00235 static PyObject * hdrExpandFilelist(hdrObject * s, PyObject * args)
00236         /*@*/
00237 {
00238     expandFilelist (s->h);
00239 
00240     Py_INCREF(Py_None);
00241     return Py_None;
00242 }
00243 
00246 static PyObject * hdrCompressFilelist(hdrObject * s, PyObject * args)
00247         /*@*/
00248 {
00249     compressFilelist (s->h);
00250 
00251     Py_INCREF(Py_None);
00252     return Py_None;
00253 }
00254 
00255 /* make a header with _all_ the tags we need */
00258 static void mungeFilelist(Header h)
00259         /*@*/
00260 {
00261     const char ** fileNames = NULL;
00262     int count = 0;
00263 
00264     if (!headerIsEntry (h, RPMTAG_BASENAMES)
00265         || !headerIsEntry (h, RPMTAG_DIRNAMES)
00266         || !headerIsEntry (h, RPMTAG_DIRINDEXES))
00267         compressFilelist(h);
00268 
00269     rpmfiBuildFNames(h, RPMTAG_BASENAMES, &fileNames, &count);
00270 
00271     if (fileNames == NULL || count <= 0)
00272         return;
00273 
00274     /* XXX Legacy tag needs to go away. */
00275     headerAddEntry(h, RPMTAG_OLDFILENAMES, RPM_STRING_ARRAY_TYPE,
00276                         fileNames, count);
00277 
00278     fileNames = _free(fileNames);
00279 }
00280 
00283 static PyObject * rhnUnload(hdrObject * s, PyObject * args)
00284         /*@*/
00285 {
00286     int len;
00287     char * uh;
00288     PyObject * rc;
00289     Header h;
00290 
00291     if (!PyArg_ParseTuple(args, ""))
00292         return NULL;
00293 
00294     h = headerLink(s->h);
00295 
00296     /* Retrofit a RHNPlatform: tag. */
00297     if (!headerIsEntry(h, RPMTAG_RHNPLATFORM)) {
00298         const char * arch;
00299         int_32 at;
00300         if (headerGetEntry(h, RPMTAG_ARCH, &at, (void **)&arch, NULL))
00301             headerAddEntry(h, RPMTAG_RHNPLATFORM, at, arch, 1);
00302     }
00303 
00304     /* Legacy headers are forced into immutable region. */
00305     if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
00306         Header nh = headerReload(h, RPMTAG_HEADERIMMUTABLE);
00307         /* XXX Another unload/load cycle to "seal" the immutable region. */
00308         uh = headerUnload(nh);
00309         headerFree(nh);
00310         h = headerLoad(uh);
00311         headerAllocated(h);
00312     }
00313 
00314     /* All headers have SHA1 digest, compute and add if necessary. */
00315     if (!headerIsEntry(h, RPMTAG_SHA1HEADER)) {
00316         int_32 uht, uhc;
00317         const char * digest;
00318         size_t digestlen;
00319         DIGEST_CTX ctx;
00320 
00321         headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, (void **)&uh, &uhc);
00322 
00323         ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
00324         rpmDigestUpdate(ctx, uh, uhc);
00325         rpmDigestFinal(ctx, (void **)&digest, &digestlen, 1);
00326 
00327         headerAddEntry(h, RPMTAG_SHA1RHN, RPM_STRING_TYPE, digest, 1);
00328 
00329         uh = headerFreeData(uh, uht);
00330         digest = _free(digest);
00331     }
00332 
00333     len = headerSizeof(h, 0);
00334     uh = headerUnload(h);
00335     headerFree(h);
00336 
00337     rc = PyString_FromStringAndSize(uh, len);
00338     uh = _free(uh);
00339 
00340     return rc;
00341 }
00342 
00345 static PyObject * hdrFullFilelist(hdrObject * s, PyObject * args)
00346         /*@*/
00347 {
00348     if (!PyArg_ParseTuple(args, ""))
00349         return NULL;
00350 
00351     mungeFilelist (s->h);
00352 
00353     Py_INCREF(Py_None);
00354     return Py_None;
00355 }
00356 
00359 static PyObject * hdrSprintf(hdrObject * s, PyObject * args)
00360         /*@*/
00361 {
00362     char * fmt;
00363     char * r;
00364     errmsg_t err;
00365     PyObject * result;
00366 
00367     if (!PyArg_ParseTuple(args, "s", &fmt))
00368         return NULL;
00369 
00370     r = headerSprintf(s->h, fmt, rpmTagTable, rpmHeaderFormats, &err);
00371     if (!r) {
00372         PyErr_SetString(pyrpmError, err);
00373         return NULL;
00374     }
00375 
00376     result = Py_BuildValue("s", r);
00377     r = _free(r);
00378 
00379     return result;
00380 }
00381 
00384 static int hdr_compare(hdrObject * a, hdrObject * b)
00385         /*@*/
00386 {
00387     return rpmVersionCompare(a->h, b->h);
00388 }
00389 
00390 static long hdr_hash(PyObject * h)
00391 {
00392     return (long) h;
00393 }
00394 
00397 /*@unchecked@*/ /*@observer@*/
00398 static struct PyMethodDef hdr_methods[] = {
00399     {"keys",            (PyCFunction) hdrKeyList,       METH_VARARGS,
00400         NULL },
00401     {"unload",          (PyCFunction) hdrUnload,        METH_VARARGS|METH_KEYWORDS,
00402         NULL },
00403     {"expandFilelist",  (PyCFunction) hdrExpandFilelist,METH_VARARGS,
00404         NULL },
00405     {"compressFilelist",(PyCFunction) hdrCompressFilelist,METH_VARARGS,
00406         NULL },
00407     {"fullFilelist",    (PyCFunction) hdrFullFilelist,  METH_VARARGS,
00408         NULL },
00409     {"rhnUnload",       (PyCFunction) rhnUnload,        METH_VARARGS,
00410         NULL },
00411     {"sprintf",         (PyCFunction) hdrSprintf,       METH_VARARGS,
00412         NULL },
00413 
00414     {"dsOfHeader",      (PyCFunction)hdr_dsOfHeader,    METH_VARARGS,
00415         NULL},
00416     {"dsFromHeader",    (PyCFunction)hdr_dsFromHeader,  METH_VARARGS,
00417         NULL},
00418     {"fiFromHeader",    (PyCFunction)hdr_fiFromHeader,  METH_VARARGS,
00419         NULL},
00420 
00421     {NULL,              NULL}           /* sentinel */
00422 };
00423 
00426 static PyObject * hdr_getattr(hdrObject * s, char * name)
00427         /*@*/
00428 {
00429     return Py_FindMethod(hdr_methods, (PyObject * ) s, name);
00430 }
00431 
00434 static void hdr_dealloc(hdrObject * s)
00435         /*@*/
00436 {
00437     if (s->h) headerFree(s->h);
00438     s->md5list = _free(s->md5list);
00439     s->fileList = _free(s->fileList);
00440     s->linkList = _free(s->linkList);
00441     PyObject_Del(s);
00442 }
00443 
00446 long tagNumFromPyObject (PyObject *item)
00447 {
00448     char * str;
00449     int i;
00450 
00451     if (PyInt_Check(item)) {
00452         return PyInt_AsLong(item);
00453     } else if (PyString_Check(item)) {
00454         str = PyString_AsString(item);
00455         for (i = 0; i < rpmTagTableSize; i++)
00456             if (!xstrcasecmp(rpmTagTable[i].name + 7, str)) break;
00457         if (i < rpmTagTableSize) return rpmTagTable[i].val;
00458     }
00459     return -1;
00460 }
00461 
00464 static PyObject * hdr_subscript(hdrObject * s, PyObject * item)
00465         /*@*/
00466 {
00467     int type, count, i, tag = -1;
00468     void * data;
00469     PyObject * o, * metao;
00470     char ** stringArray;
00471     int forceArray = 0;
00472     int freeData = 0;
00473     char * str;
00474     struct headerSprintfExtension_s * ext = NULL;
00475     const struct headerSprintfExtension_s * extensions = rpmHeaderFormats;
00476 
00477     if (PyCObject_Check (item))
00478         ext = PyCObject_AsVoidPtr(item);
00479     else
00480         tag = tagNumFromPyObject (item);
00481     if (tag == -1 && PyString_Check(item)) {
00482         /* if we still don't have the tag, go looking for the header
00483            extensions */
00484         str = PyString_AsString(item);
00485         while (extensions->name) {
00486             if (extensions->type == HEADER_EXT_TAG
00487                 && !xstrcasecmp(extensions->name + 7, str)) {
00488                 (const struct headerSprintfExtension *) ext = extensions;
00489             }
00490             extensions++;
00491         }
00492     }
00493 
00494     /* Retrieve data from extension or header. */
00495     if (ext) {
00496         ext->u.tagFunction(s->h, &type, (const void **) &data, &count, &freeData);
00497     } else {
00498         if (tag == -1) {
00499             PyErr_SetString(PyExc_KeyError, "unknown header tag");
00500             return NULL;
00501         }
00502         
00503         if (!rpmHeaderGetEntry(s->h, tag, &type, &data, &count)) {
00504             switch (tag) {
00505             case RPMTAG_EPOCH:
00506             case RPMTAG_NAME:
00507             case RPMTAG_VERSION:
00508             case RPMTAG_RELEASE:
00509             case RPMTAG_ARCH:
00510             case RPMTAG_OS:
00511                 Py_INCREF(Py_None);
00512                 return Py_None;
00513                 break;
00514             default:
00515                 return PyList_New(0);
00516                 break;
00517             }
00518         }
00519     }
00520 
00521     switch (tag) {
00522     case RPMTAG_OLDFILENAMES:
00523     case RPMTAG_FILESIZES:
00524     case RPMTAG_FILESTATES:
00525     case RPMTAG_FILEMODES:
00526     case RPMTAG_FILEUIDS:
00527     case RPMTAG_FILEGIDS:
00528     case RPMTAG_FILERDEVS:
00529     case RPMTAG_FILEMTIMES:
00530     case RPMTAG_FILEMD5S:
00531     case RPMTAG_FILELINKTOS:
00532     case RPMTAG_FILEFLAGS:
00533     case RPMTAG_ROOT:
00534     case RPMTAG_FILEUSERNAME:
00535     case RPMTAG_FILEGROUPNAME:
00536     case RPMTAG_REQUIRENAME:
00537     case RPMTAG_REQUIREFLAGS:
00538     case RPMTAG_REQUIREVERSION:
00539     case RPMTAG_PROVIDENAME:
00540     case RPMTAG_PROVIDEFLAGS:
00541     case RPMTAG_PROVIDEVERSION:
00542     case RPMTAG_OBSOLETENAME:
00543     case RPMTAG_OBSOLETEFLAGS:
00544     case RPMTAG_OBSOLETEVERSION:
00545     case RPMTAG_CONFLICTNAME:
00546     case RPMTAG_CONFLICTFLAGS:
00547     case RPMTAG_CONFLICTVERSION:
00548         forceArray = 1;
00549         break;
00550     case RPMTAG_SUMMARY:
00551     case RPMTAG_GROUP:
00552     case RPMTAG_DESCRIPTION:
00553         freeData = 1;
00554         break;
00555     default:
00556         break;
00557     }
00558 
00559     switch (type) {
00560     case RPM_BIN_TYPE:
00561         o = PyString_FromStringAndSize(data, count);
00562         break;
00563 
00564     case RPM_INT32_TYPE:
00565         if (count != 1 || forceArray) {
00566             metao = PyList_New(0);
00567             for (i = 0; i < count; i++) {
00568                 o = PyInt_FromLong(((int *) data)[i]);
00569                 PyList_Append(metao, o);
00570                 Py_DECREF(o);
00571             }
00572             o = metao;
00573         } else {
00574             o = PyInt_FromLong(*((int *) data));
00575         }
00576         break;
00577 
00578     case RPM_CHAR_TYPE:
00579     case RPM_INT8_TYPE:
00580         if (count != 1 || forceArray) {
00581             metao = PyList_New(0);
00582             for (i = 0; i < count; i++) {
00583                 o = PyInt_FromLong(((char *) data)[i]);
00584                 PyList_Append(metao, o);
00585                 Py_DECREF(o);
00586             }
00587             o = metao;
00588         } else {
00589             o = PyInt_FromLong(*((char *) data));
00590         }
00591         break;
00592 
00593     case RPM_INT16_TYPE:
00594         if (count != 1 || forceArray) {
00595             metao = PyList_New(0);
00596             for (i = 0; i < count; i++) {
00597                 o = PyInt_FromLong(((short *) data)[i]);
00598                 PyList_Append(metao, o);
00599                 Py_DECREF(o);
00600             }
00601             o = metao;
00602         } else {
00603             o = PyInt_FromLong(*((short *) data));
00604         }
00605         break;
00606 
00607     case RPM_STRING_ARRAY_TYPE:
00608         stringArray = data;
00609 
00610         metao = PyList_New(0);
00611         for (i = 0; i < count; i++) {
00612             o = PyString_FromString(stringArray[i]);
00613             PyList_Append(metao, o);
00614             Py_DECREF(o);
00615         }
00616         free (stringArray);
00617         o = metao;
00618         break;
00619 
00620     case RPM_STRING_TYPE:
00621         if (count != 1 || forceArray) {
00622             stringArray = data;
00623 
00624             metao = PyList_New(0);
00625             for (i=0; i < count; i++) {
00626                 o = PyString_FromString(stringArray[i]);
00627                 PyList_Append(metao, o);
00628                 Py_DECREF(o);
00629             }
00630             o = metao;
00631         } else {
00632             o = PyString_FromString(data);
00633             if (freeData)
00634                 free (data);
00635         }
00636         break;
00637 
00638     default:
00639         PyErr_SetString(PyExc_TypeError, "unsupported type in header");
00640         return NULL;
00641     }
00642 
00643     return o;
00644 }
00645 
00648 /*@unchecked@*/ /*@observer@*/
00649 static PyMappingMethods hdr_as_mapping = {
00650         (inquiry) 0,                    /* mp_length */
00651         (binaryfunc) hdr_subscript,     /* mp_subscript */
00652         (objobjargproc)0,               /* mp_ass_subscript */
00653 };
00654 
00657 static char hdr_doc[] =
00658 "";
00659 
00662 /*@unchecked@*/ /*@observer@*/
00663 PyTypeObject hdr_Type = {
00664         PyObject_HEAD_INIT(&PyType_Type)
00665         0,                              /* ob_size */
00666         "rpm.hdr",                      /* tp_name */
00667         sizeof(hdrObject),              /* tp_size */
00668         0,                              /* tp_itemsize */
00669         (destructor) hdr_dealloc,       /* tp_dealloc */
00670         0,                              /* tp_print */
00671         (getattrfunc) hdr_getattr,      /* tp_getattr */
00672         0,                              /* tp_setattr */
00673         (cmpfunc) hdr_compare,          /* tp_compare */
00674         0,                              /* tp_repr */
00675         0,                              /* tp_as_number */
00676         0,                              /* tp_as_sequence */
00677         &hdr_as_mapping,                /* tp_as_mapping */
00678         hdr_hash,                       /* tp_hash */
00679         0,                              /* tp_call */
00680         0,                              /* tp_str */
00681         0,                              /* tp_getattro */
00682         0,                              /* tp_setattro */
00683         0,                              /* tp_as_buffer */
00684         Py_TPFLAGS_DEFAULT,             /* tp_flags */
00685         hdr_doc,                        /* tp_doc */
00686 #if Py_TPFLAGS_HAVE_ITER
00687         0,                              /* tp_traverse */
00688         0,                              /* tp_clear */
00689         0,                              /* tp_richcompare */
00690         0,                              /* tp_weaklistoffset */
00691         0,                              /* tp_iter */
00692         0,                              /* tp_iternext */
00693         hdr_methods,                    /* tp_methods */
00694         0,                              /* tp_members */
00695         0,                              /* tp_getset */
00696         0,                              /* tp_base */
00697         0,                              /* tp_dict */
00698         0,                              /* tp_descr_get */
00699         0,                              /* tp_descr_set */
00700         0,                              /* tp_dictoffset */
00701         0,                              /* tp_init */
00702         0,                              /* tp_alloc */
00703         0,                              /* tp_new */
00704         0,                              /* tp_free */
00705         0,                              /* tp_is_gc */
00706 #endif
00707 };
00708 
00709 hdrObject * hdr_Wrap(Header h)
00710 {
00711     hdrObject * hdr = PyObject_New(hdrObject, &hdr_Type);
00712     hdr->h = headerLink(h);
00713     hdr->fileList = hdr->linkList = hdr->md5list = NULL;
00714     hdr->uids = hdr->gids = hdr->mtimes = hdr->fileSizes = NULL;
00715     hdr->modes = hdr->rdevs = NULL;
00716     return hdr;
00717 }
00718 
00719 Header hdrGetHeader(hdrObject * s)
00720 {
00721     return s->h;
00722 }
00723 
00726 PyObject * hdrLoad(PyObject * self, PyObject * args)
00727 {
00728     hdrObject * hdr;
00729     char * copy = NULL;
00730     char * obj;
00731     Header h;
00732     int len;
00733 
00734     if (!PyArg_ParseTuple(args, "s#", &obj, &len)) return NULL;
00735 
00736     /* malloc is needed to avoid surprises from data swab in headerLoad(). */
00737     copy = malloc(len);
00738     if (copy == NULL) {
00739         PyErr_SetString(pyrpmError, "out of memory");
00740         return NULL;
00741     }
00742     memcpy (copy, obj, len);
00743 
00744     h = headerLoad(copy);
00745     if (!h) {
00746         PyErr_SetString(pyrpmError, "bad header");
00747         return NULL;
00748     }
00749     headerAllocated(h);
00750     compressFilelist (h);
00751     providePackageNVR (h);
00752 
00753     hdr = hdr_Wrap(h);
00754     h = headerFree(h);  /* XXX ref held by hdr */
00755 
00756     return (PyObject *) hdr;
00757 }
00758 
00761 PyObject * rhnLoad(PyObject * self, PyObject * args)
00762 {
00763     char * obj, * copy=NULL;
00764     Header h;
00765     int len;
00766 
00767     if (!PyArg_ParseTuple(args, "s#", &obj, &len)) return NULL;
00768 
00769     /* malloc is needed to avoid surprises from data swab in headerLoad(). */
00770     copy = malloc(len);
00771     if (copy == NULL) {
00772         PyErr_SetString(pyrpmError, "out of memory");
00773         return NULL;
00774     }
00775     memcpy (copy, obj, len);
00776 
00777     h = headerLoad(copy);
00778     if (!h) {
00779         PyErr_SetString(pyrpmError, "bad header");
00780         return NULL;
00781     }
00782     headerAllocated(h);
00783 
00784     /* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
00785     if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
00786         PyErr_SetString(pyrpmError, "bad header, not immutable");
00787         headerFree(h);
00788         return NULL;
00789     }
00790 
00791     /* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
00792     if (!headerIsEntry(h, RPMTAG_SHA1HEADER)
00793     &&  !headerIsEntry(h, RPMTAG_SHA1RHN)) {
00794         PyErr_SetString(pyrpmError, "bad header, no digest");
00795         headerFree(h);
00796         return NULL;
00797     }
00798 
00799     /* Retrofit a RHNPlatform: tag. */
00800     if (!headerIsEntry(h, RPMTAG_RHNPLATFORM)) {
00801         const char * arch;
00802         int_32 at;
00803         if (headerGetEntry(h, RPMTAG_ARCH, &at, (void **)&arch, NULL))
00804             headerAddEntry(h, RPMTAG_RHNPLATFORM, at, arch, 1);
00805     }
00806 
00807     return (PyObject *) hdr_Wrap(h);
00808 }
00809 
00812 PyObject * rpmReadHeaders (FD_t fd)
00813 {
00814     PyObject * list;
00815     Header h;
00816     hdrObject * hdr;
00817 
00818     if (!fd) {
00819         PyErr_SetFromErrno(pyrpmError);
00820         return NULL;
00821     }
00822 
00823     list = PyList_New(0);
00824     Py_BEGIN_ALLOW_THREADS
00825     h = headerRead(fd, HEADER_MAGIC_YES);
00826     Py_END_ALLOW_THREADS
00827 
00828     while (h) {
00829         compressFilelist(h);
00830         providePackageNVR(h);
00831         hdr = hdr_Wrap(h);
00832         if (PyList_Append(list, (PyObject *) hdr)) {
00833             Py_DECREF(list);
00834             Py_DECREF(hdr);
00835             return NULL;
00836         }
00837         Py_DECREF(hdr);
00838 
00839         h = headerFree(h);      /* XXX ref held by hdr */
00840 
00841         Py_BEGIN_ALLOW_THREADS
00842         h = headerRead(fd, HEADER_MAGIC_YES);
00843         Py_END_ALLOW_THREADS
00844     }
00845 
00846     return list;
00847 }
00848 
00851 PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args)
00852 {
00853     FD_t fd;
00854     int fileno;
00855     PyObject * list;
00856 
00857     if (!PyArg_ParseTuple(args, "i", &fileno)) return NULL;
00858     fd = fdDup(fileno);
00859 
00860     list = rpmReadHeaders (fd);
00861     Fclose(fd);
00862 
00863     return list;
00864 }
00865 
00868 PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args)
00869 {
00870     char * filespec;
00871     FD_t fd;
00872     PyObject * list;
00873 
00874     if (!PyArg_ParseTuple(args, "s", &filespec)) return NULL;
00875     fd = Fopen(filespec, "r.fdio");
00876 
00877     if (!fd) {
00878         PyErr_SetFromErrno(pyrpmError);
00879         return NULL;
00880     }
00881 
00882     list = rpmReadHeaders (fd);
00883     Fclose(fd);
00884 
00885     return list;
00886 }
00887 
00892 int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag)
00893 {
00894     Header h;
00895     HeaderIterator hi;
00896     int_32 * newMatch;
00897     int_32 * oldMatch;
00898     hdrObject * hdr;
00899     int count = 0;
00900     int type, c, tag;
00901     void * p;
00902 
00903     Py_BEGIN_ALLOW_THREADS
00904     h = headerRead(fd, HEADER_MAGIC_YES);
00905     Py_END_ALLOW_THREADS
00906 
00907     while (h) {
00908         if (!headerGetEntry(h, matchTag, NULL, (void **) &newMatch, NULL)) {
00909             PyErr_SetString(pyrpmError, "match tag missing in new header");
00910             return 1;
00911         }
00912 
00913         hdr = (hdrObject *) PyList_GetItem(list, count++);
00914         if (!hdr) return 1;
00915 
00916         if (!headerGetEntry(hdr->h, matchTag, NULL, (void **) &oldMatch, NULL)) {
00917             PyErr_SetString(pyrpmError, "match tag missing in new header");
00918             return 1;
00919         }
00920 
00921         if (*newMatch != *oldMatch) {
00922             PyErr_SetString(pyrpmError, "match tag mismatch");
00923             return 1;
00924         }
00925 
00926         hdr->md5list = _free(hdr->md5list);
00927         hdr->fileList = _free(hdr->fileList);
00928         hdr->linkList = _free(hdr->linkList);
00929 
00930         for (hi = headerInitIterator(h);
00931             headerNextIterator(hi, &tag, &type, (void *) &p, &c);
00932             p = headerFreeData(p, type))
00933         {
00934             /* could be dupes */
00935             headerRemoveEntry(hdr->h, tag);
00936             headerAddEntry(hdr->h, tag, type, p, c);
00937         }
00938 
00939         headerFreeIterator(hi);
00940         h = headerFree(h);
00941 
00942         Py_BEGIN_ALLOW_THREADS
00943         h = headerRead(fd, HEADER_MAGIC_YES);
00944         Py_END_ALLOW_THREADS
00945     }
00946 
00947     return 0;
00948 }
00949 
00950 PyObject * rpmMergeHeadersFromFD(PyObject * self, PyObject * args)
00951 {
00952     FD_t fd;
00953     int fileno;
00954     PyObject * list;
00955     int rc;
00956     int matchTag;
00957 
00958     if (!PyArg_ParseTuple(args, "Oii", &list, &fileno, &matchTag))
00959         return NULL;
00960 
00961     if (!PyList_Check(list)) {
00962         PyErr_SetString(PyExc_TypeError, "first parameter must be a list");
00963         return NULL;
00964     }
00965 
00966     fd = fdDup(fileno);
00967 
00968     rc = rpmMergeHeaders (list, fd, matchTag);
00969     Fclose(fd);
00970 
00971     if (rc) {
00972         return NULL;
00973     }
00974 
00975     Py_INCREF(Py_None);
00976     return Py_None;
00977 }
00978 
00981 PyObject * versionCompare (PyObject * self, PyObject * args)
00982 {
00983     hdrObject * h1, * h2;
00984 
00985     if (!PyArg_ParseTuple(args, "O!O!", &hdr_Type, &h1, &hdr_Type, &h2))
00986         return NULL;
00987 
00988     return Py_BuildValue("i", hdr_compare(h1, h2));
00989 }
00990 
00993 static int compare_values(const char *str1, const char *str2)
00994 {
00995     if (!str1 && !str2)
00996         return 0;
00997     else if (str1 && !str2)
00998         return 1;
00999     else if (!str1 && str2)
01000         return -1;
01001     return rpmvercmp(str1, str2);
01002 }
01003 
01004 PyObject * labelCompare (PyObject * self, PyObject * args)
01005 {
01006     char *v1, *r1, *e1, *v2, *r2, *e2;
01007     int rc;
01008 
01009     if (!PyArg_ParseTuple(args, "(zzz)(zzz)",
01010                         &e1, &v1, &r1, &e2, &v2, &r2))
01011         return NULL;
01012 
01013     rc = compare_values(e1, e2);
01014     if (!rc) {
01015         rc = compare_values(v1, v2);
01016         if (!rc)
01017             rc = compare_values(r1, r2);
01018     }
01019     return Py_BuildValue("i", rc);
01020 }
01021 

Generated on Sun Nov 21 17:08:57 2004 for rpm by doxygen 1.3.5