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         forceArray = 1;
00541         break;
00542     case RPMTAG_SUMMARY:
00543     case RPMTAG_GROUP:
00544     case RPMTAG_DESCRIPTION:
00545         freeData = 1;
00546         break;
00547     default:
00548         break;
00549     }
00550 
00551     switch (type) {
00552     case RPM_BIN_TYPE:
00553         o = PyString_FromStringAndSize(data, count);
00554         break;
00555 
00556     case RPM_INT32_TYPE:
00557         if (count != 1 || forceArray) {
00558             metao = PyList_New(0);
00559             for (i = 0; i < count; i++) {
00560                 o = PyInt_FromLong(((int *) data)[i]);
00561                 PyList_Append(metao, o);
00562                 Py_DECREF(o);
00563             }
00564             o = metao;
00565         } else {
00566             o = PyInt_FromLong(*((int *) data));
00567         }
00568         break;
00569 
00570     case RPM_CHAR_TYPE:
00571     case RPM_INT8_TYPE:
00572         if (count != 1 || forceArray) {
00573             metao = PyList_New(0);
00574             for (i = 0; i < count; i++) {
00575                 o = PyInt_FromLong(((char *) data)[i]);
00576                 PyList_Append(metao, o);
00577                 Py_DECREF(o);
00578             }
00579             o = metao;
00580         } else {
00581             o = PyInt_FromLong(*((char *) data));
00582         }
00583         break;
00584 
00585     case RPM_INT16_TYPE:
00586         if (count != 1 || forceArray) {
00587             metao = PyList_New(0);
00588             for (i = 0; i < count; i++) {
00589                 o = PyInt_FromLong(((short *) data)[i]);
00590                 PyList_Append(metao, o);
00591                 Py_DECREF(o);
00592             }
00593             o = metao;
00594         } else {
00595             o = PyInt_FromLong(*((short *) data));
00596         }
00597         break;
00598 
00599     case RPM_STRING_ARRAY_TYPE:
00600         stringArray = data;
00601 
00602         metao = PyList_New(0);
00603         for (i = 0; i < count; i++) {
00604             o = PyString_FromString(stringArray[i]);
00605             PyList_Append(metao, o);
00606             Py_DECREF(o);
00607         }
00608         free (stringArray);
00609         o = metao;
00610         break;
00611 
00612     case RPM_STRING_TYPE:
00613         if (count != 1 || forceArray) {
00614             stringArray = data;
00615 
00616             metao = PyList_New(0);
00617             for (i=0; i < count; i++) {
00618                 o = PyString_FromString(stringArray[i]);
00619                 PyList_Append(metao, o);
00620                 Py_DECREF(o);
00621             }
00622             o = metao;
00623         } else {
00624             o = PyString_FromString(data);
00625             if (freeData)
00626                 free (data);
00627         }
00628         break;
00629 
00630     default:
00631         PyErr_SetString(PyExc_TypeError, "unsupported type in header");
00632         return NULL;
00633     }
00634 
00635     return o;
00636 }
00637 
00640 /*@unchecked@*/ /*@observer@*/
00641 static PyMappingMethods hdr_as_mapping = {
00642         (inquiry) 0,                    /* mp_length */
00643         (binaryfunc) hdr_subscript,     /* mp_subscript */
00644         (objobjargproc)0,               /* mp_ass_subscript */
00645 };
00646 
00649 static char hdr_doc[] =
00650 "";
00651 
00654 /*@unchecked@*/ /*@observer@*/
00655 PyTypeObject hdr_Type = {
00656         PyObject_HEAD_INIT(&PyType_Type)
00657         0,                              /* ob_size */
00658         "rpm.hdr",                      /* tp_name */
00659         sizeof(hdrObject),              /* tp_size */
00660         0,                              /* tp_itemsize */
00661         (destructor) hdr_dealloc,       /* tp_dealloc */
00662         0,                              /* tp_print */
00663         (getattrfunc) 0,                /* tp_getattr */
00664         0,                              /* tp_setattr */
00665         (cmpfunc) hdr_compare,          /* tp_compare */
00666         0,                              /* tp_repr */
00667         0,                              /* tp_as_number */
00668         0,                              /* tp_as_sequence */
00669         &hdr_as_mapping,                /* tp_as_mapping */
00670         hdr_hash,                       /* tp_hash */
00671         0,                              /* tp_call */
00672         0,                              /* tp_str */
00673         (getattrofunc) hdr_getattro,    /* tp_getattro */
00674         (setattrofunc) hdr_setattro,    /* tp_setattro */
00675         0,                              /* tp_as_buffer */
00676         Py_TPFLAGS_DEFAULT,             /* tp_flags */
00677         hdr_doc,                        /* tp_doc */
00678 #if Py_TPFLAGS_HAVE_ITER
00679         0,                              /* tp_traverse */
00680         0,                              /* tp_clear */
00681         0,                              /* tp_richcompare */
00682         0,                              /* tp_weaklistoffset */
00683         0,                              /* tp_iter */
00684         0,                              /* tp_iternext */
00685         hdr_methods,                    /* tp_methods */
00686         0,                              /* tp_members */
00687         0,                              /* tp_getset */
00688         0,                              /* tp_base */
00689         0,                              /* tp_dict */
00690         0,                              /* tp_descr_get */
00691         0,                              /* tp_descr_set */
00692         0,                              /* tp_dictoffset */
00693         0,                              /* tp_init */
00694         0,                              /* tp_alloc */
00695         0,                              /* tp_new */
00696         0,                              /* tp_free */
00697         0,                              /* tp_is_gc */
00698 #endif
00699 };
00700 
00701 hdrObject * hdr_Wrap(Header h)
00702 {
00703     hdrObject * hdr = PyObject_New(hdrObject, &hdr_Type);
00704     hdr->h = headerLink(h);
00705     hdr->fileList = hdr->linkList = hdr->md5list = NULL;
00706     hdr->uids = hdr->gids = hdr->mtimes = hdr->fileSizes = NULL;
00707     hdr->modes = hdr->rdevs = NULL;
00708     return hdr;
00709 }
00710 
00711 Header hdrGetHeader(hdrObject * s)
00712 {
00713     return s->h;
00714 }
00715 
00718 PyObject * hdrLoad(PyObject * self, PyObject * args, PyObject * kwds)
00719 {
00720     hdrObject * hdr;
00721     char * copy = NULL;
00722     char * obj;
00723     Header h;
00724     int len;
00725     char * kwlist[] = {"headers", NULL};
00726 
00727     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwlist, &obj, &len))
00728         return NULL;
00729 
00730     /* malloc is needed to avoid surprises from data swab in headerLoad(). */
00731     copy = malloc(len);
00732     if (copy == NULL) {
00733         PyErr_SetString(pyrpmError, "out of memory");
00734         return NULL;
00735     }
00736     memcpy (copy, obj, len);
00737 
00738     h = headerLoad(copy);
00739     if (!h) {
00740         PyErr_SetString(pyrpmError, "bad header");
00741         return NULL;
00742     }
00743     headerAllocated(h);
00744     compressFilelist (h);
00745     providePackageNVR (h);
00746 
00747     hdr = hdr_Wrap(h);
00748     h = headerFree(h);  /* XXX ref held by hdr */
00749 
00750     return (PyObject *) hdr;
00751 }
00752 
00755 PyObject * rhnLoad(PyObject * self, PyObject * args, PyObject * kwds)
00756 {
00757     char * obj, * copy=NULL;
00758     Header h;
00759     int len;
00760     char * kwlist[] = {"headers", NULL};
00761 
00762     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwlist, &obj, &len))
00763         return NULL;
00764 
00765     /* malloc is needed to avoid surprises from data swab in headerLoad(). */
00766     copy = malloc(len);
00767     if (copy == NULL) {
00768         PyErr_SetString(pyrpmError, "out of memory");
00769         return NULL;
00770     }
00771     memcpy (copy, obj, len);
00772 
00773     h = headerLoad(copy);
00774     if (!h) {
00775         PyErr_SetString(pyrpmError, "bad header");
00776         return NULL;
00777     }
00778     headerAllocated(h);
00779 
00780     /* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
00781     if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
00782         PyErr_SetString(pyrpmError, "bad header, not immutable");
00783         headerFree(h);
00784         return NULL;
00785     }
00786 
00787     /* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
00788     if (!headerIsEntry(h, RPMTAG_SHA1HEADER)
00789     &&  !headerIsEntry(h, RPMTAG_SHA1RHN)) {
00790         PyErr_SetString(pyrpmError, "bad header, no digest");
00791         headerFree(h);
00792         return NULL;
00793     }
00794 
00795     /* Retrofit a RHNPlatform: tag. */
00796     if (!headerIsEntry(h, RPMTAG_RHNPLATFORM)) {
00797         const char * arch;
00798         int_32 at;
00799         if (headerGetEntry(h, RPMTAG_ARCH, &at, (void **)&arch, NULL))
00800             headerAddEntry(h, RPMTAG_RHNPLATFORM, at, arch, 1);
00801     }
00802 
00803     return (PyObject *) hdr_Wrap(h);
00804 }
00805 
00808 PyObject * rpmReadHeaders (FD_t fd)
00809 {
00810     PyObject * list;
00811     Header h;
00812     hdrObject * hdr;
00813 
00814     if (!fd) {
00815         PyErr_SetFromErrno(pyrpmError);
00816         return NULL;
00817     }
00818 
00819     list = PyList_New(0);
00820     Py_BEGIN_ALLOW_THREADS
00821     h = headerRead(fd, HEADER_MAGIC_YES);
00822     Py_END_ALLOW_THREADS
00823 
00824     while (h) {
00825         compressFilelist(h);
00826         providePackageNVR(h);
00827         hdr = hdr_Wrap(h);
00828         if (PyList_Append(list, (PyObject *) hdr)) {
00829             Py_DECREF(list);
00830             Py_DECREF(hdr);
00831             return NULL;
00832         }
00833         Py_DECREF(hdr);
00834 
00835         h = headerFree(h);      /* XXX ref held by hdr */
00836 
00837         Py_BEGIN_ALLOW_THREADS
00838         h = headerRead(fd, HEADER_MAGIC_YES);
00839         Py_END_ALLOW_THREADS
00840     }
00841 
00842     return list;
00843 }
00844 
00847 PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args, PyObject * kwds)
00848 {
00849     FD_t fd;
00850     int fileno;
00851     PyObject * list;
00852     char * kwlist[] = {"fd", NULL};
00853 
00854     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
00855         return NULL;
00856 
00857     fd = fdDup(fileno);
00858 
00859     list = rpmReadHeaders (fd);
00860     Fclose(fd);
00861 
00862     return list;
00863 }
00864 
00867 PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args, PyObject *kwds)
00868 {
00869     char * filespec;
00870     FD_t fd;
00871     PyObject * list;
00872     char * kwlist[] = {"file", NULL};
00873 
00874     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &filespec))
00875         return NULL;
00876 
00877     fd = Fopen(filespec, "r.fdio");
00878 
00879     if (!fd) {
00880         PyErr_SetFromErrno(pyrpmError);
00881         return NULL;
00882     }
00883 
00884     list = rpmReadHeaders (fd);
00885     Fclose(fd);
00886 
00887     return list;
00888 }
00889 
00894 int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag)
00895 {
00896     Header h;
00897     HeaderIterator hi;
00898     int_32 * newMatch;
00899     int_32 * oldMatch;
00900     hdrObject * hdr;
00901     int count = 0;
00902     int type, c, tag;
00903     void * p;
00904 
00905     Py_BEGIN_ALLOW_THREADS
00906     h = headerRead(fd, HEADER_MAGIC_YES);
00907     Py_END_ALLOW_THREADS
00908 
00909     while (h) {
00910         if (!headerGetEntry(h, matchTag, NULL, (void **) &newMatch, NULL)) {
00911             PyErr_SetString(pyrpmError, "match tag missing in new header");
00912             return 1;
00913         }
00914 
00915         hdr = (hdrObject *) PyList_GetItem(list, count++);
00916         if (!hdr) return 1;
00917 
00918         if (!headerGetEntry(hdr->h, matchTag, NULL, (void **) &oldMatch, NULL)) {
00919             PyErr_SetString(pyrpmError, "match tag missing in new header");
00920             return 1;
00921         }
00922 
00923         if (*newMatch != *oldMatch) {
00924             PyErr_SetString(pyrpmError, "match tag mismatch");
00925             return 1;
00926         }
00927 
00928         hdr->md5list = _free(hdr->md5list);
00929         hdr->fileList = _free(hdr->fileList);
00930         hdr->linkList = _free(hdr->linkList);
00931 
00932         for (hi = headerInitIterator(h);
00933             headerNextIterator(hi, &tag, &type, (void *) &p, &c);
00934             p = headerFreeData(p, type))
00935         {
00936             /* could be dupes */
00937             headerRemoveEntry(hdr->h, tag);
00938             headerAddEntry(hdr->h, tag, type, p, c);
00939         }
00940 
00941         headerFreeIterator(hi);
00942         h = headerFree(h);
00943 
00944         Py_BEGIN_ALLOW_THREADS
00945         h = headerRead(fd, HEADER_MAGIC_YES);
00946         Py_END_ALLOW_THREADS
00947     }
00948 
00949     return 0;
00950 }
00951 
00952 PyObject *
00953 rpmMergeHeadersFromFD(PyObject * self, PyObject * args, PyObject * kwds)
00954 {
00955     FD_t fd;
00956     int fileno;
00957     PyObject * list;
00958     int rc;
00959     int matchTag;
00960     char * kwlist[] = {"list", "fd", "matchTag", NULL};
00961 
00962     if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oii", kwlist, &list,
00963             &fileno, &matchTag))
00964         return NULL;
00965 
00966     if (!PyList_Check(list)) {
00967         PyErr_SetString(PyExc_TypeError, "first parameter must be a list");
00968         return NULL;
00969     }
00970 
00971     fd = fdDup(fileno);
00972 
00973     rc = rpmMergeHeaders (list, fd, matchTag);
00974     Fclose(fd);
00975 
00976     if (rc) {
00977         return NULL;
00978     }
00979 
00980     Py_INCREF(Py_None);
00981     return Py_None;
00982 }
00983 
00986 PyObject *
00987 rpmSingleHeaderFromFD(PyObject * self, PyObject * args, PyObject * kwds)
00988 {
00989     FD_t fd;
00990     int fileno;
00991     off_t offset;
00992     PyObject * tuple;
00993     Header h;
00994     char * kwlist[] = {"fd", NULL};
00995 
00996     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno))
00997         return NULL;
00998 
00999     offset = lseek(fileno, 0, SEEK_CUR);
01000 
01001     fd = fdDup(fileno);
01002 
01003     if (!fd) {
01004         PyErr_SetFromErrno(pyrpmError);
01005         return NULL;
01006     }
01007 
01008     Py_BEGIN_ALLOW_THREADS
01009     h = headerRead(fd, HEADER_MAGIC_YES);
01010     Py_END_ALLOW_THREADS
01011 
01012     Fclose(fd);
01013 
01014     tuple = PyTuple_New(2);
01015 
01016     if (h && tuple) {
01017         PyTuple_SET_ITEM(tuple, 0, (PyObject *) hdr_Wrap(h));
01018         PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(offset));
01019         h = headerFree(h);
01020     } else {
01021         Py_INCREF(Py_None);
01022         Py_INCREF(Py_None);
01023         PyTuple_SET_ITEM(tuple, 0, Py_None);
01024         PyTuple_SET_ITEM(tuple, 1, Py_None);
01025     }
01026 
01027     return tuple;
01028 }
01029 
01032 PyObject * versionCompare (PyObject * self, PyObject * args, PyObject * kwds)
01033 {
01034     hdrObject * h1, * h2;
01035     char * kwlist[] = {"version0", "version1", NULL};
01036 
01037     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!", kwlist, &hdr_Type,
01038             &h1, &hdr_Type, &h2))
01039         return NULL;
01040 
01041     return Py_BuildValue("i", hdr_compare(h1, h2));
01042 }
01043 
01046 static int compare_values(const char *str1, const char *str2)
01047 {
01048     if (!str1 && !str2)
01049         return 0;
01050     else if (str1 && !str2)
01051         return 1;
01052     else if (!str1 && str2)
01053         return -1;
01054     return rpmvercmp(str1, str2);
01055 }
01056 
01057 PyObject * labelCompare (PyObject * self, PyObject * args)
01058 {
01059     char *v1, *r1, *e1, *v2, *r2, *e2;
01060     int rc;
01061 
01062     if (!PyArg_ParseTuple(args, "(zzz)(zzz)",
01063                         &e1, &v1, &r1, &e2, &v2, &r2))
01064         return NULL;
01065 
01066     rc = compare_values(e1, e2);
01067     if (!rc) {
01068         rc = compare_values(v1, v2);
01069         if (!rc)
01070             rc = compare_values(r1, r2);
01071     }
01072     return Py_BuildValue("i", rc);
01073 }
01074 

Generated on Mon Mar 5 14:30:58 2007 for rpm by  doxygen 1.5.1