rpm
4.5
|
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 #define _RPMEVR_INTERNAL 00016 #include "rpmevr.h" 00017 00018 #include "header-py.h" 00019 #include "rpmds-py.h" 00020 #include "rpmfi-py.h" 00021 00022 #include "debug.h" 00023 00135 struct hdrObject_s { 00136 PyObject_HEAD 00137 Header h; 00138 char ** md5list; 00139 char ** fileList; 00140 char ** linkList; 00141 int_32 * fileSizes; 00142 int_32 * mtimes; 00143 int_32 * uids, * gids; /* XXX these tags are not used anymore */ 00144 unsigned short * rdevs; 00145 unsigned short * modes; 00146 } ; 00147 00150 /*@unused@*/ static inline Header headerAllocated(Header h) 00151 /*@modifies h @*/ 00152 { 00153 h->flags |= HEADERFLAG_ALLOCATED; 00154 return 0; 00155 } 00156 00157 /*@-boundsread@*/ 00158 static int dncmp(const void * a, const void * b) 00159 /*@*/ 00160 { 00161 const char *const * first = a; 00162 const char *const * second = b; 00163 return strcmp(*first, *second); 00164 } 00165 /*@=boundsread@*/ 00166 00171 static void expandFilelist(Header h) 00172 /*@modifies h @*/ 00173 { 00174 HAE_t hae = (HAE_t)headerAddEntry; 00175 HRE_t hre = (HRE_t)headerRemoveEntry; 00176 const char ** fileNames = NULL; 00177 int count = 0; 00178 int xx; 00179 00180 /*@-branchstate@*/ 00181 if (!headerIsEntry(h, RPMTAG_OLDFILENAMES)) { 00182 rpmfiBuildFNames(h, RPMTAG_BASENAMES, &fileNames, &count); 00183 if (fileNames == NULL || count <= 0) 00184 return; 00185 xx = hae(h, RPMTAG_OLDFILENAMES, RPM_STRING_ARRAY_TYPE, 00186 fileNames, count); 00187 fileNames = _free(fileNames); 00188 } 00189 /*@=branchstate@*/ 00190 00191 xx = hre(h, RPMTAG_DIRNAMES); 00192 xx = hre(h, RPMTAG_BASENAMES); 00193 xx = hre(h, RPMTAG_DIRINDEXES); 00194 } 00195 00196 /*@-bounds@*/ 00201 static void compressFilelist(Header h) 00202 /*@modifies h @*/ 00203 { 00204 HGE_t hge = (HGE_t)headerGetEntryMinMemory; 00205 HAE_t hae = (HAE_t)headerAddEntry; 00206 HRE_t hre = (HRE_t)headerRemoveEntry; 00207 HFD_t hfd = headerFreeData; 00208 char ** fileNames; 00209 const char ** dirNames; 00210 const char ** baseNames; 00211 int_32 * dirIndexes; 00212 rpmTagType fnt; 00213 int count; 00214 int i, xx; 00215 int dirIndex = -1; 00216 00217 /* 00218 * This assumes the file list is already sorted, and begins with a 00219 * single '/'. That assumption isn't critical, but it makes things go 00220 * a bit faster. 00221 */ 00222 00223 if (headerIsEntry(h, RPMTAG_DIRNAMES)) { 00224 xx = hre(h, RPMTAG_OLDFILENAMES); 00225 return; /* Already converted. */ 00226 } 00227 00228 if (!hge(h, RPMTAG_OLDFILENAMES, &fnt, &fileNames, &count)) 00229 return; /* no file list */ 00230 if (fileNames == NULL || count <= 0) 00231 return; 00232 00233 dirNames = alloca(sizeof(*dirNames) * count); /* worst case */ 00234 baseNames = alloca(sizeof(*dirNames) * count); 00235 dirIndexes = alloca(sizeof(*dirIndexes) * count); 00236 00237 if (fileNames[0][0] != '/') { 00238 /* HACK. Source RPM, so just do things differently */ 00239 dirIndex = 0; 00240 dirNames[dirIndex] = ""; 00241 for (i = 0; i < count; i++) { 00242 dirIndexes[i] = dirIndex; 00243 baseNames[i] = fileNames[i]; 00244 } 00245 goto exit; 00246 } 00247 00248 /*@-branchstate@*/ 00249 for (i = 0; i < count; i++) { 00250 const char ** needle; 00251 char savechar; 00252 char * baseName; 00253 int len; 00254 00255 if (fileNames[i] == NULL) /* XXX can't happen */ 00256 continue; 00257 baseName = strrchr(fileNames[i], '/') + 1; 00258 len = baseName - fileNames[i]; 00259 needle = dirNames; 00260 savechar = *baseName; 00261 *baseName = '\0'; 00262 /*@-compdef@*/ 00263 if (dirIndex < 0 || 00264 (needle = bsearch(&fileNames[i], dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL) { 00265 char *s = alloca(len + 1); 00266 memcpy(s, fileNames[i], len + 1); 00267 s[len] = '\0'; 00268 dirIndexes[i] = ++dirIndex; 00269 dirNames[dirIndex] = s; 00270 } else 00271 dirIndexes[i] = needle - dirNames; 00272 /*@=compdef@*/ 00273 00274 *baseName = savechar; 00275 baseNames[i] = baseName; 00276 } 00277 /*@=branchstate@*/ 00278 00279 exit: 00280 if (count > 0) { 00281 xx = hae(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, dirIndexes, count); 00282 xx = hae(h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE, 00283 baseNames, count); 00284 xx = hae(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE, 00285 dirNames, dirIndex + 1); 00286 } 00287 00288 fileNames = hfd(fileNames, fnt); 00289 00290 xx = hre(h, RPMTAG_OLDFILENAMES); 00291 } 00292 /*@=bounds@*/ 00293 /* make a header with _all_ the tags we need */ 00296 static void mungeFilelist(Header h) 00297 /*@*/ 00298 { 00299 const char ** fileNames = NULL; 00300 int count = 0; 00301 00302 if (!headerIsEntry (h, RPMTAG_BASENAMES) 00303 || !headerIsEntry (h, RPMTAG_DIRNAMES) 00304 || !headerIsEntry (h, RPMTAG_DIRINDEXES)) 00305 compressFilelist(h); 00306 00307 rpmfiBuildFNames(h, RPMTAG_BASENAMES, &fileNames, &count); 00308 00309 if (fileNames == NULL || count <= 0) 00310 return; 00311 00312 /* XXX Legacy tag needs to go away. */ 00313 headerAddEntry(h, RPMTAG_OLDFILENAMES, RPM_STRING_ARRAY_TYPE, 00314 fileNames, count); 00315 00316 fileNames = _free(fileNames); 00317 } 00318 00324 static void providePackageNVR(Header h) 00325 { 00326 HGE_t hge = (HGE_t)headerGetEntryMinMemory; 00327 HFD_t hfd = headerFreeData; 00328 const char *name, *version, *release; 00329 int_32 * epoch; 00330 const char *pEVR; 00331 char *p; 00332 int_32 pFlags = RPMSENSE_EQUAL; 00333 const char ** provides = NULL; 00334 const char ** providesEVR = NULL; 00335 rpmTagType pnt, pvt; 00336 int_32 * provideFlags = NULL; 00337 int providesCount; 00338 int i, xx; 00339 int bingo = 1; 00340 00341 /* Generate provides for this package name-version-release. */ 00342 xx = headerNVR(h, &name, &version, &release); 00343 if (!(name && version && release)) 00344 return; 00345 pEVR = p = alloca(21 + strlen(version) + 1 + strlen(release) + 1); 00346 *p = '\0'; 00347 if (hge(h, RPMTAG_EPOCH, NULL, &epoch, NULL)) { 00348 sprintf(p, "%d:", *epoch); 00349 while (*p != '\0') 00350 p++; 00351 } 00352 (void) stpcpy( stpcpy( stpcpy(p, version) , "-") , release); 00353 00354 /* 00355 * Rpm prior to 3.0.3 does not have versioned provides. 00356 * If no provides at all are available, we can just add. 00357 */ 00358 if (!hge(h, RPMTAG_PROVIDENAME, &pnt, &provides, &providesCount)) 00359 goto exit; 00360 00361 /* 00362 * Otherwise, fill in entries on legacy packages. 00363 */ 00364 if (!hge(h, RPMTAG_PROVIDEVERSION, &pvt, &providesEVR, NULL)) { 00365 for (i = 0; i < providesCount; i++) { 00366 char * vdummy = ""; 00367 int_32 fdummy = RPMSENSE_ANY; 00368 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE, 00369 &vdummy, 1); 00370 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE, 00371 &fdummy, 1); 00372 } 00373 goto exit; 00374 } 00375 00376 xx = hge(h, RPMTAG_PROVIDEFLAGS, NULL, &provideFlags, NULL); 00377 00378 /*@-nullderef@*/ /* LCL: providesEVR is not NULL */ 00379 if (provides && providesEVR && provideFlags) 00380 for (i = 0; i < providesCount; i++) { 00381 if (!(provides[i] && providesEVR[i])) 00382 continue; 00383 if (!(provideFlags[i] == RPMSENSE_EQUAL && 00384 !strcmp(name, provides[i]) && !strcmp(pEVR, providesEVR[i]))) 00385 continue; 00386 bingo = 0; 00387 break; 00388 } 00389 /*@=nullderef@*/ 00390 00391 exit: 00392 provides = hfd(provides, pnt); 00393 providesEVR = hfd(providesEVR, pvt); 00394 00395 if (bingo) { 00396 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME, RPM_STRING_ARRAY_TYPE, 00397 &name, 1); 00398 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE, 00399 &pFlags, 1); 00400 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE, 00401 &pEVR, 1); 00402 } 00403 } 00404 00409 00412 static PyObject * hdrKeyList(hdrObject * s) 00413 /*@*/ 00414 { 00415 PyObject * list, *o; 00416 HeaderIterator hi; 00417 int tag, type; 00418 00419 list = PyList_New(0); 00420 00421 hi = headerInitIterator(s->h); 00422 while (headerNextIterator(hi, &tag, &type, NULL, NULL)) { 00423 if (tag == HEADER_I18NTABLE) continue; 00424 00425 switch (type) { 00426 case RPM_OPENPGP_TYPE: 00427 case RPM_ASN1_TYPE: 00428 case RPM_BIN_TYPE: 00429 case RPM_INT64_TYPE: 00430 case RPM_INT32_TYPE: 00431 case RPM_INT16_TYPE: 00432 case RPM_INT8_TYPE: 00433 case RPM_CHAR_TYPE: 00434 case RPM_STRING_ARRAY_TYPE: 00435 case RPM_STRING_TYPE: 00436 PyList_Append(list, o=PyInt_FromLong(tag)); 00437 Py_DECREF(o); 00438 } 00439 } 00440 headerFreeIterator(hi); 00441 00442 return list; 00443 } 00444 00447 static PyObject * hdrUnload(hdrObject * s, PyObject * args, PyObject *keywords) 00448 /*@*/ 00449 { 00450 char * buf; 00451 PyObject * rc; 00452 int len, legacy = 0; 00453 Header h; 00454 static char *kwlist[] = { "legacyHeader", NULL}; 00455 00456 if (!PyArg_ParseTupleAndKeywords(args, keywords, "|i", kwlist, &legacy)) 00457 return NULL; 00458 00459 h = headerLink(s->h); 00460 /* XXX this legacy switch is a hack, needs to be removed. */ 00461 if (legacy) { 00462 h = headerCopy(s->h); /* XXX strip region tags, etc */ 00463 headerFree(s->h); 00464 } 00465 len = headerSizeof(h, 0); 00466 buf = headerUnload(h); 00467 h = headerFree(h); 00468 00469 if (buf == NULL || len == 0) { 00470 PyErr_SetString(pyrpmError, "can't unload bad header\n"); 00471 return NULL; 00472 } 00473 00474 rc = PyString_FromStringAndSize(buf, len); 00475 buf = _free(buf); 00476 00477 return rc; 00478 } 00479 00482 static PyObject * hdrExpandFilelist(hdrObject * s) 00483 /*@*/ 00484 { 00485 expandFilelist (s->h); 00486 00487 Py_INCREF(Py_None); 00488 return Py_None; 00489 } 00490 00493 static PyObject * hdrCompressFilelist(hdrObject * s) 00494 /*@*/ 00495 { 00496 compressFilelist (s->h); 00497 00498 Py_INCREF(Py_None); 00499 return Py_None; 00500 } 00501 00504 static PyObject * hdrGetOrigin(hdrObject * s) 00505 /*@*/ 00506 { 00507 const char * origin = NULL; 00508 if (s->h != NULL) 00509 00510 origin = headerGetOrigin(s->h); 00511 if (origin != NULL) 00512 return Py_BuildValue("s", origin); 00513 Py_INCREF(Py_None); 00514 return Py_None; 00515 } 00516 00519 static PyObject * hdrSetOrigin(hdrObject * s, PyObject * args, PyObject * kwds) 00520 /*@*/ 00521 { 00522 char * kwlist[] = {"origin", NULL}; 00523 const char * origin = NULL; 00524 00525 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:SetOrigin", kwlist, &origin)) 00526 return NULL; 00527 00528 if (s->h != NULL && origin != NULL) 00529 headerSetOrigin(s->h, origin); 00530 00531 Py_INCREF(Py_None); 00532 return Py_None; 00533 } 00534 00537 static PyObject * hdrFullFilelist(hdrObject * s) 00538 /*@*/ 00539 { 00540 mungeFilelist (s->h); 00541 00542 Py_INCREF(Py_None); 00543 return Py_None; 00544 } 00545 00548 static PyObject * hdrSprintf(hdrObject * s, PyObject * args, PyObject * kwds) 00549 /*@*/ 00550 { 00551 char * fmt; 00552 char * r; 00553 errmsg_t err; 00554 PyObject * result; 00555 char * kwlist[] = {"format", NULL}; 00556 00557 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &fmt)) 00558 return NULL; 00559 00560 r = headerSprintf(s->h, fmt, rpmTagTable, rpmHeaderFormats, &err); 00561 if (!r) { 00562 PyErr_SetString(pyrpmError, err); 00563 return NULL; 00564 } 00565 00566 result = Py_BuildValue("s", r); 00567 r = _free(r); 00568 00569 return result; 00570 } 00571 00576 /*@unchecked@*/ /*@observer@*/ 00577 static struct PyMethodDef hdr_methods[] = { 00578 {"keys", (PyCFunction) hdrKeyList, METH_NOARGS, 00579 NULL }, 00580 {"unload", (PyCFunction) hdrUnload, METH_VARARGS|METH_KEYWORDS, 00581 NULL }, 00582 {"expandFilelist", (PyCFunction) hdrExpandFilelist,METH_NOARGS, 00583 NULL }, 00584 {"compressFilelist",(PyCFunction) hdrCompressFilelist,METH_NOARGS, 00585 NULL }, 00586 {"fullFilelist", (PyCFunction) hdrFullFilelist, METH_NOARGS, 00587 NULL }, 00588 {"getorigin", (PyCFunction) hdrGetOrigin, METH_NOARGS, 00589 NULL }, 00590 {"setorigin", (PyCFunction) hdrSetOrigin, METH_NOARGS, 00591 NULL }, 00592 {"sprintf", (PyCFunction) hdrSprintf, METH_VARARGS|METH_KEYWORDS, 00593 NULL }, 00594 00595 {"dsOfHeader", (PyCFunction)hdr_dsOfHeader, METH_NOARGS, 00596 NULL}, 00597 {"dsFromHeader", (PyCFunction)hdr_dsFromHeader, METH_VARARGS|METH_KEYWORDS, 00598 NULL}, 00599 {"fiFromHeader", (PyCFunction)hdr_fiFromHeader, METH_VARARGS|METH_KEYWORDS, 00600 NULL}, 00601 00602 {NULL, NULL} /* sentinel */ 00603 }; 00604 00607 static int hdr_compare(hdrObject * a, hdrObject * b) 00608 /*@*/ 00609 { 00610 return rpmVersionCompare(a->h, b->h); 00611 } 00612 00613 static long hdr_hash(PyObject * h) 00614 { 00615 return (long) h; 00616 } 00617 00618 00621 static void hdr_dealloc(hdrObject * s) 00622 /*@*/ 00623 { 00624 if (s->h) headerFree(s->h); 00625 s->md5list = _free(s->md5list); 00626 s->fileList = _free(s->fileList); 00627 s->linkList = _free(s->linkList); 00628 PyObject_Del(s); 00629 } 00630 00633 long tagNumFromPyObject (PyObject *item) 00634 { 00635 char * str; 00636 int i; 00637 00638 if (PyInt_Check(item)) { 00639 return PyInt_AsLong(item); 00640 } else if (PyString_Check(item) || PyUnicode_Check(item)) { 00641 str = PyString_AsString(item); 00642 for (i = 0; i < rpmTagTableSize; i++) 00643 if (!xstrcasecmp(rpmTagTable[i].name + 7, str)) break; 00644 if (i < rpmTagTableSize) return rpmTagTable[i].val; 00645 } 00646 return -1; 00647 } 00648 00662 static int rpmHeaderGetEntry(Header h, int_32 tag, /*@out@*/ int_32 *type, 00663 /*@out@*/ void **p, /*@out@*/ int_32 *c) 00664 /*@modifies *type, *p, *c @*/ 00665 { 00666 switch (tag) { 00667 case RPMTAG_OLDFILENAMES: 00668 { const char ** fl = NULL; 00669 int count; 00670 rpmfiBuildFNames(h, RPMTAG_BASENAMES, &fl, &count); 00671 if (count > 0) { 00672 *p = fl; 00673 if (c) *c = count; 00674 if (type) *type = RPM_STRING_ARRAY_TYPE; 00675 return 1; 00676 } 00677 if (c) *c = 0; 00678 return 0; 00679 } /*@notreached@*/ break; 00680 00681 case RPMTAG_GROUP: 00682 case RPMTAG_DESCRIPTION: 00683 case RPMTAG_SUMMARY: 00684 { char fmt[128]; 00685 const char * msgstr; 00686 const char * errstr; 00687 00688 fmt[0] = '\0'; 00689 (void) stpcpy( stpcpy( stpcpy( fmt, "%{"), tagName(tag)), "}\n"); 00690 00691 /* XXX FIXME: memory leak. */ 00692 msgstr = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, &errstr); 00693 if (msgstr) { 00694 *p = (void *) msgstr; 00695 if (type) *type = RPM_STRING_TYPE; 00696 if (c) *c = 1; 00697 return 1; 00698 } else { 00699 if (c) *c = 0; 00700 return 0; 00701 } 00702 } /*@notreached@*/ break; 00703 00704 default: 00705 return headerGetEntry(h, tag, type, p, c); 00706 /*@notreached@*/ break; 00707 } 00708 /*@notreached@*/ 00709 } 00710 00713 static PyObject * hdr_subscript(hdrObject * s, PyObject * item) 00714 /*@*/ 00715 { 00716 int type, count, i, tag = -1; 00717 void * data; 00718 PyObject * o, * metao; 00719 char ** stringArray; 00720 int forceArray = 0; 00721 int freeData = 0; 00722 char * str; 00723 const struct headerSprintfExtension_s * ext = NULL; 00724 const struct headerSprintfExtension_s * extensions = rpmHeaderFormats; 00725 00726 if (PyCObject_Check (item)) 00727 ext = PyCObject_AsVoidPtr(item); 00728 else 00729 tag = tagNumFromPyObject (item); 00730 if (tag == -1 && (PyString_Check(item) || PyUnicode_Check(item))) { 00731 /* if we still don't have the tag, go looking for the header 00732 extensions */ 00733 str = PyString_AsString(item); 00734 while (extensions->name) { 00735 if (extensions->type == HEADER_EXT_TAG 00736 && !xstrcasecmp(extensions->name + 7, str)) { 00737 ext = extensions; 00738 } 00739 extensions++; 00740 } 00741 } 00742 00743 /* Retrieve data from extension or header. */ 00744 if (ext) { 00745 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00746 ext->u.tagFunction(s->h, he); 00747 type = he->t; 00748 data = he->p.ptr; 00749 count = he->c; 00750 freeData = he->freeData; 00751 } else { 00752 if (tag == -1) { 00753 PyErr_SetString(PyExc_KeyError, "unknown header tag"); 00754 return NULL; 00755 } 00756 00757 if (!rpmHeaderGetEntry(s->h, tag, &type, &data, &count)) { 00758 switch (tag) { 00759 case RPMTAG_EPOCH: 00760 case RPMTAG_NAME: 00761 case RPMTAG_VERSION: 00762 case RPMTAG_RELEASE: 00763 case RPMTAG_ARCH: 00764 case RPMTAG_OS: 00765 Py_INCREF(Py_None); 00766 return Py_None; 00767 break; 00768 default: 00769 return PyList_New(0); 00770 break; 00771 } 00772 } 00773 } 00774 00775 switch (tag) { 00776 case RPMTAG_OLDFILENAMES: 00777 case RPMTAG_FILESIZES: 00778 case RPMTAG_FILESTATES: 00779 case RPMTAG_FILEMODES: 00780 case RPMTAG_FILEUIDS: 00781 case RPMTAG_FILEGIDS: 00782 case RPMTAG_FILERDEVS: 00783 case RPMTAG_FILEMTIMES: 00784 case RPMTAG_FILEMD5S: 00785 case RPMTAG_FILELINKTOS: 00786 case RPMTAG_FILEFLAGS: 00787 case RPMTAG_ROOT: 00788 case RPMTAG_FILEUSERNAME: 00789 case RPMTAG_FILEGROUPNAME: 00790 case RPMTAG_REQUIRENAME: 00791 case RPMTAG_REQUIREFLAGS: 00792 case RPMTAG_REQUIREVERSION: 00793 case RPMTAG_PROVIDENAME: 00794 case RPMTAG_PROVIDEFLAGS: 00795 case RPMTAG_PROVIDEVERSION: 00796 case RPMTAG_OBSOLETENAME: 00797 case RPMTAG_OBSOLETEFLAGS: 00798 case RPMTAG_OBSOLETEVERSION: 00799 case RPMTAG_CONFLICTNAME: 00800 case RPMTAG_CONFLICTFLAGS: 00801 case RPMTAG_CONFLICTVERSION: 00802 case RPMTAG_CHANGELOGTIME: 00803 case RPMTAG_FILEVERIFYFLAGS: 00804 forceArray = 1; 00805 break; 00806 case RPMTAG_SUMMARY: 00807 case RPMTAG_GROUP: 00808 case RPMTAG_DESCRIPTION: 00809 freeData = 1; 00810 break; 00811 default: 00812 break; 00813 } 00814 00815 switch (type) { 00816 case RPM_OPENPGP_TYPE: 00817 case RPM_ASN1_TYPE: 00818 case RPM_BIN_TYPE: 00819 o = PyString_FromStringAndSize(data, count); 00820 break; 00821 00822 case RPM_INT64_TYPE: 00823 if (count != 1 || forceArray) { 00824 metao = PyList_New(0); 00825 for (i = 0; i < count; i++) { 00826 o = PyInt_FromLong(((long long *) data)[i]); 00827 PyList_Append(metao, o); 00828 Py_DECREF(o); 00829 } 00830 o = metao; 00831 } else { 00832 o = PyInt_FromLong(*((long long *) data)); 00833 } 00834 break; 00835 case RPM_INT32_TYPE: 00836 if (count != 1 || forceArray) { 00837 metao = PyList_New(0); 00838 for (i = 0; i < count; i++) { 00839 o = PyInt_FromLong(((int *) data)[i]); 00840 PyList_Append(metao, o); 00841 Py_DECREF(o); 00842 } 00843 o = metao; 00844 } else { 00845 o = PyInt_FromLong(*((int *) data)); 00846 } 00847 break; 00848 00849 case RPM_CHAR_TYPE: 00850 case RPM_INT8_TYPE: 00851 if (count != 1 || forceArray) { 00852 metao = PyList_New(0); 00853 for (i = 0; i < count; i++) { 00854 o = PyInt_FromLong(((char *) data)[i]); 00855 PyList_Append(metao, o); 00856 Py_DECREF(o); 00857 } 00858 o = metao; 00859 } else { 00860 o = PyInt_FromLong(*((char *) data)); 00861 } 00862 break; 00863 00864 case RPM_INT16_TYPE: 00865 if (count != 1 || forceArray) { 00866 metao = PyList_New(0); 00867 for (i = 0; i < count; i++) { 00868 o = PyInt_FromLong(((short *) data)[i]); 00869 PyList_Append(metao, o); 00870 Py_DECREF(o); 00871 } 00872 o = metao; 00873 } else { 00874 o = PyInt_FromLong(*((short *) data)); 00875 } 00876 break; 00877 00878 case RPM_STRING_ARRAY_TYPE: 00879 stringArray = data; 00880 00881 metao = PyList_New(0); 00882 for (i = 0; i < count; i++) { 00883 o = PyString_FromString(stringArray[i]); 00884 PyList_Append(metao, o); 00885 Py_DECREF(o); 00886 } 00887 free (stringArray); 00888 o = metao; 00889 break; 00890 00891 case RPM_STRING_TYPE: 00892 if (count != 1 || forceArray) { 00893 stringArray = data; 00894 00895 metao = PyList_New(0); 00896 for (i=0; i < count; i++) { 00897 o = PyString_FromString(stringArray[i]); 00898 PyList_Append(metao, o); 00899 Py_DECREF(o); 00900 } 00901 o = metao; 00902 } else { 00903 o = PyString_FromString(data); 00904 if (freeData) 00905 free (data); 00906 } 00907 break; 00908 00909 default: 00910 PyErr_SetString(PyExc_TypeError, "unsupported type in header"); 00911 return NULL; 00912 } 00913 00914 return o; 00915 } 00916 00917 static PyObject * hdr_getattro(PyObject * o, PyObject * n) 00918 /*@*/ 00919 { 00920 PyObject * res = PyObject_GenericGetAttr(o, n); 00921 if (res == NULL) 00922 res = hdr_subscript(o, n); 00923 return res; 00924 } 00925 00926 static int hdr_setattro(PyObject * o, PyObject * n, PyObject * v) 00927 /*@*/ 00928 { 00929 return PyObject_GenericSetAttr(o, n, v); 00930 } 00931 00934 /*@unchecked@*/ /*@observer@*/ 00935 static PyMappingMethods hdr_as_mapping = { 00936 (inquiry) 0, /* mp_length */ 00937 (binaryfunc) hdr_subscript, /* mp_subscript */ 00938 (objobjargproc)0, /* mp_ass_subscript */ 00939 }; 00940 00943 static char hdr_doc[] = 00944 ""; 00945 00948 /*@unchecked@*/ /*@observer@*/ 00949 PyTypeObject hdr_Type = { 00950 PyObject_HEAD_INIT(&PyType_Type) 00951 0, /* ob_size */ 00952 "rpm.hdr", /* tp_name */ 00953 sizeof(hdrObject), /* tp_size */ 00954 0, /* tp_itemsize */ 00955 (destructor) hdr_dealloc, /* tp_dealloc */ 00956 0, /* tp_print */ 00957 (getattrfunc) 0, /* tp_getattr */ 00958 0, /* tp_setattr */ 00959 (cmpfunc) hdr_compare, /* tp_compare */ 00960 0, /* tp_repr */ 00961 0, /* tp_as_number */ 00962 0, /* tp_as_sequence */ 00963 &hdr_as_mapping, /* tp_as_mapping */ 00964 hdr_hash, /* tp_hash */ 00965 0, /* tp_call */ 00966 0, /* tp_str */ 00967 (getattrofunc) hdr_getattro, /* tp_getattro */ 00968 (setattrofunc) hdr_setattro, /* tp_setattro */ 00969 0, /* tp_as_buffer */ 00970 Py_TPFLAGS_DEFAULT, /* tp_flags */ 00971 hdr_doc, /* tp_doc */ 00972 #if Py_TPFLAGS_HAVE_ITER 00973 0, /* tp_traverse */ 00974 0, /* tp_clear */ 00975 0, /* tp_richcompare */ 00976 0, /* tp_weaklistoffset */ 00977 0, /* tp_iter */ 00978 0, /* tp_iternext */ 00979 hdr_methods, /* tp_methods */ 00980 0, /* tp_members */ 00981 0, /* tp_getset */ 00982 0, /* tp_base */ 00983 0, /* tp_dict */ 00984 0, /* tp_descr_get */ 00985 0, /* tp_descr_set */ 00986 0, /* tp_dictoffset */ 00987 0, /* tp_init */ 00988 0, /* tp_alloc */ 00989 0, /* tp_new */ 00990 0, /* tp_free */ 00991 0, /* tp_is_gc */ 00992 #endif 00993 }; 00994 00995 hdrObject * hdr_Wrap(Header h) 00996 { 00997 hdrObject * hdr = PyObject_New(hdrObject, &hdr_Type); 00998 hdr->h = headerLink(h); 00999 hdr->fileList = hdr->linkList = hdr->md5list = NULL; 01000 hdr->uids = hdr->gids = hdr->mtimes = hdr->fileSizes = NULL; 01001 hdr->modes = hdr->rdevs = NULL; 01002 return hdr; 01003 } 01004 01005 Header hdrGetHeader(hdrObject * s) 01006 { 01007 return s->h; 01008 } 01009 01012 PyObject * hdrLoad(PyObject * self, PyObject * args, PyObject * kwds) 01013 { 01014 hdrObject * hdr; 01015 char * copy = NULL; 01016 char * obj; 01017 Header h; 01018 int len; 01019 char * kwlist[] = {"headers", NULL}; 01020 01021 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwlist, &obj, &len)) 01022 return NULL; 01023 01024 /* malloc is needed to avoid surprises from data swab in headerLoad(). */ 01025 copy = malloc(len); 01026 if (copy == NULL) { 01027 PyErr_SetString(pyrpmError, "out of memory"); 01028 return NULL; 01029 } 01030 memcpy (copy, obj, len); 01031 01032 h = headerLoad(copy); 01033 if (!h) { 01034 PyErr_SetString(pyrpmError, "bad header"); 01035 return NULL; 01036 } 01037 headerAllocated(h); 01038 compressFilelist (h); 01039 providePackageNVR (h); 01040 01041 hdr = hdr_Wrap(h); 01042 h = headerFree(h); /* XXX ref held by hdr */ 01043 01044 return (PyObject *) hdr; 01045 } 01046 01049 PyObject * rpmReadHeaders (FD_t fd) 01050 { 01051 PyObject * list; 01052 Header h; 01053 hdrObject * hdr; 01054 01055 if (!fd) { 01056 PyErr_SetFromErrno(pyrpmError); 01057 return NULL; 01058 } 01059 01060 list = PyList_New(0); 01061 Py_BEGIN_ALLOW_THREADS 01062 h = headerRead(fd, HEADER_MAGIC_YES); 01063 Py_END_ALLOW_THREADS 01064 01065 while (h) { 01066 compressFilelist(h); 01067 providePackageNVR(h); 01068 hdr = hdr_Wrap(h); 01069 if (PyList_Append(list, (PyObject *) hdr)) { 01070 Py_DECREF(list); 01071 Py_DECREF(hdr); 01072 return NULL; 01073 } 01074 Py_DECREF(hdr); 01075 01076 h = headerFree(h); /* XXX ref held by hdr */ 01077 01078 Py_BEGIN_ALLOW_THREADS 01079 h = headerRead(fd, HEADER_MAGIC_YES); 01080 Py_END_ALLOW_THREADS 01081 } 01082 01083 return list; 01084 } 01085 01088 PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args, PyObject * kwds) 01089 { 01090 FD_t fd; 01091 int fileno; 01092 PyObject * list; 01093 char * kwlist[] = {"fd", NULL}; 01094 01095 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno)) 01096 return NULL; 01097 01098 fd = fdDup(fileno); 01099 01100 list = rpmReadHeaders (fd); 01101 Fclose(fd); 01102 01103 return list; 01104 } 01105 01108 PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args, PyObject *kwds) 01109 { 01110 char * filespec; 01111 FD_t fd; 01112 PyObject * list; 01113 char * kwlist[] = {"file", NULL}; 01114 01115 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &filespec)) 01116 return NULL; 01117 01118 fd = Fopen(filespec, "r.fdio"); 01119 01120 if (!fd) { 01121 PyErr_SetFromErrno(pyrpmError); 01122 return NULL; 01123 } 01124 01125 list = rpmReadHeaders (fd); 01126 Fclose(fd); 01127 01128 return list; 01129 } 01130 01135 int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag) 01136 { 01137 Header h; 01138 HeaderIterator hi; 01139 int_32 * newMatch; 01140 int_32 * oldMatch; 01141 hdrObject * hdr; 01142 int count = 0; 01143 int type, c, tag; 01144 void * p; 01145 01146 Py_BEGIN_ALLOW_THREADS 01147 h = headerRead(fd, HEADER_MAGIC_YES); 01148 Py_END_ALLOW_THREADS 01149 01150 while (h) { 01151 if (!headerGetEntry(h, matchTag, NULL, &newMatch, NULL)) { 01152 PyErr_SetString(pyrpmError, "match tag missing in new header"); 01153 return 1; 01154 } 01155 01156 hdr = (hdrObject *) PyList_GetItem(list, count++); 01157 if (!hdr) return 1; 01158 01159 if (!headerGetEntry(hdr->h, matchTag, NULL, &oldMatch, NULL)) { 01160 PyErr_SetString(pyrpmError, "match tag missing in new header"); 01161 return 1; 01162 } 01163 01164 if (*newMatch != *oldMatch) { 01165 PyErr_SetString(pyrpmError, "match tag mismatch"); 01166 return 1; 01167 } 01168 01169 hdr->md5list = _free(hdr->md5list); 01170 hdr->fileList = _free(hdr->fileList); 01171 hdr->linkList = _free(hdr->linkList); 01172 01173 for (hi = headerInitIterator(h); 01174 headerNextIterator(hi, &tag, &type, (void *) &p, &c); 01175 p = headerFreeData(p, type)) 01176 { 01177 /* could be dupes */ 01178 headerRemoveEntry(hdr->h, tag); 01179 headerAddEntry(hdr->h, tag, type, p, c); 01180 } 01181 01182 headerFreeIterator(hi); 01183 h = headerFree(h); 01184 01185 Py_BEGIN_ALLOW_THREADS 01186 h = headerRead(fd, HEADER_MAGIC_YES); 01187 Py_END_ALLOW_THREADS 01188 } 01189 01190 return 0; 01191 } 01192 01193 PyObject * 01194 rpmMergeHeadersFromFD(PyObject * self, PyObject * args, PyObject * kwds) 01195 { 01196 FD_t fd; 01197 int fileno; 01198 PyObject * list; 01199 int rc; 01200 int matchTag; 01201 char * kwlist[] = {"list", "fd", "matchTag", NULL}; 01202 01203 if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oii", kwlist, &list, 01204 &fileno, &matchTag)) 01205 return NULL; 01206 01207 if (!PyList_Check(list)) { 01208 PyErr_SetString(PyExc_TypeError, "first parameter must be a list"); 01209 return NULL; 01210 } 01211 01212 fd = fdDup(fileno); 01213 01214 rc = rpmMergeHeaders (list, fd, matchTag); 01215 Fclose(fd); 01216 01217 if (rc) { 01218 return NULL; 01219 } 01220 01221 Py_INCREF(Py_None); 01222 return Py_None; 01223 } 01224 01227 PyObject * 01228 rpmSingleHeaderFromFD(PyObject * self, PyObject * args, PyObject * kwds) 01229 { 01230 FD_t fd; 01231 int fileno; 01232 off_t offset; 01233 PyObject * tuple; 01234 Header h; 01235 char * kwlist[] = {"fd", NULL}; 01236 01237 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &fileno)) 01238 return NULL; 01239 01240 offset = lseek(fileno, 0, SEEK_CUR); 01241 01242 fd = fdDup(fileno); 01243 01244 if (!fd) { 01245 PyErr_SetFromErrno(pyrpmError); 01246 return NULL; 01247 } 01248 01249 Py_BEGIN_ALLOW_THREADS 01250 h = headerRead(fd, HEADER_MAGIC_YES); 01251 Py_END_ALLOW_THREADS 01252 01253 Fclose(fd); 01254 01255 tuple = PyTuple_New(2); 01256 01257 if (h && tuple) { 01258 PyTuple_SET_ITEM(tuple, 0, (PyObject *) hdr_Wrap(h)); 01259 PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(offset)); 01260 h = headerFree(h); 01261 } else { 01262 Py_INCREF(Py_None); 01263 Py_INCREF(Py_None); 01264 PyTuple_SET_ITEM(tuple, 0, Py_None); 01265 PyTuple_SET_ITEM(tuple, 1, Py_None); 01266 } 01267 01268 return tuple; 01269 } 01270 01273 PyObject * versionCompare (PyObject * self, PyObject * args, PyObject * kwds) 01274 { 01275 hdrObject * h1, * h2; 01276 char * kwlist[] = {"version0", "version1", NULL}; 01277 01278 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!", kwlist, &hdr_Type, 01279 &h1, &hdr_Type, &h2)) 01280 return NULL; 01281 01282 return Py_BuildValue("i", hdr_compare(h1, h2)); 01283 } 01284 01285 PyObject * labelCompare (PyObject * self, PyObject * args) 01286 { 01287 EVR_t A = memset(alloca(sizeof(*A)), 0, sizeof(*A)); 01288 EVR_t B = memset(alloca(sizeof(*B)), 0, sizeof(*B)); 01289 int rc; 01290 01291 if (!PyArg_ParseTuple(args, "(zzz)(zzz)", 01292 &A->E, &A->V, &A->R, &B->E, &B->V, &B->R)) 01293 return NULL; 01294 01295 if (A->E == NULL) A->E = "0"; 01296 if (B->E == NULL) B->E = "0"; 01297 if (A->V == NULL) A->E = ""; 01298 if (B->V == NULL) B->E = ""; 01299 if (A->R == NULL) A->E = ""; 01300 if (B->R == NULL) B->E = ""; 01301 01302 rc = rpmEVRcompare(A, B); 01303 01304 return Py_BuildValue("i", rc); 01305 }