/** * Return exit code from running verify script from header. * @todo malloc/free/refcount handling is fishy here. * @param qva parsed query/verify options * @param ts transaction set * @param h header * @param scriptFd file handle to use for stderr (or NULL) * @return 0 on success */ static int rpmVerifyScript(QVA_t qva, rpmts ts, Header h, FD_t scriptFd) { rpmpsm psm = NULL; rpmte te = NULL; int rc = 0; /* fake up a erasure transaction element */ rc = rpmtsAddEraseElement(ts, h, -1); te = rpmtsElement(ts, 0); rpmteOpen(te, ts, 0); if (scriptFd != NULL) rpmtsSetScriptFd(ts, scriptFd); /* create psm to run the script */ psm = rpmpsmNew(ts, te); rpmpsmScriptStage(psm, RPMTAG_VERIFYSCRIPT, RPMTAG_VERIFYSCRIPTPROG); rc = rpmpsmStage(psm, PSM_SCRIPT); psm = rpmpsmFree(psm); if (scriptFd != NULL) rpmtsSetScriptFd(ts, NULL); /* clean up our fake transaction bits */ rpmteClose(te, ts, 0); rpmtsEmpty(ts); return rc; }
int rpmErase(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_const_t argv) { char * const * arg; char *qfmt = NULL; int numFailed = 0; int numPackages = 0; rpmVSFlags vsflags, ovsflags; if (argv == NULL) return 0; vsflags = setvsFlags(ia); ovsflags = rpmtsSetVSFlags(ts, vsflags); (void) rpmtsSetFlags(ts, ia->transFlags); setNotifyFlag(ia, ts); qfmt = rpmExpand("%{?_query_all_fmt}\n", NULL); for (arg = argv; *arg; arg++) { rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMDBI_LABEL, *arg, 0); int matches = rpmdbGetIteratorCount(mi); int erasing = 1; if (! matches) { rpmlog(RPMLOG_ERR, _("package %s is not installed\n"), *arg); numFailed++; } else { Header h; /* XXX iterator owns the reference */ if (matches > 1 && !(ia->installInterfaceFlags & UNINSTALL_ALLMATCHES)) { rpmlog(RPMLOG_ERR, _("\"%s\" specifies multiple packages:\n"), *arg); numFailed++; erasing = 0; } while ((h = rpmdbNextIterator(mi)) != NULL) { if (erasing) { (void) rpmtsAddEraseElement(ts, h, -1); numPackages++; } else { char *nevra = headerFormat(h, qfmt, NULL); rpmlog(RPMLOG_NOTICE, " %s", nevra); free(nevra); } } } rpmdbFreeIterator(mi); } free(qfmt); if (numFailed) goto exit; numFailed = rpmcliTransaction(ts, ia, numPackages); exit: rpmtsEmpty(ts); rpmtsSetVSFlags(ts, ovsflags); return numFailed; }
/* * Add a delete operation to the transaction * @param [String, Package, Dependency] pkg Package to delete */ VALUE rpm_transaction_delete(VALUE trans, VALUE pkg) { VALUE db; VALUE mi; #if RPM_VERSION_CODE < RPM_VERSION(4,9,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0) db = rb_ivar_get(trans, id_db); if (TYPE(pkg) == T_STRING) mi = rpm_db_init_iterator(db, INT2NUM(RPMDBI_LABEL), pkg); else if (rb_obj_is_kind_of(pkg, rpm_cPackage) != Qfalse) { VALUE sigmd5 = rpm_package_aref(pkg,INT2NUM(RPMTAG_SIGMD5)); if (sigmd5 != Qnil){ mi = rpm_db_init_iterator(db, INT2NUM(RPMTAG_SIGMD5), sigmd5); }else{ VALUE name = rpm_package_aref(pkg,INT2NUM(RPMDBI_LABEL)); mi = rpm_db_init_iterator(db, INT2NUM(RPMDBI_LABEL), name); } } else if ( rb_obj_is_kind_of(pkg, rpm_cDependency) ==Qfalse && rb_respond_to(pkg,rb_intern("name")) && rb_respond_to(pkg,rb_intern("version"))){ mi = rpm_db_init_iterator(db, INT2NUM(RPMDBI_LABEL),rb_funcall(pkg,rb_intern("name"),0)); rpm_mi_set_iterator_version(mi,rb_funcall(pkg,rb_intern("version"),0)); } else rb_raise(rb_eTypeError, "illegal argument type"); #else if (TYPE(pkg) == T_STRING) mi = rpm_transaction_init_iterator(trans, INT2NUM(RPMDBI_LABEL), pkg); else if (rb_obj_is_kind_of(pkg, rpm_cPackage) != Qfalse) { VALUE sigmd5 = rpm_package_aref(pkg,INT2NUM(RPMTAG_SIGMD5)); if (sigmd5 != Qnil){ mi = rpm_transaction_init_iterator(trans, INT2NUM(RPMTAG_SIGMD5), sigmd5); }else{ VALUE name = rpm_package_aref(pkg,INT2NUM(RPMDBI_LABEL)); mi = rpm_transaction_init_iterator(trans, INT2NUM(RPMDBI_LABEL), name); } } else if ( rb_obj_is_kind_of(pkg, rpm_cDependency) ==Qfalse && rb_respond_to(pkg,rb_intern("name")) && rb_respond_to(pkg,rb_intern("version"))){ mi = rpm_transaction_init_iterator(trans, INT2NUM(RPMDBI_LABEL),rb_funcall(pkg,rb_intern("name"),0)); rpm_mi_set_iterator_version(mi,rb_funcall(pkg,rb_intern("version"),0)); } else rb_raise(rb_eTypeError, "illegal argument type"); #endif VALUE p; while (!NIL_P(p = rpm_mi_next_iterator(mi))) { VALUE off = rpm_mi_get_iterator_offset(mi); if (!NIL_P(off)){ #if RPM_VERSION_CODE < RPM_VERSION(4,1,0) rpmtransRemovePackage(RPM_TRANSACTION(trans), NUM2INT(off)); #else rpmtsAddEraseElement(RPM_TRANSACTION(trans), RPM_HEADER(p), NUM2INT(off)); #endif } } return Qnil; }
static PyObject * rpmts_AddErase(rpmtsObject * s, PyObject * args) { Header h; if (!PyArg_ParseTuple(args, "O&:AddErase", hdrFromPyObject, &h)) return NULL; return PyBool_FromLong(rpmtsAddEraseElement(s->ts, h, -1) == 0); }
int add_for_erase(rpmts ts, char *name) { Header hdr; rpmdbMatchIterator mi; int rc = 0; /* Locate the package and add for erasure */ mi = rpmtsInitIterator(ts, (rpmTag)RPMDBI_LABEL, name, 0); while ((hdr = rpmdbNextIterator(mi)) != NULL) { int recOffset = rpmdbGetIteratorOffset(mi); if (recOffset) { rc = rpmtsAddEraseElement(ts, hdr, recOffset); if (rc) printf("Error adding %s to transaction", name); } } mi = rpmdbFreeIterator(mi); return rc; }
int ssds_add_to_erase(rpmts ts, char *pkg){ Header hdr; rpmdbMatchIterator mi; int rc = OK; /* Locate the package and add for erasure */ mi = rpmtsInitIterator(ts, (rpmTag)RPMDBI_LABEL, pkg, 0); while ((hdr = rpmdbNextIterator(mi)) != NULL) { int recOffset = rpmdbGetIteratorOffset(mi); if (recOffset) { rc = rpmtsAddEraseElement(ts, hdr, recOffset); if (rc) ssds_log(logERROR, "Error adding %s to transaction.\n", pkg); } } mi = rpmdbFreeIterator(mi); return rc; }
uint32_t TDNFTransAddErasePkg( PTDNFRPMTS pTS, HyPackage hPkg ) { uint32_t dwError = 0; Header pRpmHeader = NULL; rpmdbMatchIterator pIterator = NULL; const char* pszName = NULL; unsigned int nOffset = 0; if(!pTS || !hPkg) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } pszName = hy_package_get_name(hPkg); pIterator = rpmtsInitIterator(pTS->pTS, (rpmTag)RPMDBI_LABEL, pszName, 0); while ((pRpmHeader = rpmdbNextIterator(pIterator)) != NULL) { nOffset = rpmdbGetIteratorOffset(pIterator); if(nOffset) { dwError = rpmtsAddEraseElement(pTS->pTS, pRpmHeader, nOffset); BAIL_ON_TDNF_ERROR(dwError); } } cleanup: if(pIterator) { rpmdbFreeIterator(pIterator); } return dwError; error: goto cleanup; }
/* --- Object methods */ static JSBool rpmts_add(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmtsClass, NULL); rpmts ts = ptr; char * pkgN = 0; JSBool ok = JS_FALSE; _METHOD_DEBUG_ENTRY(_debug); if (!(ok = JS_ConvertArguments(cx, argc, argv, "s", &pkgN))) goto exit; if (pkgN != NULL) { rpmmi mi; Header h; int upgrade = 0; int xx; switch (*pkgN) { case '-': pkgN++; upgrade = -1; break; case '+': pkgN++; upgrade = 1; break; default: upgrade = 1; break; } mi = rpmtsInitIterator(ts, RPMTAG_NVRA, pkgN, 0); while ((h = rpmmiNext(mi)) != NULL) { xx = (upgrade >= 0) ? rpmtsAddInstallElement(ts, h, (fnpyKey)pkgN, upgrade, NULL) : rpmtsAddEraseElement(ts, h, rpmmiInstance(mi)); break; } mi = rpmmiFree(mi); } ok = JS_TRUE; exit: *rval = BOOLEAN_TO_JSVAL(ok); /* XXX return error */ return ok; }
int rpmErase(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_const_t argv) { char * const * arg; char *qfmt = NULL; int numFailed = 0; int stopUninstall = 0; int numPackages = 0; rpmVSFlags vsflags, ovsflags; rpmps ps; if (argv == NULL) return 0; vsflags = rpmExpandNumeric("%{?_vsflags_erase}"); if (ia->qva_flags & VERIFY_DIGEST) vsflags |= _RPMVSF_NODIGESTS; if (ia->qva_flags & VERIFY_SIGNATURE) vsflags |= _RPMVSF_NOSIGNATURES; if (ia->qva_flags & VERIFY_HDRCHK) vsflags |= RPMVSF_NOHDRCHK; ovsflags = rpmtsSetVSFlags(ts, vsflags); /* XXX suggest mechanism only meaningful when installing */ ia->transFlags |= RPMTRANS_FLAG_NOSUGGEST; (void) rpmtsSetFlags(ts, ia->transFlags); #ifdef NOTYET /* XXX no callbacks on erase yet */ { int notifyFlags, xx; notifyFlags = ia->eraseInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 ); xx = rpmtsSetNotifyCallback(ts, rpmShowProgress, (void *) ((long)notifyFlags)); } #endif qfmt = rpmExpand("%{?_query_all_fmt}\n", NULL); for (arg = argv; *arg; arg++) { rpmdbMatchIterator mi; int matches = 0; int erasing = 1; /* Iterator count isn't reliable with labels, count manually... */ mi = rpmtsInitIterator(ts, RPMDBI_LABEL, *arg, 0); while (rpmdbNextIterator(mi) != NULL) { matches++; } rpmdbFreeIterator(mi); if (! matches) { rpmlog(RPMLOG_ERR, _("package %s is not installed\n"), *arg); numFailed++; } else { Header h; /* XXX iterator owns the reference */ if (matches > 1 && !(ia->eraseInterfaceFlags & UNINSTALL_ALLMATCHES)) { rpmlog(RPMLOG_ERR, _("\"%s\" specifies multiple packages:\n"), *arg); numFailed++; erasing = 0; } mi = rpmtsInitIterator(ts, RPMDBI_LABEL, *arg, 0); while ((h = rpmdbNextIterator(mi)) != NULL) { if (erasing) { (void) rpmtsAddEraseElement(ts, h, -1); numPackages++; } else { char *nevra = headerFormat(h, qfmt, NULL); rpmlog(RPMLOG_NOTICE, " %s", nevra); free(nevra); } } mi = rpmdbFreeIterator(mi); } } free(qfmt); if (numFailed) goto exit; if (!(ia->eraseInterfaceFlags & UNINSTALL_NODEPS)) { if (rpmtsCheck(ts)) { numFailed = numPackages; stopUninstall = 1; } ps = rpmtsProblems(ts); if (!stopUninstall && rpmpsNumProblems(ps) > 0) { rpmlog(RPMLOG_ERR, _("Failed dependencies:\n")); rpmpsPrint(NULL, ps); numFailed += numPackages; stopUninstall = 1; } ps = rpmpsFree(ps); } if (!stopUninstall && !(ia->installInterfaceFlags & INSTALL_NOORDER)) { if (rpmtsOrder(ts)) { numFailed += numPackages; stopUninstall = 1; } } if (numPackages && !stopUninstall) { (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_REVERSE)); /* Drop added/available package indices and dependency sets. */ rpmtsClean(ts); numPackages = rpmtsRun(ts, NULL, ia->probFilter & (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES)); ps = rpmtsProblems(ts); if (rpmpsNumProblems(ps) > 0) rpmpsPrint(NULL, ps); numFailed += numPackages; stopUninstall = 1; ps = rpmpsFree(ps); } exit: rpmtsEmpty(ts); return numFailed; }
/** * Check installed package dependencies for problems. * @param qva parsed query/verify options * @param ts transaction set * @param h header * @return number of problems found (0 for no problems) */ static int verifyDependencies(/*@unused@*/ QVA_t qva, rpmts ts, Header h) /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ /*@modifies ts, h, rpmGlobalMacroContext, fileSystem, internalState @*/ { #ifdef NOTYET uint32_t hdrNum = headerGetInstance(h); #endif rpmps ps; int rc = 0; /* assume no problems */ int xx; rpmtsEmpty(ts); #ifdef NOTYET if (hdrNum > 0) (void) rpmtsAddEraseElement(ts, h, hdrNum); else #endif (void) rpmtsAddInstallElement(ts, h, headerGetOrigin(h), 0, NULL); xx = rpmtsCheck(ts); ps = rpmtsProblems(ts); if (rpmpsNumProblems(ps) > 0) { const char * altNEVR; const char * pkgNEVR = NULL; rpmpsi psi; rpmProblem prob; char * t, * te; int nb = 512; psi = rpmpsInitIterator(ps); while (rpmpsNextIterator(psi) >= 0) { prob = rpmpsProblem(psi); if (pkgNEVR == NULL) pkgNEVR = rpmProblemGetPkgNEVR(prob); altNEVR = rpmProblemGetAltNEVR(prob); assert(altNEVR != NULL); if (altNEVR[0] == 'R' && altNEVR[1] == ' ') nb += sizeof("\tRequires: ")-1; if (altNEVR[0] == 'C' && altNEVR[1] == ' ') nb += sizeof("\tConflicts: ")-1; nb += strlen(altNEVR+2) + sizeof("\n") - 1; } psi = rpmpsFreeIterator(psi); te = t = alloca(nb); *te = '\0'; sprintf(te, _("Unsatisfied dependencies for %s:\n"), pkgNEVR); te += strlen(te); psi = rpmpsInitIterator(ps); while (rpmpsNextIterator(psi) >= 0) { prob = rpmpsProblem(psi); if ((altNEVR = rpmProblemGetAltNEVR(prob)) == NULL) altNEVR = "? ?altNEVR?"; if (altNEVR[0] == 'R' && altNEVR[1] == ' ') te = stpcpy(te, "\tRequires: "); if (altNEVR[0] == 'C' && altNEVR[1] == ' ') te = stpcpy(te, "\tConflicts: "); te = stpcpy( stpcpy(te, altNEVR+2), "\n"); rc++; } psi = rpmpsFreeIterator(psi); if (te > t) { *te++ = '\n'; *te = '\0'; rpmlog(RPMLOG_NOTICE, "%s", t); te = t; *t = '\0'; } } ps = rpmpsFree(ps); rpmtsEmpty(ts); return rc; }
/************************************************************************* * FUNCTION : RPMTransaction_Set::Install_or_remove * * ARGUMENTS : RPM headers to add * * RETURNS : TCL_OK or TCL_ERROR * * EXCEPTIONS : none * * PURPOSE : Add an RPM to an install set * *************************************************************************/ int RPMTransaction_Set::Install_or_remove(Tcl_Obj *name,Install_mode mode) { // Is this a list? if so, recurse through it Tcl_ObjType *listtype = Tcl_GetObjType("list"); if (name->typePtr == listtype) { // OK, go recursive on this int count = 0; if (Tcl_ListObjLength(_interp,name,&count) != TCL_OK) return TCL_ERROR; for (int i = 0; i < count; ++i) { Tcl_Obj *element = 0; if (Tcl_ListObjIndex(_interp,name,i,&element) != TCL_OK) { return TCL_ERROR; } if (Install_or_remove(element,mode) != TCL_OK) return TCL_ERROR; } return TCL_OK; } // OK, so not a list. Try to make it into an RPM header if (Tcl_ConvertToType(_interp,name,&RPMHeader_Obj::mytype) != TCL_OK) return TCL_ERROR; RPMHeader_Obj *header = ( RPMHeader_Obj *)(name->internalRep.otherValuePtr); \ // Unfortunately, the transaction set API does not give us a way to know when // it has freed a fnpyKey key object. In order to clean these up, we will create // a TCL list object of all headers we use for this purpose, and clean it as needed. Tcl_Obj *hdr_copy = header->Get_obj(); Tcl_IncrRefCount(hdr_copy); int error = 0; switch (mode) { case INSTALL: error = rpmtsAddInstallElement(transaction,*header,header,0,0); break; case UPGRADE: error = rpmtsAddInstallElement(transaction,*header,header,1,0); break; case REMOVE: error = rpmtsAddEraseElement(transaction,*header,header->DB_entry()); break; } switch (error) { case 0: // Record that we have created an entry on the list header_list = Grow_list(header_list,hdr_copy); return TCL_OK; case 1: header->Dec_refcount(); return Error("Error adding %s: %s\n",Tcl_GetStringFromObj(name,0),rpmErrorString()); case 2: header->Dec_refcount(); return Error("Error adding %s: needs capabilities %s\n",Tcl_GetStringFromObj(name,0),rpmErrorString()); default: header->Dec_refcount(); return Error("Unknown RPMlib error %d adding %s: needs capabilities %s\n",error,Tcl_GetStringFromObj(name,0),rpmErrorString()); } return TCL_OK; }
rpmRC rpmgiNext(/*@null@*/ rpmgi gi) { char hnum[32]; rpmRC rpmrc = RPMRC_NOTFOUND; int xx; if (gi == NULL) return rpmrc; if (_rpmgi_debug) fprintf(stderr, "--> %s(%p) tag %s\n", __FUNCTION__, gi, tagName(gi->tag)); /* Free header from previous iteration. */ (void)headerFree(gi->h); gi->h = NULL; gi->hdrPath = _free(gi->hdrPath); hnum[0] = '\0'; if (++gi->i >= 0) switch (gi->tag) { default: if (!gi->active) { nextkey: rpmrc = rpmgiLoadNextKey(gi); if (rpmrc != RPMRC_OK) goto enditer; rpmrc = rpmgiInitFilter(gi); if (rpmrc != RPMRC_OK || gi->mi == NULL) { gi->mi = rpmmiFree(gi->mi); /* XXX unnecessary */ gi->i++; goto nextkey; } rpmrc = RPMRC_NOTFOUND; /* XXX hack */ gi->active = 1; } if (gi->mi != NULL) { /* XXX unnecessary */ Header h = rpmmiNext(gi->mi); if (h != NULL) { if (!(gi->flags & RPMGI_NOHEADER)) gi->h = headerLink(h); /* XXX use h->origin instead. */ sprintf(hnum, "%u", (unsigned)rpmmiInstance(gi->mi)); gi->hdrPath = rpmExpand("rpmdb h# ", hnum, NULL); rpmrc = RPMRC_OK; /* XXX header reference held by iterator, so no headerFree */ } } if (rpmrc != RPMRC_OK) { gi->mi = rpmmiFree(gi->mi); goto nextkey; } break; case RPMDBI_PACKAGES: if (!gi->active) { rpmrc = rpmgiInitFilter(gi); if (rpmrc != RPMRC_OK) { gi->mi = rpmmiFree(gi->mi); /* XXX unnecessary */ goto enditer; } rpmrc = RPMRC_NOTFOUND; /* XXX hack */ gi->active = 1; } if (gi->mi != NULL) { /* XXX unnecessary */ Header h = rpmmiNext(gi->mi); if (h != NULL) { if (!(gi->flags & RPMGI_NOHEADER)) gi->h = headerLink(h); /* XXX use h->origin instead. */ sprintf(hnum, "%u", (unsigned)rpmmiInstance(gi->mi)); gi->hdrPath = rpmExpand("rpmdb h# ", hnum, NULL); rpmrc = RPMRC_OK; /* XXX header reference held by iterator, so no headerFree */ } } if (rpmrc != RPMRC_OK) { gi->mi = rpmmiFree(gi->mi); goto enditer; } break; case RPMDBI_REMOVED: case RPMDBI_ADDED: { rpmte p; int teType = 0; const char * teTypeString = NULL; if (!gi->active) { gi->tsi = rpmtsiInit(gi->ts); gi->active = 1; } if ((p = rpmtsiNext(gi->tsi, teType)) != NULL) { Header h = rpmteHeader(p); if (h != NULL) if (!(gi->flags & RPMGI_NOHEADER)) { gi->h = headerLink(h); switch(rpmteType(p)) { case TR_ADDED: teTypeString = "+++"; /*@switchbreak@*/break; case TR_REMOVED: teTypeString = "---"; /*@switchbreak@*/break; } sprintf(hnum, "%u", (unsigned)gi->i); gi->hdrPath = rpmExpand("%s h# ", teTypeString, hnum, NULL); rpmrc = RPMRC_OK; (void)headerFree(h); h = NULL; } } if (rpmrc != RPMRC_OK) { gi->tsi = rpmtsiFree(gi->tsi); goto enditer; } } break; case RPMDBI_HDLIST: if (!gi->active) { const char * path = rpmExpand("%{?_query_hdlist_path}", NULL); if (path == NULL || *path == '\0') { path = _free(path); path = rpmExpand(_query_hdlist_path, NULL); } gi->fd = rpmgiOpen(path, "rm%{?_rpmgio}"); gi->active = 1; path = _free(path); } if (gi->fd != NULL) { Header h = NULL; const char item[] = "Header"; const char * msg = NULL; /*@+voidabstract@*/ rpmrc = rpmpkgRead(item, gi->fd, &h, &msg); /*@=voidabstract@*/ switch(rpmrc) { default: rpmlog(RPMLOG_ERR, "%s: %s: %s\n", "rpmpkgRead", item, msg); case RPMRC_NOTFOUND: h = NULL; case RPMRC_OK: break; } msg = _free(msg); if (h != NULL) { if (!(gi->flags & RPMGI_NOHEADER)) gi->h = headerLink(h); sprintf(hnum, "%u", (unsigned)gi->i); gi->hdrPath = rpmExpand("hdlist h# ", hnum, NULL); rpmrc = RPMRC_OK; (void)headerFree(h); h = NULL; } } if (rpmrc != RPMRC_OK) { if (gi->fd != NULL) (void) Fclose(gi->fd); gi->fd = NULL; goto enditer; } break; case RPMDBI_ARGLIST: /* XXX gi->active initialize? */ if (_rpmgi_debug < 0) fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->argv, gi->i, gi->argv[gi->i]); /* Read next header, lazily expanding manifests as found. */ rpmrc = rpmgiLoadReadHeader(gi); if (rpmrc != RPMRC_OK) /* XXX check this */ goto enditer; gi->hdrPath = xstrdup(gi->argv[gi->i]); break; case RPMDBI_FTSWALK: if (gi->argv == NULL || gi->argv[0] == NULL) /* HACK */ goto enditer; if (!gi->active) { gi->ftsp = Fts_open((char *const *)gi->argv, gi->ftsOpts, NULL); /* XXX NULL with open(2)/malloc(3) errno set */ gi->active = 1; } /* Read next header, lazily walking file tree. */ rpmrc = rpmgiWalkReadHeader(gi); if (rpmrc != RPMRC_OK) { xx = Fts_close(gi->ftsp); gi->ftsp = NULL; goto enditer; } if (gi->fts != NULL) gi->hdrPath = xstrdup(gi->fts->fts_path); break; } if ((gi->flags & RPMGI_TSADD) && gi->h != NULL) { /* XXX rpmgi hack: Save header in transaction element. */ if (gi->flags & RPMGI_ERASING) { uint32_t hdrNum = headerGetInstance(gi->h); xx = rpmtsAddEraseElement(gi->ts, gi->h, hdrNum); } else xx = rpmtsAddInstallElement(gi->ts, gi->h, (fnpyKey)gi->hdrPath, 2, NULL); } goto exit; enditer: if (gi->flags & RPMGI_TSORDER) { rpmts ts = gi->ts; /* Block access to indices used for depsolving. */ if (!(gi->flags & RPMGI_ERASING)) { (void) rpmtsSetGoal(ts, TSM_INSTALL); xx = rpmdbBlockDBI(rpmtsGetRdb(ts), -RPMDBI_DEPCACHE); xx = rpmdbBlockDBI(rpmtsGetRdb(ts), -RPMTAG_BASENAMES); xx = rpmdbBlockDBI(rpmtsGetRdb(ts), -RPMTAG_PROVIDENAME); } else { (void) rpmtsSetGoal(ts, TSM_ERASE); } /* XXX query/verify will need the glop added to a buffer instead. */ xx = rpmcliInstallCheck(ts); xx = rpmcliInstallSuggests(ts); /* Permit access to indices used for depsolving. */ if (!(gi->flags & RPMGI_ERASING)) { xx = rpmdbBlockDBI(rpmtsGetRdb(ts), RPMTAG_PROVIDENAME); xx = rpmdbBlockDBI(rpmtsGetRdb(ts), RPMTAG_BASENAMES); xx = rpmdbBlockDBI(rpmtsGetRdb(ts), RPMDBI_DEPCACHE); } /* XXX Display dependency loops with rpm -qvT. */ if (rpmIsVerbose()) (void) rpmtsSetDFlags(ts, (rpmtsDFlags(ts) | RPMDEPS_FLAG_DEPLOOPS)); xx = (*gi->tsOrder) (ts); /* XXX hackery alert! */ gi->tag = (!(gi->flags & RPMGI_ERASING) ? RPMDBI_ADDED : RPMDBI_REMOVED); gi->flags &= ~(RPMGI_TSADD|RPMGI_TSORDER); } (void)headerFree(gi->h); gi->h = NULL; gi->hdrPath = _free(gi->hdrPath); gi->i = -1; gi->active = 0; exit: if (_rpmgi_debug) fprintf(stderr, "<-- %s(%p) rc %d\n", __FUNCTION__, gi, rpmrc); return rpmrc; }