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

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

Generated on Sat Mar 11 04:43:44 2006 for rpm by  doxygen 1.3.9.1