python/header-py.c

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

Generated on Fri Oct 12 08:44:54 2007 for rpm by  doxygen 1.5.2