|
|
2ff057 |
/** \ingroup rpmts payload
|
|
|
2ff057 |
* \file lib/psm.c
|
|
|
2ff057 |
* Package state machine to handle a package from a transaction set.
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
|
|
|
2ff057 |
#include "system.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
#include <errno.h>
|
|
|
2ff057 |
|
|
|
2ff057 |
#include <rpm/rpmlib.h> /* rpmvercmp and others */
|
|
|
2ff057 |
#include <rpm/rpmmacro.h>
|
|
|
2ff057 |
#include <rpm/rpmds.h>
|
|
|
2ff057 |
#include <rpm/rpmts.h>
|
|
|
2ff057 |
#include <rpm/rpmfileutil.h>
|
|
|
2ff057 |
#include <rpm/rpmdb.h>
|
|
|
2ff057 |
#include <rpm/rpmlog.h>
|
|
|
2ff057 |
#include <rpm/rpmstring.h>
|
|
|
2ff057 |
#include <rpm/argv.h>
|
|
|
2ff057 |
|
|
|
2ff057 |
#include "lib/fsm.h" /* XXX CPIO_FOO/FSM_FOO constants */
|
|
|
2ff057 |
#include "lib/rpmchroot.h"
|
|
|
2ff057 |
#include "lib/rpmfi_internal.h" /* XXX replaced/states... */
|
|
|
2ff057 |
#include "lib/rpmte_internal.h" /* XXX internal apis */
|
|
|
2ff057 |
#include "lib/rpmdb_internal.h" /* rpmdbAdd/Remove */
|
|
|
2ff057 |
#include "lib/rpmts_internal.h" /* rpmtsPlugins() etc */
|
|
|
2ff057 |
#include "lib/rpmds_internal.h" /* rpmdsFilterTi() */
|
|
|
2ff057 |
#include "lib/rpmscript.h"
|
|
|
2ff057 |
#include "lib/misc.h"
|
|
|
2ff057 |
#include "lib/rpmtriggers.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
#include "lib/rpmplugins.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
#include "debug.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
struct rpmpsm_s {
|
|
|
2ff057 |
rpmts ts; /*!< transaction set */
|
|
|
2ff057 |
rpmte te; /*!< current transaction element */
|
|
|
2ff057 |
rpmfiles files; /*!< transaction element file info */
|
|
|
2ff057 |
int scriptArg; /*!< Scriptlet package arg. */
|
|
|
2ff057 |
int countCorrection; /*!< 0 if installing, -1 if removing. */
|
|
|
2ff057 |
rpmCallbackType what; /*!< Callback type. */
|
|
|
2ff057 |
rpm_loff_t amount; /*!< Callback amount. */
|
|
|
2ff057 |
rpm_loff_t total; /*!< Callback total. */
|
|
|
2ff057 |
|
|
|
2ff057 |
int nrefs; /*!< Reference count. */
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmpsm rpmpsmNew(rpmts ts, rpmte te, pkgGoal goal);
|
|
|
2ff057 |
static rpmRC rpmpsmUnpack(rpmpsm psm);
|
|
|
2ff057 |
static rpmpsm rpmpsmFree(rpmpsm psm);
|
|
|
2ff057 |
static const char * pkgGoalString(pkgGoal goal);
|
|
|
2ff057 |
|
|
|
2ff057 |
/**
|
|
|
2ff057 |
* Adjust file states in database for files shared with this package:
|
|
|
2ff057 |
* currently either "replaced" or "wrong color".
|
|
|
2ff057 |
* @param psm package state machine data
|
|
|
2ff057 |
* @return 0 always
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
static rpmRC markReplacedFiles(const rpmpsm psm)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
const rpmts ts = psm->ts;
|
|
|
2ff057 |
rpmfs fs = rpmteGetFileStates(psm->te);
|
|
|
2ff057 |
sharedFileInfo replaced = rpmfsGetReplaced(fs);
|
|
|
2ff057 |
sharedFileInfo sfi;
|
|
|
2ff057 |
rpmdbMatchIterator mi;
|
|
|
2ff057 |
Header h;
|
|
|
2ff057 |
unsigned int * offsets;
|
|
|
2ff057 |
unsigned int prev;
|
|
|
2ff057 |
unsigned int num;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!replaced)
|
|
|
2ff057 |
return RPMRC_OK;
|
|
|
2ff057 |
|
|
|
2ff057 |
num = prev = 0;
|
|
|
2ff057 |
for (sfi = replaced; sfi; sfi=rpmfsNextReplaced(fs, sfi)) {
|
|
|
2ff057 |
if (prev && prev == sfi->otherPkg)
|
|
|
2ff057 |
continue;
|
|
|
2ff057 |
prev = sfi->otherPkg;
|
|
|
2ff057 |
num++;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (num == 0)
|
|
|
2ff057 |
return RPMRC_OK;
|
|
|
2ff057 |
|
|
|
2ff057 |
offsets = xmalloc(num * sizeof(*offsets));
|
|
|
2ff057 |
offsets[0] = 0;
|
|
|
2ff057 |
num = prev = 0;
|
|
|
2ff057 |
for (sfi = replaced; sfi; sfi=rpmfsNextReplaced(fs, sfi)) {
|
|
|
2ff057 |
if (prev && prev == sfi->otherPkg)
|
|
|
2ff057 |
continue;
|
|
|
2ff057 |
prev = sfi->otherPkg;
|
|
|
2ff057 |
offsets[num++] = sfi->otherPkg;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
|
|
|
2ff057 |
rpmdbAppendIterator(mi, offsets, num);
|
|
|
2ff057 |
rpmdbSetIteratorRewrite(mi, 1);
|
|
|
2ff057 |
|
|
|
2ff057 |
sfi = replaced;
|
|
|
2ff057 |
while ((h = rpmdbNextIterator(mi)) != NULL) {
|
|
|
2ff057 |
int modified;
|
|
|
2ff057 |
struct rpmtd_s secStates;
|
|
|
2ff057 |
modified = 0;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!headerGet(h, RPMTAG_FILESTATES, &secStates, HEADERGET_MINMEM))
|
|
|
2ff057 |
continue;
|
|
|
2ff057 |
|
|
|
2ff057 |
prev = rpmdbGetIteratorOffset(mi);
|
|
|
2ff057 |
num = 0;
|
|
|
2ff057 |
while (sfi && sfi->otherPkg == prev) {
|
|
|
2ff057 |
int ix = rpmtdSetIndex(&secStates, sfi->otherFileNum);
|
|
|
2ff057 |
assert(ix != -1);
|
|
|
2ff057 |
|
|
|
2ff057 |
char *state = rpmtdGetChar(&secStates);
|
|
|
2ff057 |
if (state && *state != sfi->rstate) {
|
|
|
2ff057 |
*state = sfi->rstate;
|
|
|
2ff057 |
if (modified == 0) {
|
|
|
2ff057 |
/* Modified header will be rewritten. */
|
|
|
2ff057 |
modified = 1;
|
|
|
2ff057 |
rpmdbSetIteratorModified(mi, modified);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
num++;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
sfi=rpmfsNextReplaced(fs, sfi);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
rpmtdFreeData(&secStates);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
rpmdbFreeIterator(mi);
|
|
|
2ff057 |
free(offsets);
|
|
|
2ff057 |
|
|
|
2ff057 |
return RPMRC_OK;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpmlibDeps(Header h)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmds req = rpmdsInit(rpmdsNew(h, RPMTAG_REQUIRENAME, 0));
|
|
|
2ff057 |
rpmds rpmlib = NULL;
|
|
|
2ff057 |
rpmdsRpmlib(&rpmlib, NULL);
|
|
|
2ff057 |
int rc = 1;
|
|
|
2ff057 |
char *nvr = NULL;
|
|
|
2ff057 |
while (rpmdsNext(req) >= 0) {
|
|
|
2ff057 |
if (!(rpmdsFlags(req) & RPMSENSE_RPMLIB))
|
|
|
2ff057 |
continue;
|
|
|
2ff057 |
if (rpmdsSearch(rpmlib, req) < 0) {
|
|
|
2ff057 |
if (!nvr) {
|
|
|
2ff057 |
nvr = headerGetAsString(h, RPMTAG_NEVRA);
|
|
|
2ff057 |
rpmlog(RPMLOG_ERR, _("Missing rpmlib features for %s:\n"), nvr);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
rpmlog(RPMLOG_ERR, "\t%s\n", rpmdsDNEVR(req)+2);
|
|
|
2ff057 |
rc = 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
rpmdsFree(req);
|
|
|
2ff057 |
rpmdsFree(rpmlib);
|
|
|
2ff057 |
free(nvr);
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmRC rpmInstallSourcePackage(rpmts ts, FD_t fd,
|
|
|
2ff057 |
char ** specFilePtr, char ** cookie)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
Header h = NULL;
|
|
|
2ff057 |
rpmpsm psm = NULL;
|
|
|
2ff057 |
rpmte te = NULL;
|
|
|
2ff057 |
rpmRC rpmrc;
|
|
|
2ff057 |
int specix = -1;
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmrc = rpmReadPackageFile(ts, fd, NULL, &h);
|
|
|
2ff057 |
switch (rpmrc) {
|
|
|
2ff057 |
case RPMRC_NOTTRUSTED:
|
|
|
2ff057 |
case RPMRC_NOKEY:
|
|
|
2ff057 |
case RPMRC_OK:
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (h == NULL)
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmrc = RPMRC_FAIL; /* assume failure */
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!headerIsSource(h)) {
|
|
|
2ff057 |
rpmlog(RPMLOG_ERR, _("source package expected, binary found\n"));
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/* src.rpm install can require specific rpmlib features, check them */
|
|
|
2ff057 |
if (!rpmlibDeps(h))
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
|
|
|
2ff057 |
specix = headerFindSpec(h);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (specix < 0) {
|
|
|
2ff057 |
rpmlog(RPMLOG_ERR, _("source package contains no .spec file\n"));
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
if (rpmtsAddInstallElement(ts, h, NULL, 0, NULL)) {
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
te = rpmtsElement(ts, 0);
|
|
|
2ff057 |
if (te == NULL) { /* XXX can't happen */
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
rpmteSetFd(te, fd);
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmteSetHeader(te, h);
|
|
|
2ff057 |
|
|
|
2ff057 |
{
|
|
|
2ff057 |
/* set all files to be installed */
|
|
|
2ff057 |
rpmfs fs = rpmteGetFileStates(te);
|
|
|
2ff057 |
int fc = rpmfsFC(fs);
|
|
|
2ff057 |
for (int i = 0; i < fc; i++)
|
|
|
2ff057 |
rpmfsSetAction(fs, i, FA_CREATE);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
psm = rpmpsmNew(ts, te, PKG_INSTALL);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (rpmpsmUnpack(psm) == RPMRC_OK)
|
|
|
2ff057 |
rpmrc = RPMRC_OK;
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmpsmFree(psm);
|
|
|
2ff057 |
|
|
|
2ff057 |
exit:
|
|
|
2ff057 |
if (rpmrc == RPMRC_OK && specix >= 0) {
|
|
|
2ff057 |
if (cookie)
|
|
|
2ff057 |
*cookie = headerGetAsString(h, RPMTAG_COOKIE);
|
|
|
2ff057 |
if (specFilePtr) {
|
|
|
2ff057 |
rpmfiles files = rpmteFiles(te);
|
|
|
2ff057 |
*specFilePtr = rpmfilesFN(files, specix);
|
|
|
2ff057 |
rpmfilesFree(files);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/* XXX nuke the added package(s). */
|
|
|
2ff057 |
headerFree(h);
|
|
|
2ff057 |
rpmtsEmpty(ts);
|
|
|
2ff057 |
|
|
|
2ff057 |
return rpmrc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmRC runInstScript(rpmpsm psm, rpmTagVal scriptTag)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmRC rc = RPMRC_OK;
|
|
|
2ff057 |
struct rpmtd_s pfx;
|
|
|
2ff057 |
Header h = rpmteHeader(psm->te);
|
|
|
2ff057 |
rpmScript script = rpmScriptFromTag(h, scriptTag);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (script) {
|
|
|
2ff057 |
headerGet(h, RPMTAG_INSTPREFIXES, &pfx, HEADERGET_ALLOC|HEADERGET_ARGV);
|
|
|
2ff057 |
rc = runScript(psm->ts, psm->te, h, pfx.data, script, psm->scriptArg, -1);
|
|
|
2ff057 |
rpmtdFreeData(&pfx;;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmScriptFree(script);
|
|
|
2ff057 |
headerFree(h);
|
|
|
2ff057 |
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/**
|
|
|
2ff057 |
* Execute triggers.
|
|
|
2ff057 |
* @todo Trigger on any provides, not just package NVR.
|
|
|
2ff057 |
* @param ts transaction set
|
|
|
2ff057 |
* @param te transaction element
|
|
|
2ff057 |
* @param sense trigger type
|
|
|
2ff057 |
* @param sourceH header of trigger source
|
|
|
2ff057 |
* @param trigH header of triggered package
|
|
|
2ff057 |
* @param arg2
|
|
|
2ff057 |
* @param triggersAlreadyRun
|
|
|
2ff057 |
* @return
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
static rpmRC handleOneTrigger(rpmts ts, rpmte te, rpmsenseFlags sense,
|
|
|
2ff057 |
Header sourceH, Header trigH, int countCorrection,
|
|
|
2ff057 |
int arg2, unsigned char * triggersAlreadyRun)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmds trigger = rpmdsInit(rpmdsNew(trigH, RPMTAG_TRIGGERNAME, 0));
|
|
|
2ff057 |
struct rpmtd_s pfx;
|
|
|
2ff057 |
const char * sourceName = headerGetString(sourceH, RPMTAG_NAME);
|
|
|
2ff057 |
const char * triggerName = headerGetString(trigH, RPMTAG_NAME);
|
|
|
2ff057 |
rpmRC rc = RPMRC_OK;
|
|
|
2ff057 |
int i;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (trigger == NULL)
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
|
|
|
2ff057 |
headerGet(trigH, RPMTAG_INSTPREFIXES, &pfx, HEADERGET_ALLOC|HEADERGET_ARGV);
|
|
|
2ff057 |
(void) rpmdsSetNoPromote(trigger, 1);
|
|
|
2ff057 |
|
|
|
2ff057 |
while ((i = rpmdsNext(trigger)) >= 0) {
|
|
|
2ff057 |
uint32_t tix;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(rpmdsFlags(trigger) & sense))
|
|
|
2ff057 |
continue;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!rstreq(rpmdsN(trigger), sourceName))
|
|
|
2ff057 |
continue;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* XXX Trigger on any provided dependency, not just the package NEVR */
|
|
|
2ff057 |
if (!rpmdsAnyMatchesDep(sourceH, trigger, 1))
|
|
|
2ff057 |
continue;
|
|
|
2ff057 |
|
|
|
2ff057 |
tix = rpmdsTi(trigger);
|
|
|
2ff057 |
if (triggersAlreadyRun == NULL || triggersAlreadyRun[tix] == 0) {
|
|
|
2ff057 |
int arg1 = rpmdbCountPackages(rpmtsGetRdb(ts), triggerName);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (arg1 < 0) {
|
|
|
2ff057 |
/* XXX W2DO? fails as "execution of script failed" */
|
|
|
2ff057 |
rc = RPMRC_FAIL;
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
rpmScript script = rpmScriptFromTriggerTag(trigH,
|
|
|
2ff057 |
triggertag(sense), RPMSCRIPT_NORMALTRIGGER, tix);
|
|
|
2ff057 |
arg1 += countCorrection;
|
|
|
2ff057 |
rc = runScript(ts, te, trigH, pfx.data, script, arg1, arg2);
|
|
|
2ff057 |
if (triggersAlreadyRun != NULL)
|
|
|
2ff057 |
triggersAlreadyRun[tix] = 1;
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmScriptFree(script);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/*
|
|
|
2ff057 |
* Each target/source header pair can only result in a single
|
|
|
2ff057 |
* script being run.
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmtdFreeData(&pfx;;
|
|
|
2ff057 |
rpmdsFree(trigger);
|
|
|
2ff057 |
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/**
|
|
|
2ff057 |
* Run trigger scripts in the database that are fired by this header.
|
|
|
2ff057 |
* @param psm package state machine data
|
|
|
2ff057 |
* @param sense trigger type
|
|
|
2ff057 |
* @return 0 on success
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
static rpmRC runTriggers(rpmpsm psm, rpmsenseFlags sense)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
const rpmts ts = psm->ts;
|
|
|
2ff057 |
int numPackage = -1;
|
|
|
2ff057 |
const char * N = NULL;
|
|
|
2ff057 |
int nerrors = 0;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (psm->te) /* XXX can't happen */
|
|
|
2ff057 |
N = rpmteN(psm->te);
|
|
|
2ff057 |
if (N) /* XXX can't happen */
|
|
|
2ff057 |
numPackage = rpmdbCountPackages(rpmtsGetRdb(ts), N)
|
|
|
2ff057 |
+ psm->countCorrection;
|
|
|
2ff057 |
if (numPackage < 0)
|
|
|
2ff057 |
return RPMRC_NOTFOUND;
|
|
|
2ff057 |
|
|
|
2ff057 |
{ Header triggeredH;
|
|
|
2ff057 |
Header h = rpmteHeader(psm->te);
|
|
|
2ff057 |
rpmdbMatchIterator mi;
|
|
|
2ff057 |
|
|
|
2ff057 |
mi = rpmtsInitIterator(ts, RPMDBI_TRIGGERNAME, N, 0);
|
|
|
2ff057 |
while ((triggeredH = rpmdbNextIterator(mi)) != NULL) {
|
|
|
2ff057 |
nerrors += handleOneTrigger(ts, NULL, sense, h, triggeredH,
|
|
|
2ff057 |
0, numPackage, NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
rpmdbFreeIterator(mi);
|
|
|
2ff057 |
headerFree(h);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
return (nerrors == 0) ? RPMRC_OK : RPMRC_FAIL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/**
|
|
|
2ff057 |
* Run triggers from this header that are fired by headers in the database.
|
|
|
2ff057 |
* @param psm package state machine data
|
|
|
2ff057 |
* @param sense trigger type
|
|
|
2ff057 |
* @return 0 on success
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
static rpmRC runImmedTriggers(rpmpsm psm, rpmsenseFlags sense)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
const rpmts ts = psm->ts;
|
|
|
2ff057 |
unsigned char * triggersRun;
|
|
|
2ff057 |
struct rpmtd_s tnames, tindexes;
|
|
|
2ff057 |
Header h = rpmteHeader(psm->te);
|
|
|
2ff057 |
int nerrors = 0;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(headerGet(h, RPMTAG_TRIGGERNAME, &tnames, HEADERGET_MINMEM) &&
|
|
|
2ff057 |
headerGet(h, RPMTAG_TRIGGERINDEX, &tindexes, HEADERGET_MINMEM))) {
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
triggersRun = xcalloc(rpmtdCount(&tindexes), sizeof(*triggersRun));
|
|
|
2ff057 |
{ Header sourceH = NULL;
|
|
|
2ff057 |
const char *trigName;
|
|
|
2ff057 |
rpm_count_t *triggerIndices = tindexes.data;
|
|
|
2ff057 |
|
|
|
2ff057 |
while ((trigName = rpmtdNextString(&tnames))) {
|
|
|
2ff057 |
rpmdbMatchIterator mi;
|
|
|
2ff057 |
int i = rpmtdGetIndex(&tnames);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (triggersRun[triggerIndices[i]] != 0) continue;
|
|
|
2ff057 |
|
|
|
2ff057 |
mi = rpmtsInitIterator(ts, RPMDBI_NAME, trigName, 0);
|
|
|
2ff057 |
|
|
|
2ff057 |
while ((sourceH = rpmdbNextIterator(mi)) != NULL) {
|
|
|
2ff057 |
nerrors += handleOneTrigger(psm->ts, psm->te,
|
|
|
2ff057 |
sense, sourceH, h,
|
|
|
2ff057 |
psm->countCorrection,
|
|
|
2ff057 |
rpmdbGetIteratorCount(mi),
|
|
|
2ff057 |
triggersRun);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmdbFreeIterator(mi);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
rpmtdFreeData(&tnames);
|
|
|
2ff057 |
rpmtdFreeData(&tindexes);
|
|
|
2ff057 |
free(triggersRun);
|
|
|
2ff057 |
|
|
|
2ff057 |
exit:
|
|
|
2ff057 |
headerFree(h);
|
|
|
2ff057 |
return (nerrors == 0) ? RPMRC_OK : RPMRC_FAIL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmpsm rpmpsmFree(rpmpsm psm)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (psm) {
|
|
|
2ff057 |
rpmfilesFree(psm->files);
|
|
|
2ff057 |
rpmtsFree(psm->ts),
|
|
|
2ff057 |
/* XXX rpmte not refcounted yet */
|
|
|
2ff057 |
memset(psm, 0, sizeof(*psm)); /* XXX trash and burn */
|
|
|
2ff057 |
free(psm);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmpsm rpmpsmNew(rpmts ts, rpmte te, pkgGoal goal)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmpsm psm = xcalloc(1, sizeof(*psm));
|
|
|
2ff057 |
psm->ts = rpmtsLink(ts);
|
|
|
2ff057 |
psm->files = rpmteFiles(te);
|
|
|
2ff057 |
psm->te = te; /* XXX rpmte not refcounted yet */
|
|
|
2ff057 |
if (!rpmteIsSource(te)) {
|
|
|
2ff057 |
/*
|
|
|
2ff057 |
* When we run scripts, we pass an argument which is the number of
|
|
|
2ff057 |
* versions of this package that will be installed when we are
|
|
|
2ff057 |
* finished.
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
int npkgs_installed = rpmdbCountPackages(rpmtsGetRdb(ts), rpmteN(te));
|
|
|
2ff057 |
switch (goal) {
|
|
|
2ff057 |
case PKG_INSTALL:
|
|
|
2ff057 |
case PKG_PRETRANS:
|
|
|
2ff057 |
psm->scriptArg = npkgs_installed + 1;
|
|
|
2ff057 |
psm->countCorrection = 0;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PKG_ERASE:
|
|
|
2ff057 |
psm->scriptArg = npkgs_installed - 1;
|
|
|
2ff057 |
psm->countCorrection = -1;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PKG_VERIFY:
|
|
|
2ff057 |
case PKG_POSTTRANS:
|
|
|
2ff057 |
psm->scriptArg = npkgs_installed;
|
|
|
2ff057 |
psm->countCorrection = 0;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (goal == PKG_INSTALL) {
|
|
|
2ff057 |
Header h = rpmteHeader(te);
|
|
|
2ff057 |
psm->total = headerGetNumber(h, RPMTAG_LONGARCHIVESIZE);
|
|
|
2ff057 |
headerFree(h);
|
|
|
2ff057 |
} else if (goal == PKG_ERASE) {
|
|
|
2ff057 |
psm->total = rpmfilesFC(psm->files);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
/* Fake up something for packages with no files */
|
|
|
2ff057 |
if (psm->total == 0)
|
|
|
2ff057 |
psm->total = 100;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (goal == PKG_INSTALL || goal == PKG_ERASE) {
|
|
|
2ff057 |
rpmlog(RPMLOG_DEBUG, "%s: %s has %d files\n", pkgGoalString(goal),
|
|
|
2ff057 |
rpmteNEVRA(psm->te), rpmfilesFC(psm->files));
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
return psm;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmpsmNotify(rpmpsm psm, int what, rpm_loff_t amount)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (psm) {
|
|
|
2ff057 |
int changed = 0;
|
|
|
2ff057 |
if (amount > psm->total)
|
|
|
2ff057 |
amount = psm->total;
|
|
|
2ff057 |
if (amount > psm->amount) {
|
|
|
2ff057 |
psm->amount = amount;
|
|
|
2ff057 |
changed = 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (what && what != psm->what) {
|
|
|
2ff057 |
psm->what = what;
|
|
|
2ff057 |
changed = 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (changed) {
|
|
|
2ff057 |
rpmtsNotify(psm->ts, psm->te, psm->what, psm->amount, psm->total);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/*
|
|
|
2ff057 |
* --replacepkgs hack: find the header instance we're replacing and
|
|
|
2ff057 |
* mark it as the db instance of the install element. In PSM_POST,
|
|
|
2ff057 |
* if an install element already has a db instance, it's removed
|
|
|
2ff057 |
* before proceeding with the adding the new header to the db.
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
static void markReplacedInstance(rpmts ts, rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMDBI_NAME, rpmteN(te), 0);
|
|
|
2ff057 |
rpmdbSetIteratorRE(mi, RPMTAG_EPOCH, RPMMIRE_STRCMP, rpmteE(te));
|
|
|
2ff057 |
rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_STRCMP, rpmteV(te));
|
|
|
2ff057 |
rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_STRCMP, rpmteR(te));
|
|
|
2ff057 |
/* XXX shouldn't we also do this on colorless transactions? */
|
|
|
2ff057 |
if (rpmtsColor(ts)) {
|
|
|
2ff057 |
rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_STRCMP, rpmteA(te));
|
|
|
2ff057 |
rpmdbSetIteratorRE(mi, RPMTAG_OS, RPMMIRE_STRCMP, rpmteO(te));
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
while (rpmdbNextIterator(mi) != NULL) {
|
|
|
2ff057 |
rpmteSetDBInstance(te, rpmdbGetIteratorOffset(mi));
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
rpmdbFreeIterator(mi);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmRC dbAdd(rpmts ts, rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
Header h = rpmteHeader(te);
|
|
|
2ff057 |
rpm_time_t installTime = (rpm_time_t) time(NULL);
|
|
|
2ff057 |
rpmfs fs = rpmteGetFileStates(te);
|
|
|
2ff057 |
rpm_count_t fc = rpmfsFC(fs);
|
|
|
2ff057 |
rpm_fstate_t * fileStates = rpmfsGetStates(fs);
|
|
|
2ff057 |
rpm_color_t tscolor = rpmtsColor(ts);
|
|
|
2ff057 |
rpm_tid_t tid = rpmtsGetTid(ts);
|
|
|
2ff057 |
rpmRC rc;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (fileStates != NULL && fc > 0) {
|
|
|
2ff057 |
headerPutChar(h, RPMTAG_FILESTATES, fileStates, fc);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
headerPutUint32(h, RPMTAG_INSTALLTID, &tid, 1);
|
|
|
2ff057 |
headerPutUint32(h, RPMTAG_INSTALLTIME, &installTime, 1);
|
|
|
2ff057 |
headerPutUint32(h, RPMTAG_INSTALLCOLOR, &tscolor, 1);
|
|
|
2ff057 |
|
|
|
2ff057 |
(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DBADD), 0);
|
|
|
2ff057 |
rc = (rpmdbAdd(rpmtsGetRdb(ts), h) == 0) ? RPMRC_OK : RPMRC_FAIL;
|
|
|
2ff057 |
(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DBADD), 0);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (rc == RPMRC_OK) {
|
|
|
2ff057 |
rpmteSetDBInstance(te, headerGetInstance(h));
|
|
|
2ff057 |
packageHashAddEntry(ts->members->installedPackages,
|
|
|
2ff057 |
headerGetInstance(h), te);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
headerFree(h);
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmRC dbRemove(rpmts ts, rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmRC rc;
|
|
|
2ff057 |
|
|
|
2ff057 |
(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0);
|
|
|
2ff057 |
rc = (rpmdbRemove(rpmtsGetRdb(ts), rpmteDBInstance(te)) == 0) ?
|
|
|
2ff057 |
RPMRC_OK : RPMRC_FAIL;
|
|
|
2ff057 |
(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (rc == RPMRC_OK)
|
|
|
2ff057 |
rpmteSetDBInstance(te, 0);
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmRC rpmpsmUnpack(rpmpsm psm)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
char *failedFile = NULL;
|
|
|
2ff057 |
int fsmrc = 0;
|
|
|
2ff057 |
int saved_errno = 0;
|
|
|
2ff057 |
rpmRC rc = RPMRC_OK;
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmpsmNotify(psm, RPMCALLBACK_INST_START, 0);
|
|
|
2ff057 |
/* make sure first progress call gets made */
|
|
|
2ff057 |
rpmpsmNotify(psm, RPMCALLBACK_INST_PROGRESS, 0);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(rpmtsFlags(psm->ts) & RPMTRANS_FLAG_JUSTDB)) {
|
|
|
2ff057 |
if (rpmfilesFC(psm->files) > 0) {
|
|
|
2ff057 |
fsmrc = rpmPackageFilesInstall(psm->ts, psm->te, psm->files,
|
|
|
2ff057 |
psm, &failedFile);
|
|
|
2ff057 |
saved_errno = errno;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/* XXX make sure progress reaches 100% */
|
|
|
2ff057 |
rpmpsmNotify(psm, RPMCALLBACK_INST_PROGRESS, psm->total);
|
|
|
2ff057 |
rpmpsmNotify(psm, RPMCALLBACK_INST_STOP, psm->total);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (fsmrc) {
|
|
|
2ff057 |
char *emsg;
|
|
|
2ff057 |
errno = saved_errno;
|
|
|
2ff057 |
emsg = rpmfileStrerror(fsmrc);
|
|
|
2ff057 |
rpmlog(RPMLOG_ERR,
|
|
|
2ff057 |
_("unpacking of archive failed%s%s: %s\n"),
|
|
|
2ff057 |
(failedFile != NULL ? _(" on file ") : ""),
|
|
|
2ff057 |
(failedFile != NULL ? failedFile : ""),
|
|
|
2ff057 |
emsg);
|
|
|
2ff057 |
free(emsg);
|
|
|
2ff057 |
rc = RPMRC_FAIL;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* XXX notify callback on error. */
|
|
|
2ff057 |
rpmtsNotify(psm->ts, psm->te, RPMCALLBACK_UNPACK_ERROR, 0, 0);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
free(failedFile);
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmRC rpmpsmRemove(rpmpsm psm)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
char *failedFile = NULL;
|
|
|
2ff057 |
int fsmrc = 0;
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmpsmNotify(psm, RPMCALLBACK_UNINST_START, 0);
|
|
|
2ff057 |
/* make sure first progress call gets made */
|
|
|
2ff057 |
rpmpsmNotify(psm, RPMCALLBACK_UNINST_PROGRESS, 0);
|
|
|
2ff057 |
|
|
|
2ff057 |
/* XXX should't we log errors from here? */
|
|
|
2ff057 |
if (!(rpmtsFlags(psm->ts) & RPMTRANS_FLAG_JUSTDB)) {
|
|
|
2ff057 |
if (rpmfilesFC(psm->files) > 0) {
|
|
|
2ff057 |
fsmrc = rpmPackageFilesRemove(psm->ts, psm->te, psm->files,
|
|
|
2ff057 |
psm, &failedFile);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
/* XXX make sure progress reaches 100% */
|
|
|
2ff057 |
rpmpsmNotify(psm, RPMCALLBACK_UNINST_PROGRESS, psm->total);
|
|
|
2ff057 |
rpmpsmNotify(psm, RPMCALLBACK_UNINST_STOP, psm->total);
|
|
|
2ff057 |
|
|
|
2ff057 |
free(failedFile);
|
|
|
2ff057 |
return (fsmrc == 0) ? RPMRC_OK : RPMRC_FAIL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmRC rpmPackageInstall(rpmts ts, rpmpsm psm)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmRC rc = RPMRC_OK;
|
|
|
2ff057 |
int once = 1;
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmswEnter(rpmtsOp(psm->ts, RPMTS_OP_INSTALL), 0);
|
|
|
2ff057 |
while (once--) {
|
|
|
2ff057 |
/* HACK: replacepkgs abuses te instance to remove old header */
|
|
|
2ff057 |
if (rpmtsFilterFlags(psm->ts) & RPMPROB_FILTER_REPLACEPKG)
|
|
|
2ff057 |
markReplacedInstance(ts, psm->te);
|
|
|
2ff057 |
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPREIN)) {
|
|
|
2ff057 |
/* Run triggers in other package(s) this package sets off. */
|
|
|
2ff057 |
rc = runTriggers(psm, RPMSENSE_TRIGGERPREIN);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Run triggers in this package other package(s) set off. */
|
|
|
2ff057 |
rc = runImmedTriggers(psm, RPMSENSE_TRIGGERPREIN);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPRE)) {
|
|
|
2ff057 |
rc = runInstScript(psm, RPMTAG_PREIN);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rc = rpmpsmUnpack(psm);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
/*
|
|
|
2ff057 |
* If this package has already been installed, remove it from
|
|
|
2ff057 |
* the database before adding the new one.
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
if (rpmteDBInstance(psm->te)) {
|
|
|
2ff057 |
rc = dbRemove(ts, psm->te);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rc = dbAdd(ts, psm->te);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERIN)) {
|
|
|
2ff057 |
/* Run upper file triggers i. e. with higher priorities */
|
|
|
2ff057 |
/* Run file triggers in other package(s) this package sets off. */
|
|
|
2ff057 |
rc = runFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERIN,
|
|
|
2ff057 |
RPMSCRIPT_FILETRIGGER, 1);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Run file triggers in this package other package(s) set off. */
|
|
|
2ff057 |
rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERIN,
|
|
|
2ff057 |
RPMSCRIPT_FILETRIGGER, 1);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOST)) {
|
|
|
2ff057 |
rc = runInstScript(psm, RPMTAG_POSTIN);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERIN)) {
|
|
|
2ff057 |
/* Run triggers in other package(s) this package sets off. */
|
|
|
2ff057 |
rc = runTriggers(psm, RPMSENSE_TRIGGERIN);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Run triggers in this package other package(s) set off. */
|
|
|
2ff057 |
rc = runImmedTriggers(psm, RPMSENSE_TRIGGERIN);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Run lower file triggers i. e. with lower priorities */
|
|
|
2ff057 |
/* Run file triggers in other package(s) this package sets off. */
|
|
|
2ff057 |
rc = runFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERIN,
|
|
|
2ff057 |
RPMSCRIPT_FILETRIGGER, 2);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Run file triggers in this package other package(s) set off. */
|
|
|
2ff057 |
rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERIN,
|
|
|
2ff057 |
RPMSCRIPT_FILETRIGGER, 2);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rc = markReplacedFiles(psm);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmswExit(rpmtsOp(psm->ts, RPMTS_OP_INSTALL), 0);
|
|
|
2ff057 |
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmRC rpmPackageErase(rpmts ts, rpmpsm psm)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmRC rc = RPMRC_OK;
|
|
|
2ff057 |
int once = 1;
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmswEnter(rpmtsOp(psm->ts, RPMTS_OP_ERASE), 0);
|
|
|
2ff057 |
while (once--) {
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERUN)) {
|
|
|
2ff057 |
/* Run file triggers in this package other package(s) set off. */
|
|
|
2ff057 |
rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERUN,
|
|
|
2ff057 |
RPMSCRIPT_FILETRIGGER, 1);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Run file triggers in other package(s) this package sets off. */
|
|
|
2ff057 |
rc = runFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERUN,
|
|
|
2ff057 |
RPMSCRIPT_FILETRIGGER, 1);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Run triggers in this package other package(s) set off. */
|
|
|
2ff057 |
rc = runImmedTriggers(psm, RPMSENSE_TRIGGERUN);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Run triggers in other package(s) this package sets off. */
|
|
|
2ff057 |
rc = runTriggers(psm, RPMSENSE_TRIGGERUN);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPREUN)) {
|
|
|
2ff057 |
rc = runInstScript(psm, RPMTAG_PREUN);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERUN)) {
|
|
|
2ff057 |
/* Run file triggers in this package other package(s) set off. */
|
|
|
2ff057 |
rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERUN,
|
|
|
2ff057 |
RPMSCRIPT_FILETRIGGER, 2);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Run file triggers in other package(s) this package sets off. */
|
|
|
2ff057 |
rc = runFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERUN,
|
|
|
2ff057 |
RPMSCRIPT_FILETRIGGER, 2);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rc = rpmpsmRemove(psm);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Run file triggers in other package(s) this package sets off. */
|
|
|
2ff057 |
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPOSTUN)) {
|
|
|
2ff057 |
rc = runFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERPOSTUN,
|
|
|
2ff057 |
RPMSCRIPT_FILETRIGGER, 1);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOSTUN)) {
|
|
|
2ff057 |
rc = runInstScript(psm, RPMTAG_POSTUN);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPOSTUN)) {
|
|
|
2ff057 |
/* Run triggers in other package(s) this package sets off. */
|
|
|
2ff057 |
rc = runTriggers(psm, RPMSENSE_TRIGGERPOSTUN);
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Run file triggers in other package(s) this package sets off. */
|
|
|
2ff057 |
rc = runFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERPOSTUN,
|
|
|
2ff057 |
RPMSCRIPT_FILETRIGGER, 2);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (rc) break;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERPOSTUN))) {
|
|
|
2ff057 |
/* Prepare post transaction uninstall triggers */
|
|
|
2ff057 |
rpmtriggersPrepPostUnTransFileTrigs(psm->ts, psm->te);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rc = dbRemove(ts, psm->te);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmswExit(rpmtsOp(psm->ts, RPMTS_OP_ERASE), 0);
|
|
|
2ff057 |
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static const char * pkgGoalString(pkgGoal goal)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
switch (goal) {
|
|
|
2ff057 |
case PKG_INSTALL: return " install";
|
|
|
2ff057 |
case PKG_ERASE: return " erase";
|
|
|
2ff057 |
case PKG_VERIFY: return " verify";
|
|
|
2ff057 |
case PKG_PRETRANS: return " pretrans";
|
|
|
2ff057 |
case PKG_POSTTRANS: return "posttrans";
|
|
|
2ff057 |
default: return "unknown";
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmRC rpmpsmRun(rpmts ts, rpmte te, pkgGoal goal)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmpsm psm = NULL;
|
|
|
2ff057 |
rpmRC rc = RPMRC_FAIL;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Psm can't fail in test mode, just return early */
|
|
|
2ff057 |
if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)
|
|
|
2ff057 |
return RPMRC_OK;
|
|
|
2ff057 |
|
|
|
2ff057 |
psm = rpmpsmNew(ts, te, goal);
|
|
|
2ff057 |
if (rpmChrootIn() == 0) {
|
|
|
2ff057 |
/* Run pre transaction element hook for all plugins */
|
|
|
2ff057 |
rc = rpmpluginsCallPsmPre(rpmtsPlugins(ts), te);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!rc) {
|
|
|
2ff057 |
switch (goal) {
|
|
|
2ff057 |
case PKG_INSTALL:
|
|
|
2ff057 |
rc = rpmPackageInstall(ts, psm);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PKG_ERASE:
|
|
|
2ff057 |
rc = rpmPackageErase(ts, psm);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PKG_PRETRANS:
|
|
|
2ff057 |
case PKG_POSTTRANS:
|
|
|
2ff057 |
case PKG_VERIFY:
|
|
|
2ff057 |
rc = runInstScript(psm, goal);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PKG_TRANSFILETRIGGERIN:
|
|
|
2ff057 |
rc = runImmedFileTriggers(ts, te, RPMSENSE_TRIGGERIN,
|
|
|
2ff057 |
RPMSCRIPT_TRANSFILETRIGGER, 0);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PKG_TRANSFILETRIGGERUN:
|
|
|
2ff057 |
rc = runImmedFileTriggers(ts, te, RPMSENSE_TRIGGERUN,
|
|
|
2ff057 |
RPMSCRIPT_TRANSFILETRIGGER, 0);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
/* Run post transaction element hook for all plugins */
|
|
|
2ff057 |
rpmpluginsCallPsmPost(rpmtsPlugins(ts), te, rc);
|
|
|
2ff057 |
|
|
|
2ff057 |
/* XXX an error here would require a full abort */
|
|
|
2ff057 |
(void) rpmChrootOut();
|
|
|
2ff057 |
}
|
|
|
2ff057 |
rpmpsmFree(psm);
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|