2000-08-28 03:27:03 +08:00
|
|
|
/** \ingroup rpmtrans payload
|
2001-02-11 00:47:40 +08:00
|
|
|
* \file lib/psm.c
|
2001-04-10 20:36:45 +08:00
|
|
|
* Package state machine to handle a package from a transaction set.
|
2000-08-28 03:27:03 +08:00
|
|
|
*/
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
#include "system.h"
|
1997-01-18 00:22:57 +08:00
|
|
|
|
2001-09-26 04:51:34 +08:00
|
|
|
#include "psm.h"
|
1999-11-13 01:20:49 +08:00
|
|
|
#include <rpmmacro.h>
|
|
|
|
#include <rpmurl.h>
|
1996-01-09 03:31:44 +08:00
|
|
|
|
2001-02-12 06:02:29 +08:00
|
|
|
#include "rpmlead.h" /* writeLead proto */
|
|
|
|
#include "signature.h" /* signature constants */
|
2001-10-22 05:43:32 +08:00
|
|
|
#include "legacy.h" /* XXX buildOrigFileList() */
|
|
|
|
#include "ugid.h" /* XXX unameToUid() and gnameToGid() */
|
|
|
|
#include "misc.h" /* XXX stripTrailingChar() */
|
2001-07-28 08:33:07 +08:00
|
|
|
#include "rpmdb.h" /* XXX for db_chrootDone */
|
2000-12-13 04:03:45 +08:00
|
|
|
#include "debug.h"
|
1996-01-09 03:31:44 +08:00
|
|
|
|
2001-02-11 00:47:40 +08:00
|
|
|
/*@access Header @*/ /* compared with NULL */
|
2001-03-15 07:09:09 +08:00
|
|
|
/*@access rpmdbMatchIterator @*/ /* compared with NULL */
|
|
|
|
/*@access FSM_t @*/ /* compared with NULL */
|
|
|
|
/*@access FD_t @*/ /* compared with NULL */
|
2001-08-03 23:17:55 +08:00
|
|
|
/*@access rpmdb @*/ /* compared with NULL */
|
2001-02-11 00:47:40 +08:00
|
|
|
|
2001-10-19 00:39:54 +08:00
|
|
|
/*@access rpmTransactionSet @*/
|
|
|
|
/*@access TFI_t @*/
|
|
|
|
/*@access rpmProblemSet@*/
|
|
|
|
/*@access rpmProblem@*/
|
|
|
|
/*@access PSM_t @*/
|
|
|
|
|
2001-08-03 23:17:55 +08:00
|
|
|
/*@-redecl -declundef -exportheadervar@*/
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@unchecked@*/
|
2001-07-28 08:33:07 +08:00
|
|
|
extern const char * chroot_prefix;
|
2001-08-03 23:17:55 +08:00
|
|
|
/*@=redecl =declundef =exportheadervar@*/
|
2001-07-28 08:33:07 +08:00
|
|
|
|
2001-03-05 01:15:56 +08:00
|
|
|
int rpmVersionCompare(Header first, Header second)
|
|
|
|
{
|
|
|
|
const char * one, * two;
|
|
|
|
int_32 * epochOne, * epochTwo;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if (!headerGetEntry(first, RPMTAG_EPOCH, NULL, (void **) &epochOne, NULL))
|
|
|
|
epochOne = NULL;
|
|
|
|
if (!headerGetEntry(second, RPMTAG_EPOCH, NULL, (void **) &epochTwo,
|
|
|
|
NULL))
|
|
|
|
epochTwo = NULL;
|
|
|
|
|
|
|
|
if (epochOne && !epochTwo)
|
|
|
|
return 1;
|
|
|
|
else if (!epochOne && epochTwo)
|
|
|
|
return -1;
|
|
|
|
else if (epochOne && epochTwo) {
|
|
|
|
if (*epochOne < *epochTwo)
|
|
|
|
return -1;
|
|
|
|
else if (*epochOne > *epochTwo)
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
rc = headerGetEntry(first, RPMTAG_VERSION, NULL, (void **) &one, NULL);
|
|
|
|
rc = headerGetEntry(second, RPMTAG_VERSION, NULL, (void **) &two, NULL);
|
2001-03-05 01:15:56 +08:00
|
|
|
|
|
|
|
rc = rpmvercmp(one, two);
|
|
|
|
if (rc)
|
|
|
|
return rc;
|
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
rc = headerGetEntry(first, RPMTAG_RELEASE, NULL, (void **) &one, NULL);
|
|
|
|
rc = headerGetEntry(second, RPMTAG_RELEASE, NULL, (void **) &two, NULL);
|
2001-03-05 01:15:56 +08:00
|
|
|
|
|
|
|
return rpmvercmp(one, two);
|
|
|
|
}
|
|
|
|
|
2001-10-19 00:39:54 +08:00
|
|
|
rpmProblemSet psCreate(void)
|
|
|
|
{
|
|
|
|
rpmProblemSet probs;
|
|
|
|
|
|
|
|
probs = xcalloc(1, sizeof(*probs)); /* XXX memory leak */
|
|
|
|
probs->numProblems = probs->numProblemsAlloced = 0;
|
|
|
|
probs->probs = NULL;
|
|
|
|
|
|
|
|
return probs;
|
|
|
|
}
|
|
|
|
|
|
|
|
void psAppend(rpmProblemSet probs, rpmProblemType type,
|
|
|
|
const struct availablePackage * alp,
|
|
|
|
const char * dn, const char * bn,
|
|
|
|
Header altH, unsigned long ulong1)
|
|
|
|
{
|
|
|
|
rpmProblem p;
|
|
|
|
char *t;
|
|
|
|
|
|
|
|
if (probs->numProblems == probs->numProblemsAlloced) {
|
|
|
|
if (probs->numProblemsAlloced)
|
|
|
|
probs->numProblemsAlloced *= 2;
|
|
|
|
else
|
|
|
|
probs->numProblemsAlloced = 2;
|
|
|
|
probs->probs = xrealloc(probs->probs,
|
|
|
|
probs->numProblemsAlloced * sizeof(*probs->probs));
|
|
|
|
}
|
|
|
|
|
|
|
|
p = probs->probs + probs->numProblems;
|
|
|
|
probs->numProblems++;
|
|
|
|
memset(p, 0, sizeof(*p));
|
|
|
|
p->type = type;
|
|
|
|
/*@-assignexpose@*/
|
|
|
|
p->key = alp->key;
|
|
|
|
/*@=assignexpose@*/
|
|
|
|
p->ulong1 = ulong1;
|
|
|
|
p->ignoreProblem = 0;
|
|
|
|
p->str1 = NULL;
|
|
|
|
p->h = NULL;
|
|
|
|
p->pkgNEVR = NULL;
|
|
|
|
p->altNEVR = NULL;
|
|
|
|
|
|
|
|
if (dn || bn) {
|
|
|
|
p->str1 =
|
|
|
|
t = xcalloc(1, (dn ? strlen(dn) : 0) + (bn ? strlen(bn) : 0) + 1);
|
|
|
|
if (dn) t = stpcpy(t, dn);
|
|
|
|
if (bn) t = stpcpy(t, bn);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (alp) {
|
|
|
|
p->h = headerLink(alp->h);
|
|
|
|
p->pkgNEVR =
|
|
|
|
t = xcalloc(1, strlen(alp->name) +
|
|
|
|
strlen(alp->version) +
|
|
|
|
strlen(alp->release) + sizeof("--"));
|
|
|
|
t = stpcpy(t, alp->name);
|
|
|
|
t = stpcpy(t, "-");
|
|
|
|
t = stpcpy(t, alp->version);
|
|
|
|
t = stpcpy(t, "-");
|
|
|
|
t = stpcpy(t, alp->release);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (altH) {
|
|
|
|
const char * n, * v, * r;
|
|
|
|
(void) headerNVR(altH, &n, &v, &r);
|
|
|
|
p->altNEVR =
|
|
|
|
t = xcalloc(1, strlen(n) + strlen(v) + strlen(r) + sizeof("--"));
|
|
|
|
t = stpcpy(t, n);
|
|
|
|
t = stpcpy(t, "-");
|
|
|
|
t = stpcpy(t, v);
|
|
|
|
t = stpcpy(t, "-");
|
|
|
|
t = stpcpy(t, r);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
static /*@observer@*/ const char *const ftstring (fileTypes ft)
|
|
|
|
/*@*/
|
|
|
|
{
|
|
|
|
switch (ft) {
|
|
|
|
case XDIR: return "directory";
|
|
|
|
case CDEV: return "char dev";
|
|
|
|
case BDEV: return "block dev";
|
|
|
|
case LINK: return "link";
|
|
|
|
case SOCK: return "sock";
|
|
|
|
case PIPE: return "fifo/pipe";
|
|
|
|
case REG: return "file";
|
|
|
|
default: return "unknown file type";
|
|
|
|
}
|
|
|
|
/*@notreached@*/
|
|
|
|
}
|
|
|
|
|
|
|
|
fileTypes whatis(uint_16 mode)
|
|
|
|
{
|
|
|
|
if (S_ISDIR(mode)) return XDIR;
|
|
|
|
if (S_ISCHR(mode)) return CDEV;
|
|
|
|
if (S_ISBLK(mode)) return BDEV;
|
|
|
|
if (S_ISLNK(mode)) return LINK;
|
|
|
|
if (S_ISSOCK(mode)) return SOCK;
|
|
|
|
if (S_ISFIFO(mode)) return PIPE;
|
|
|
|
return REG;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
|
|
|
|
|
|
|
|
Header relocateFileList(const rpmTransactionSet ts, TFI_t fi,
|
|
|
|
struct availablePackage * alp,
|
|
|
|
Header origH, fileAction * actions)
|
|
|
|
{
|
|
|
|
HGE_t hge = fi->hge;
|
|
|
|
HAE_t hae = fi->hae;
|
|
|
|
HME_t hme = fi->hme;
|
|
|
|
HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
|
|
|
|
static int _printed = 0;
|
|
|
|
int allowBadRelocate = (ts->ignoreSet & RPMPROB_FILTER_FORCERELOCATE);
|
|
|
|
rpmRelocation * rawRelocations = alp->relocs;
|
|
|
|
rpmRelocation * relocations = NULL;
|
|
|
|
int numRelocations;
|
|
|
|
const char ** validRelocations;
|
|
|
|
rpmTagType validType;
|
|
|
|
int numValid;
|
|
|
|
const char ** baseNames;
|
|
|
|
const char ** dirNames;
|
|
|
|
int_32 * dirIndexes;
|
|
|
|
int_32 * newDirIndexes;
|
|
|
|
int_32 fileCount;
|
|
|
|
int_32 dirCount;
|
|
|
|
uint_32 * fFlags = NULL;
|
|
|
|
uint_16 * fModes = NULL;
|
|
|
|
char * skipDirList;
|
|
|
|
Header h;
|
|
|
|
int nrelocated = 0;
|
|
|
|
int fileAlloced = 0;
|
|
|
|
char * fn = NULL;
|
|
|
|
int haveRelocatedFile = 0;
|
|
|
|
int reldel = 0;
|
|
|
|
int len;
|
|
|
|
int i, j, xx;
|
|
|
|
|
|
|
|
if (!hge(origH, RPMTAG_PREFIXES, &validType,
|
|
|
|
(void **) &validRelocations, &numValid))
|
|
|
|
numValid = 0;
|
|
|
|
|
|
|
|
numRelocations = 0;
|
|
|
|
if (rawRelocations)
|
|
|
|
while (rawRelocations[numRelocations].newPath ||
|
|
|
|
rawRelocations[numRelocations].oldPath)
|
|
|
|
numRelocations++;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If no relocations are specified (usually the case), then return the
|
|
|
|
* original header. If there are prefixes, however, then INSTPREFIXES
|
|
|
|
* should be added, but, since relocateFileList() can be called more
|
|
|
|
* than once for the same header, don't bother if already present.
|
|
|
|
*/
|
|
|
|
if (rawRelocations == NULL || numRelocations == 0) {
|
|
|
|
if (numValid) {
|
|
|
|
if (!headerIsEntry(origH, RPMTAG_INSTPREFIXES))
|
|
|
|
xx = hae(origH, RPMTAG_INSTPREFIXES,
|
|
|
|
validType, validRelocations, numValid);
|
|
|
|
validRelocations = hfd(validRelocations, validType);
|
|
|
|
}
|
|
|
|
/* XXX FIXME multilib file actions need to be checked. */
|
|
|
|
return headerLink(origH);
|
|
|
|
}
|
|
|
|
|
|
|
|
h = headerLink(origH);
|
|
|
|
|
|
|
|
relocations = alloca(sizeof(*relocations) * numRelocations);
|
|
|
|
|
|
|
|
/* Build sorted relocation list from raw relocations. */
|
|
|
|
for (i = 0; i < numRelocations; i++) {
|
|
|
|
char * t;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Default relocations (oldPath == NULL) are handled in the UI,
|
|
|
|
* not rpmlib.
|
|
|
|
*/
|
|
|
|
if (rawRelocations[i].oldPath == NULL) continue; /* XXX can't happen */
|
|
|
|
|
|
|
|
/* FIXME: Trailing /'s will confuse us greatly. Internal ones will
|
|
|
|
too, but those are more trouble to fix up. :-( */
|
|
|
|
t = alloca_strdup(rawRelocations[i].oldPath);
|
|
|
|
/*@-branchstate@*/
|
|
|
|
relocations[i].oldPath = (t[0] == '/' && t[1] == '\0')
|
|
|
|
? t
|
|
|
|
: stripTrailingChar(t, '/');
|
|
|
|
/*@=branchstate@*/
|
|
|
|
|
|
|
|
/* An old path w/o a new path is valid, and indicates exclusion */
|
|
|
|
if (rawRelocations[i].newPath) {
|
|
|
|
int del;
|
|
|
|
|
|
|
|
t = alloca_strdup(rawRelocations[i].newPath);
|
|
|
|
/*@-branchstate@*/
|
|
|
|
relocations[i].newPath = (t[0] == '/' && t[1] == '\0')
|
|
|
|
? t
|
|
|
|
: stripTrailingChar(t, '/');
|
|
|
|
/*@=branchstate@*/
|
|
|
|
|
|
|
|
/*@-nullpass@*/ /* FIX: relocations[i].oldPath == NULL */
|
|
|
|
/* Verify that the relocation's old path is in the header. */
|
|
|
|
for (j = 0; j < numValid; j++)
|
|
|
|
if (!strcmp(validRelocations[j], relocations[i].oldPath))
|
|
|
|
/*@innerbreak@*/ break;
|
|
|
|
/* XXX actions check prevents problem from being appended twice. */
|
|
|
|
if (j == numValid && !allowBadRelocate && actions)
|
|
|
|
psAppend(ts->probs, RPMPROB_BADRELOCATE, alp,
|
|
|
|
relocations[i].oldPath, NULL, NULL, 0);
|
|
|
|
del =
|
|
|
|
strlen(relocations[i].newPath) - strlen(relocations[i].oldPath);
|
|
|
|
/*@=nullpass@*/
|
|
|
|
|
|
|
|
if (del > reldel)
|
|
|
|
reldel = del;
|
|
|
|
} else {
|
|
|
|
relocations[i].newPath = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* stupid bubble sort, but it's probably faster here */
|
|
|
|
for (i = 0; i < numRelocations; i++) {
|
|
|
|
int madeSwap;
|
|
|
|
madeSwap = 0;
|
|
|
|
for (j = 1; j < numRelocations; j++) {
|
|
|
|
rpmRelocation tmpReloc;
|
|
|
|
if (relocations[j - 1].oldPath == NULL || /* XXX can't happen */
|
|
|
|
relocations[j ].oldPath == NULL || /* XXX can't happen */
|
|
|
|
strcmp(relocations[j - 1].oldPath, relocations[j].oldPath) <= 0)
|
|
|
|
/*@innercontinue@*/ continue;
|
|
|
|
/*@-usereleased@*/ /* LCL: ??? */
|
|
|
|
tmpReloc = relocations[j - 1];
|
|
|
|
relocations[j - 1] = relocations[j];
|
|
|
|
relocations[j] = tmpReloc;
|
|
|
|
/*@=usereleased@*/
|
|
|
|
madeSwap = 1;
|
|
|
|
}
|
|
|
|
if (!madeSwap) break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!_printed) {
|
|
|
|
_printed = 1;
|
|
|
|
rpmMessage(RPMMESS_DEBUG, _("========== relocations\n"));
|
|
|
|
for (i = 0; i < numRelocations; i++) {
|
|
|
|
if (relocations[i].oldPath == NULL) continue; /* XXX can't happen */
|
|
|
|
if (relocations[i].newPath == NULL)
|
|
|
|
rpmMessage(RPMMESS_DEBUG, _("%5d exclude %s\n"),
|
|
|
|
i, relocations[i].oldPath);
|
|
|
|
else
|
|
|
|
rpmMessage(RPMMESS_DEBUG, _("%5d relocate %s -> %s\n"),
|
|
|
|
i, relocations[i].oldPath, relocations[i].newPath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add relocation values to the header */
|
|
|
|
if (numValid) {
|
|
|
|
const char ** actualRelocations;
|
|
|
|
int numActual;
|
|
|
|
|
|
|
|
actualRelocations = xmalloc(numValid * sizeof(*actualRelocations));
|
|
|
|
numActual = 0;
|
|
|
|
for (i = 0; i < numValid; i++) {
|
|
|
|
for (j = 0; j < numRelocations; j++) {
|
|
|
|
if (relocations[j].oldPath == NULL || /* XXX can't happen */
|
|
|
|
strcmp(validRelocations[i], relocations[j].oldPath))
|
|
|
|
/*@innercontinue@*/ continue;
|
|
|
|
/* On install, a relocate to NULL means skip the path. */
|
|
|
|
if (relocations[j].newPath) {
|
|
|
|
actualRelocations[numActual] = relocations[j].newPath;
|
|
|
|
numActual++;
|
|
|
|
}
|
|
|
|
/*@innerbreak@*/ break;
|
|
|
|
}
|
|
|
|
if (j == numRelocations) {
|
|
|
|
actualRelocations[numActual] = validRelocations[i];
|
|
|
|
numActual++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (numActual)
|
|
|
|
xx = hae(h, RPMTAG_INSTPREFIXES, RPM_STRING_ARRAY_TYPE,
|
|
|
|
(void **) actualRelocations, numActual);
|
|
|
|
|
|
|
|
actualRelocations = _free(actualRelocations);
|
|
|
|
validRelocations = hfd(validRelocations, validType);
|
|
|
|
}
|
|
|
|
|
|
|
|
xx = hge(h, RPMTAG_BASENAMES, NULL, (void **) &baseNames, &fileCount);
|
|
|
|
xx = hge(h, RPMTAG_DIRINDEXES, NULL, (void **) &dirIndexes, NULL);
|
|
|
|
xx = hge(h, RPMTAG_DIRNAMES, NULL, (void **) &dirNames, &dirCount);
|
|
|
|
xx = hge(h, RPMTAG_FILEFLAGS, NULL, (void **) &fFlags, NULL);
|
|
|
|
xx = hge(h, RPMTAG_FILEMODES, NULL, (void **) &fModes, NULL);
|
|
|
|
|
|
|
|
skipDirList = alloca(dirCount * sizeof(*skipDirList));
|
|
|
|
memset(skipDirList, 0, dirCount * sizeof(*skipDirList));
|
|
|
|
|
|
|
|
newDirIndexes = alloca(sizeof(*newDirIndexes) * fileCount);
|
|
|
|
memcpy(newDirIndexes, dirIndexes, sizeof(*newDirIndexes) * fileCount);
|
|
|
|
dirIndexes = newDirIndexes;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* For all relocations, we go through sorted file/relocation lists
|
|
|
|
* backwards so that /usr/local relocations take precedence over /usr
|
|
|
|
* ones.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Relocate individual paths. */
|
|
|
|
|
|
|
|
for (i = fileCount - 1; i >= 0; i--) {
|
|
|
|
fileTypes ft;
|
|
|
|
int fnlen;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If only adding libraries of different arch into an already
|
|
|
|
* installed package, skip all other files.
|
|
|
|
*/
|
|
|
|
if (alp->multiLib && !isFileMULTILIB((fFlags[i]))) {
|
|
|
|
if (actions) {
|
|
|
|
actions[i] = FA_SKIPMULTILIB;
|
|
|
|
rpmMessage(RPMMESS_DEBUG, _("excluding multilib path %s%s\n"),
|
|
|
|
dirNames[dirIndexes[i]], baseNames[i]);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = reldel +
|
|
|
|
strlen(dirNames[dirIndexes[i]]) + strlen(baseNames[i]) + 1;
|
|
|
|
/*@-branchstate@*/
|
|
|
|
if (len >= fileAlloced) {
|
|
|
|
fileAlloced = len * 2;
|
|
|
|
fn = xrealloc(fn, fileAlloced);
|
|
|
|
}
|
|
|
|
/*@=branchstate@*/
|
|
|
|
*fn = '\0';
|
|
|
|
fnlen = stpcpy( stpcpy(fn, dirNames[dirIndexes[i]]), baseNames[i]) - fn;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* See if this file path needs relocating.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* XXX FIXME: Would a bsearch of the (already sorted)
|
|
|
|
* relocation list be a good idea?
|
|
|
|
*/
|
|
|
|
for (j = numRelocations - 1; j >= 0; j--) {
|
|
|
|
if (relocations[j].oldPath == NULL) /* XXX can't happen */
|
|
|
|
/*@innercontinue@*/ continue;
|
|
|
|
len = strcmp(relocations[j].oldPath, "/")
|
|
|
|
? strlen(relocations[j].oldPath)
|
|
|
|
: 0;
|
|
|
|
|
|
|
|
if (fnlen < len)
|
|
|
|
/*@innercontinue@*/ continue;
|
|
|
|
/*
|
|
|
|
* Only subdirectories or complete file paths may be relocated. We
|
|
|
|
* don't check for '\0' as our directory names all end in '/'.
|
|
|
|
*/
|
|
|
|
if (!(fn[len] == '/' || fnlen == len))
|
|
|
|
/*@innercontinue@*/ continue;
|
|
|
|
|
|
|
|
if (strncmp(relocations[j].oldPath, fn, len))
|
|
|
|
/*@innercontinue@*/ continue;
|
|
|
|
/*@innerbreak@*/ break;
|
|
|
|
}
|
|
|
|
if (j < 0) continue;
|
|
|
|
|
|
|
|
ft = whatis(fModes[i]);
|
|
|
|
|
|
|
|
/* On install, a relocate to NULL means skip the path. */
|
|
|
|
if (relocations[j].newPath == NULL) {
|
|
|
|
if (ft == XDIR) {
|
|
|
|
/* Start with the parent, looking for directory to exclude. */
|
|
|
|
for (j = dirIndexes[i]; j < dirCount; j++) {
|
|
|
|
len = strlen(dirNames[j]) - 1;
|
|
|
|
while (len > 0 && dirNames[j][len-1] == '/') len--;
|
|
|
|
if (fnlen != len)
|
|
|
|
/*@innercontinue@*/ continue;
|
|
|
|
if (strncmp(fn, dirNames[j], fnlen))
|
|
|
|
/*@innercontinue@*/ continue;
|
|
|
|
/*@innerbreak@*/ break;
|
|
|
|
}
|
|
|
|
if (j < dirCount)
|
|
|
|
skipDirList[j] = 1;
|
|
|
|
}
|
|
|
|
if (actions) {
|
|
|
|
actions[i] = FA_SKIPNSTATE;
|
|
|
|
rpmMessage(RPMMESS_DEBUG, _("excluding %s %s\n"),
|
|
|
|
ftstring(ft), fn);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Relocation on full paths only, please. */
|
|
|
|
if (fnlen != len) continue;
|
|
|
|
|
|
|
|
if (actions)
|
|
|
|
rpmMessage(RPMMESS_DEBUG, _("relocating %s to %s\n"),
|
|
|
|
fn, relocations[j].newPath);
|
|
|
|
nrelocated++;
|
|
|
|
|
|
|
|
strcpy(fn, relocations[j].newPath);
|
|
|
|
{ char * te = strrchr(fn, '/');
|
|
|
|
if (te) {
|
|
|
|
if (te > fn) te++; /* root is special */
|
|
|
|
fnlen = te - fn;
|
|
|
|
} else
|
|
|
|
te = fn + strlen(fn);
|
|
|
|
/*@-nullpass -nullderef@*/ /* LCL: te != NULL here. */
|
|
|
|
if (strcmp(baseNames[i], te)) /* basename changed too? */
|
|
|
|
baseNames[i] = alloca_strdup(te);
|
|
|
|
*te = '\0'; /* terminate new directory name */
|
|
|
|
/*@=nullpass =nullderef@*/
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Does this directory already exist in the directory list? */
|
|
|
|
for (j = 0; j < dirCount; j++) {
|
|
|
|
if (fnlen != strlen(dirNames[j]))
|
|
|
|
/*@innercontinue@*/ continue;
|
|
|
|
if (strncmp(fn, dirNames[j], fnlen))
|
|
|
|
/*@innercontinue@*/ continue;
|
|
|
|
/*@innerbreak@*/ break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (j < dirCount) {
|
|
|
|
dirIndexes[i] = j;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Creating new paths is a pita */
|
|
|
|
if (!haveRelocatedFile) {
|
|
|
|
const char ** newDirList;
|
|
|
|
|
|
|
|
haveRelocatedFile = 1;
|
|
|
|
newDirList = xmalloc((dirCount + 1) * sizeof(*newDirList));
|
|
|
|
for (j = 0; j < dirCount; j++)
|
|
|
|
newDirList[j] = alloca_strdup(dirNames[j]);
|
|
|
|
dirNames = hfd(dirNames, RPM_STRING_ARRAY_TYPE);
|
|
|
|
dirNames = newDirList;
|
|
|
|
} else {
|
|
|
|
dirNames = xrealloc(dirNames,
|
|
|
|
sizeof(*dirNames) * (dirCount + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
dirNames[dirCount] = alloca_strdup(fn);
|
|
|
|
dirIndexes[i] = dirCount;
|
|
|
|
dirCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Finish off by relocating directories. */
|
|
|
|
for (i = dirCount - 1; i >= 0; i--) {
|
|
|
|
for (j = numRelocations - 1; j >= 0; j--) {
|
|
|
|
|
|
|
|
if (relocations[j].oldPath == NULL) /* XXX can't happen */
|
|
|
|
/*@innercontinue@*/ continue;
|
|
|
|
len = strcmp(relocations[j].oldPath, "/")
|
|
|
|
? strlen(relocations[j].oldPath)
|
|
|
|
: 0;
|
|
|
|
|
|
|
|
if (len && strncmp(relocations[j].oldPath, dirNames[i], len))
|
|
|
|
/*@innercontinue@*/ continue;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Only subdirectories or complete file paths may be relocated. We
|
|
|
|
* don't check for '\0' as our directory names all end in '/'.
|
|
|
|
*/
|
|
|
|
if (dirNames[i][len] != '/')
|
|
|
|
/*@innercontinue@*/ continue;
|
|
|
|
|
|
|
|
if (relocations[j].newPath) { /* Relocate the path */
|
|
|
|
const char * s = relocations[j].newPath;
|
|
|
|
char * t = alloca(strlen(s) + strlen(dirNames[i]) - len + 1);
|
|
|
|
|
|
|
|
(void) stpcpy( stpcpy(t, s) , dirNames[i] + len);
|
|
|
|
if (actions)
|
|
|
|
rpmMessage(RPMMESS_DEBUG,
|
|
|
|
_("relocating directory %s to %s\n"), dirNames[i], t);
|
|
|
|
dirNames[i] = t;
|
|
|
|
nrelocated++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Save original filenames in header and replace (relocated) filenames. */
|
|
|
|
if (nrelocated) {
|
|
|
|
int c;
|
|
|
|
void * p;
|
|
|
|
rpmTagType t;
|
|
|
|
|
|
|
|
p = NULL;
|
|
|
|
xx = hge(h, RPMTAG_BASENAMES, &t, &p, &c);
|
|
|
|
xx = hae(h, RPMTAG_ORIGBASENAMES, t, p, c);
|
|
|
|
p = hfd(p, t);
|
|
|
|
|
|
|
|
p = NULL;
|
|
|
|
xx = hge(h, RPMTAG_DIRNAMES, &t, &p, &c);
|
|
|
|
xx = hae(h, RPMTAG_ORIGDIRNAMES, t, p, c);
|
|
|
|
p = hfd(p, t);
|
|
|
|
|
|
|
|
p = NULL;
|
|
|
|
xx = hge(h, RPMTAG_DIRINDEXES, &t, &p, &c);
|
|
|
|
xx = hae(h, RPMTAG_ORIGDIRINDEXES, t, p, c);
|
|
|
|
p = hfd(p, t);
|
|
|
|
|
|
|
|
xx = hme(h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE,
|
|
|
|
baseNames, fileCount);
|
|
|
|
fi->bnl = hfd(fi->bnl, RPM_STRING_ARRAY_TYPE);
|
|
|
|
xx = hge(h, RPMTAG_BASENAMES, NULL, (void **) &fi->bnl, &fi->fc);
|
|
|
|
|
|
|
|
xx = hme(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
|
|
|
|
dirNames, dirCount);
|
|
|
|
fi->dnl = hfd(fi->dnl, RPM_STRING_ARRAY_TYPE);
|
|
|
|
xx = hge(h, RPMTAG_DIRNAMES, NULL, (void **) &fi->dnl, &fi->dc);
|
|
|
|
|
|
|
|
xx = hme(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE,
|
|
|
|
dirIndexes, fileCount);
|
|
|
|
xx = hge(h, RPMTAG_DIRINDEXES, NULL, (void **) &fi->dil, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
baseNames = hfd(baseNames, RPM_STRING_ARRAY_TYPE);
|
|
|
|
dirNames = hfd(dirNames, RPM_STRING_ARRAY_TYPE);
|
|
|
|
fn = _free(fn);
|
|
|
|
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
|
|
|
void loadFi(const rpmTransactionSet ts, TFI_t fi, Header h, int scareMem)
|
2001-02-11 00:47:40 +08:00
|
|
|
{
|
|
|
|
HGE_t hge;
|
|
|
|
HFD_t hfd;
|
|
|
|
uint_32 * uip;
|
|
|
|
int len;
|
|
|
|
int rc;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (fi->fsm == NULL)
|
|
|
|
fi->fsm = newFSM();
|
|
|
|
|
|
|
|
/* XXX avoid gcc noise on pointer (4th arg) cast(s) */
|
2001-10-19 00:39:54 +08:00
|
|
|
hge = (scareMem && fi->type == TR_ADDED)
|
2001-02-11 00:47:40 +08:00
|
|
|
? (HGE_t) headerGetEntryMinMemory : (HGE_t) headerGetEntry;
|
|
|
|
fi->hge = hge;
|
2001-06-12 12:10:21 +08:00
|
|
|
fi->hae = (HAE_t) headerAddEntry;
|
|
|
|
fi->hme = (HME_t) headerModifyEntry;
|
|
|
|
fi->hre = (HRE_t) headerRemoveEntry;
|
2001-02-11 00:47:40 +08:00
|
|
|
fi->hfd = hfd = headerFreeData;
|
|
|
|
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
2001-02-11 00:47:40 +08:00
|
|
|
if (h && fi->h == NULL) fi->h = headerLink(h);
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
2001-02-11 00:47:40 +08:00
|
|
|
|
|
|
|
/* Duplicate name-version-release so that headers can be free'd. */
|
2001-05-01 06:32:22 +08:00
|
|
|
rc = hge(fi->h, RPMTAG_NAME, NULL, (void **) &fi->name, NULL);
|
2001-02-11 00:47:40 +08:00
|
|
|
fi->name = xstrdup(fi->name);
|
2001-05-01 06:32:22 +08:00
|
|
|
rc = hge(fi->h, RPMTAG_VERSION, NULL, (void **) &fi->version, NULL);
|
2001-02-11 00:47:40 +08:00
|
|
|
fi->version = xstrdup(fi->version);
|
2001-05-01 06:32:22 +08:00
|
|
|
rc = hge(fi->h, RPMTAG_RELEASE, NULL, (void **) &fi->release, NULL);
|
2001-02-11 00:47:40 +08:00
|
|
|
fi->release = xstrdup(fi->release);
|
|
|
|
|
|
|
|
/* -1 means not found */
|
|
|
|
rc = hge(fi->h, RPMTAG_EPOCH, NULL, (void **) &uip, NULL);
|
|
|
|
fi->epoch = (rc ? *uip : -1);
|
2001-10-19 00:39:54 +08:00
|
|
|
|
2001-02-11 00:47:40 +08:00
|
|
|
/* 0 means unknown */
|
|
|
|
rc = hge(fi->h, RPMTAG_ARCHIVESIZE, NULL, (void **) &uip, NULL);
|
|
|
|
fi->archiveSize = (rc ? *uip : 0);
|
|
|
|
|
|
|
|
if (!hge(fi->h, RPMTAG_BASENAMES, NULL, (void **) &fi->bnl, &fi->fc)) {
|
|
|
|
fi->dc = 0;
|
|
|
|
fi->fc = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
rc = hge(fi->h, RPMTAG_DIRNAMES, NULL, (void **) &fi->dnl, &fi->dc);
|
2001-10-19 00:39:54 +08:00
|
|
|
|
|
|
|
rc = hge(fi->h, RPMTAG_DIRINDEXES, NULL, (void **) &fi->dil, NULL);
|
2001-05-01 06:32:22 +08:00
|
|
|
rc = hge(fi->h, RPMTAG_FILEMODES, NULL, (void **) &fi->fmodes, NULL);
|
|
|
|
rc = hge(fi->h, RPMTAG_FILEFLAGS, NULL, (void **) &fi->fflags, NULL);
|
|
|
|
rc = hge(fi->h, RPMTAG_FILESIZES, NULL, (void **) &fi->fsizes, NULL);
|
2001-10-19 00:39:54 +08:00
|
|
|
|
|
|
|
/* XXX initialized to NULL for TR_ADDED? */
|
2001-05-01 06:32:22 +08:00
|
|
|
rc = hge(fi->h, RPMTAG_FILESTATES, NULL, (void **) &fi->fstates, NULL);
|
2001-02-11 00:47:40 +08:00
|
|
|
|
|
|
|
fi->action = FA_UNKNOWN;
|
|
|
|
fi->flags = 0;
|
|
|
|
|
|
|
|
/* actions is initialized earlier for added packages */
|
|
|
|
if (fi->actions == NULL)
|
|
|
|
fi->actions = xcalloc(fi->fc, sizeof(*fi->actions));
|
|
|
|
|
|
|
|
switch (fi->type) {
|
|
|
|
case TR_ADDED:
|
2001-06-26 04:01:42 +08:00
|
|
|
fi->mapflags =
|
|
|
|
CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
|
2001-05-01 06:32:22 +08:00
|
|
|
rc = hge(fi->h, RPMTAG_FILELINKTOS, NULL, (void **) &fi->flinks, NULL);
|
|
|
|
rc = hge(fi->h, RPMTAG_FILELANGS, NULL, (void **) &fi->flangs, NULL);
|
2001-10-19 00:39:54 +08:00
|
|
|
|
|
|
|
rc = hge(fi->h, RPMTAG_FILEMD5S, NULL, (void **) &fi->fmd5s, NULL);
|
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
rc = hge(fi->h, RPMTAG_FILEMTIMES, NULL, (void **) &fi->fmtimes, NULL);
|
2001-07-18 18:49:09 +08:00
|
|
|
rc = hge(fi->h, RPMTAG_FILERDEVS, NULL, (void **) &fi->frdevs, NULL);
|
2001-02-11 00:47:40 +08:00
|
|
|
|
|
|
|
/* 0 makes for noops */
|
|
|
|
fi->replacedSizes = xcalloc(fi->fc, sizeof(*fi->replacedSizes));
|
|
|
|
|
2001-10-26 12:16:19 +08:00
|
|
|
if (ts != NULL && fi->ap != NULL && fi->h != NULL)
|
2001-10-19 00:39:54 +08:00
|
|
|
{ Header foo = relocateFileList(ts, fi, fi->ap, fi->h, fi->actions);
|
|
|
|
foo = headerFree(foo);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!scareMem) {
|
|
|
|
|
|
|
|
fprintf(stderr, "*** %s-%s-%s scareMem\n", fi->name, fi->version, fi->release);
|
|
|
|
fi->fmtimes = memcpy(xmalloc(fi->fc * sizeof(*fi->fmtimes)),
|
|
|
|
fi->fmtimes, fi->fc * sizeof(*fi->fmtimes));
|
|
|
|
fi->frdevs = memcpy(xmalloc(fi->fc * sizeof(*fi->frdevs)),
|
|
|
|
fi->frdevs, fi->fc * sizeof(*fi->frdevs));
|
|
|
|
|
|
|
|
fi->fsizes = memcpy(xmalloc(fi->fc * sizeof(*fi->fsizes)),
|
|
|
|
fi->fsizes, fi->fc * sizeof(*fi->fsizes));
|
|
|
|
fi->fflags = memcpy(xmalloc(fi->fc * sizeof(*fi->fflags)),
|
|
|
|
fi->fflags, fi->fc * sizeof(*fi->fflags));
|
|
|
|
fi->fmodes = memcpy(xmalloc(fi->fc * sizeof(*fi->fmodes)),
|
|
|
|
fi->fmodes, fi->fc * sizeof(*fi->fmodes));
|
|
|
|
/* XXX there's a tedious segfault here for some version(s) of rpm */
|
|
|
|
if (fi->fstates)
|
|
|
|
fi->fstates = memcpy(xmalloc(fi->fc * sizeof(*fi->fstates)),
|
|
|
|
fi->fstates, fi->fc * sizeof(*fi->fstates));
|
|
|
|
else
|
|
|
|
fi->fstates = xcalloc(1, fi->fc * sizeof(*fi->fstates));
|
|
|
|
fi->dil = memcpy(xmalloc(fi->fc * sizeof(*fi->dil)),
|
|
|
|
fi->dil, fi->fc * sizeof(*fi->dil));
|
|
|
|
fi->h = headerFree(fi->h);
|
|
|
|
}
|
|
|
|
|
2001-02-11 00:47:40 +08:00
|
|
|
break;
|
|
|
|
case TR_REMOVED:
|
2001-06-26 04:01:42 +08:00
|
|
|
fi->mapflags =
|
|
|
|
CPIO_MAP_ABSOLUTE | CPIO_MAP_ADDDOT | CPIO_ALL_HARDLINKS |
|
|
|
|
CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
|
2001-05-01 06:32:22 +08:00
|
|
|
rc = hge(fi->h, RPMTAG_FILEMD5S, NULL, (void **) &fi->fmd5s, NULL);
|
|
|
|
rc = hge(fi->h, RPMTAG_FILELINKTOS, NULL, (void **) &fi->flinks, NULL);
|
2001-02-11 00:47:40 +08:00
|
|
|
fi->fsizes = memcpy(xmalloc(fi->fc * sizeof(*fi->fsizes)),
|
|
|
|
fi->fsizes, fi->fc * sizeof(*fi->fsizes));
|
|
|
|
fi->fflags = memcpy(xmalloc(fi->fc * sizeof(*fi->fflags)),
|
|
|
|
fi->fflags, fi->fc * sizeof(*fi->fflags));
|
|
|
|
fi->fmodes = memcpy(xmalloc(fi->fc * sizeof(*fi->fmodes)),
|
|
|
|
fi->fmodes, fi->fc * sizeof(*fi->fmodes));
|
|
|
|
/* XXX there's a tedious segfault here for some version(s) of rpm */
|
|
|
|
if (fi->fstates)
|
|
|
|
fi->fstates = memcpy(xmalloc(fi->fc * sizeof(*fi->fstates)),
|
|
|
|
fi->fstates, fi->fc * sizeof(*fi->fstates));
|
|
|
|
else
|
|
|
|
fi->fstates = xcalloc(1, fi->fc * sizeof(*fi->fstates));
|
|
|
|
fi->dil = memcpy(xmalloc(fi->fc * sizeof(*fi->dil)),
|
|
|
|
fi->dil, fi->fc * sizeof(*fi->dil));
|
2001-05-23 22:25:19 +08:00
|
|
|
fi->h = headerFree(fi->h);
|
2001-02-11 00:47:40 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
fi->dnlmax = -1;
|
|
|
|
for (i = 0; i < fi->dc; i++) {
|
|
|
|
if ((len = strlen(fi->dnl[i])) > fi->dnlmax)
|
|
|
|
fi->dnlmax = len;
|
|
|
|
}
|
|
|
|
|
|
|
|
fi->bnlmax = -1;
|
|
|
|
for (i = 0; i < fi->fc; i++) {
|
|
|
|
if ((len = strlen(fi->bnl[i])) > fi->bnlmax)
|
|
|
|
fi->bnlmax = len;
|
|
|
|
}
|
|
|
|
|
|
|
|
fi->dperms = 0755;
|
|
|
|
fi->fperms = 0644;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void freeFi(TFI_t fi)
|
|
|
|
{
|
|
|
|
HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
|
|
|
|
|
|
|
|
fi->name = _free(fi->name);
|
|
|
|
fi->version = _free(fi->version);
|
|
|
|
fi->release = _free(fi->release);
|
|
|
|
fi->actions = _free(fi->actions);
|
|
|
|
fi->replacedSizes = _free(fi->replacedSizes);
|
|
|
|
fi->replaced = _free(fi->replaced);
|
|
|
|
|
|
|
|
fi->bnl = hfd(fi->bnl, -1);
|
|
|
|
fi->dnl = hfd(fi->dnl, -1);
|
|
|
|
fi->obnl = hfd(fi->obnl, -1);
|
|
|
|
fi->odnl = hfd(fi->odnl, -1);
|
|
|
|
fi->flinks = hfd(fi->flinks, -1);
|
|
|
|
fi->fmd5s = hfd(fi->fmd5s, -1);
|
|
|
|
fi->fuser = hfd(fi->fuser, -1);
|
|
|
|
fi->fgroup = hfd(fi->fgroup, -1);
|
|
|
|
fi->flangs = hfd(fi->flangs, -1);
|
|
|
|
|
|
|
|
fi->apath = _free(fi->apath);
|
|
|
|
fi->fuids = _free(fi->fuids);
|
|
|
|
fi->fgids = _free(fi->fgids);
|
|
|
|
fi->fmapflags = _free(fi->fmapflags);
|
|
|
|
|
|
|
|
fi->fsm = freeFSM(fi->fsm);
|
|
|
|
|
|
|
|
switch (fi->type) {
|
|
|
|
case TR_ADDED:
|
2001-10-19 00:39:54 +08:00
|
|
|
if (fi->h == NULL) {
|
|
|
|
fi->fmtimes = hfd(fi->fmtimes, -1);
|
|
|
|
fi->frdevs = hfd(fi->frdevs, -1);
|
|
|
|
fi->fsizes = hfd(fi->fsizes, -1);
|
|
|
|
fi->fflags = hfd(fi->fflags, -1);
|
|
|
|
fi->fmodes = hfd(fi->fmodes, -1);
|
|
|
|
fi->fstates = hfd(fi->fstates, -1);
|
|
|
|
fi->dil = hfd(fi->dil, -1);
|
|
|
|
}
|
|
|
|
break;
|
2001-02-11 00:47:40 +08:00
|
|
|
case TR_REMOVED:
|
|
|
|
fi->fsizes = hfd(fi->fsizes, -1);
|
|
|
|
fi->fflags = hfd(fi->fflags, -1);
|
|
|
|
fi->fmodes = hfd(fi->fmodes, -1);
|
|
|
|
fi->fstates = hfd(fi->fstates, -1);
|
|
|
|
fi->dil = hfd(fi->dil, -1);
|
|
|
|
break;
|
|
|
|
}
|
2001-05-23 22:25:19 +08:00
|
|
|
|
|
|
|
fi->h = headerFree(fi->h);
|
2001-05-04 05:00:18 +08:00
|
|
|
|
2001-09-25 05:53:14 +08:00
|
|
|
/*@-nullstate@*/ /* FIX: fi->{name,version,release,actions,...,h} NULL */
|
2001-05-04 05:00:18 +08:00
|
|
|
return;
|
|
|
|
/*@=nullstate@*/
|
2001-02-11 00:47:40 +08:00
|
|
|
}
|
|
|
|
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@observer@*/ const char *const fiTypeString(TFI_t fi)
|
|
|
|
{
|
2001-02-11 00:47:40 +08:00
|
|
|
switch(fi->type) {
|
|
|
|
case TR_ADDED: return " install";
|
|
|
|
case TR_REMOVED: return " erase";
|
|
|
|
default: return "???";
|
|
|
|
}
|
|
|
|
/*@noteached@*/
|
|
|
|
}
|
|
|
|
|
2000-08-23 21:02:13 +08:00
|
|
|
/**
|
|
|
|
* Macros to be defined from per-header tag values.
|
2001-01-26 04:26:35 +08:00
|
|
|
* @todo Should other macros be added from header when installing a package?
|
2000-08-23 21:02:13 +08:00
|
|
|
*/
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@observer@*/ /*@unchecked@*/
|
1999-04-03 08:05:03 +08:00
|
|
|
static struct tagMacro {
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@observer@*/ /*@null@*/ const char * macroname; /*!< Macro name to define. */
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmTag tag; /*!< Header tag to use for value. */
|
1999-04-03 08:05:03 +08:00
|
|
|
} tagMacros[] = {
|
2001-06-06 03:26:22 +08:00
|
|
|
{ "name", RPMTAG_NAME },
|
|
|
|
{ "version", RPMTAG_VERSION },
|
|
|
|
{ "release", RPMTAG_RELEASE },
|
|
|
|
{ "epoch", RPMTAG_EPOCH },
|
|
|
|
{ NULL, 0 }
|
1999-04-03 08:05:03 +08:00
|
|
|
};
|
|
|
|
|
2000-08-23 21:02:13 +08:00
|
|
|
/**
|
|
|
|
* Define per-header macros.
|
2001-06-12 12:10:21 +08:00
|
|
|
* @param fi transaction element file info
|
2000-08-23 21:02:13 +08:00
|
|
|
* @param h header
|
|
|
|
* @return 0 always
|
|
|
|
*/
|
2001-02-06 06:22:43 +08:00
|
|
|
static int rpmInstallLoadMacros(TFI_t fi, Header h)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals rpmGlobalMacroContext, internalState @*/
|
|
|
|
/*@modifies rpmGlobalMacroContext, internalState @*/
|
1999-07-14 06:53:46 +08:00
|
|
|
{
|
2001-06-12 12:10:21 +08:00
|
|
|
HGE_t hge = (HGE_t) fi->hge;
|
|
|
|
struct tagMacro * tagm;
|
2000-05-13 07:30:28 +08:00
|
|
|
union {
|
2001-06-12 12:10:21 +08:00
|
|
|
/*@unused@*/ void * ptr;
|
|
|
|
/*@unused@*/ const char ** argv;
|
|
|
|
const char * str;
|
2001-01-21 23:43:32 +08:00
|
|
|
int_32 * i32p;
|
2000-05-13 07:30:28 +08:00
|
|
|
} body;
|
1999-08-09 22:28:13 +08:00
|
|
|
char numbuf[32];
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmTagType type;
|
1999-04-03 08:05:03 +08:00
|
|
|
|
|
|
|
for (tagm = tagMacros; tagm->macroname != NULL; tagm++) {
|
2001-02-06 06:22:43 +08:00
|
|
|
if (!hge(h, tagm->tag, &type, (void **) &body, NULL))
|
1999-08-09 22:28:13 +08:00
|
|
|
continue;
|
|
|
|
switch (type) {
|
|
|
|
case RPM_INT32_TYPE:
|
2001-01-21 23:43:32 +08:00
|
|
|
sprintf(numbuf, "%d", *body.i32p);
|
2000-05-13 07:30:28 +08:00
|
|
|
addMacro(NULL, tagm->macroname, NULL, numbuf, -1);
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1999-08-09 22:28:13 +08:00
|
|
|
case RPM_STRING_TYPE:
|
2001-06-12 12:10:21 +08:00
|
|
|
addMacro(NULL, tagm->macroname, NULL, body.str, -1);
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
2001-06-12 12:10:21 +08:00
|
|
|
case RPM_NULL_TYPE:
|
|
|
|
case RPM_CHAR_TYPE:
|
|
|
|
case RPM_INT8_TYPE:
|
|
|
|
case RPM_INT16_TYPE:
|
|
|
|
case RPM_BIN_TYPE:
|
|
|
|
case RPM_STRING_ARRAY_TYPE:
|
|
|
|
case RPM_I18NSTRING_TYPE:
|
|
|
|
default:
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1999-04-03 08:05:03 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2000-08-23 21:02:13 +08:00
|
|
|
/**
|
2000-10-24 21:46:51 +08:00
|
|
|
* Copy file data from h to newH.
|
|
|
|
* @param h header from
|
|
|
|
* @param newH header to
|
|
|
|
* @param actions array of file dispositions
|
2001-01-04 04:19:27 +08:00
|
|
|
* @return 0 on success, 1 on failure
|
2000-08-23 21:02:13 +08:00
|
|
|
*/
|
2001-02-06 06:22:43 +08:00
|
|
|
static int mergeFiles(TFI_t fi, Header h, Header newH)
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@modifies h @*/
|
2000-07-06 04:39:15 +08:00
|
|
|
{
|
2001-02-06 06:22:43 +08:00
|
|
|
HGE_t hge = (HGE_t)fi->hge;
|
2001-06-12 12:10:21 +08:00
|
|
|
HME_t hme = (HME_t)fi->hme;
|
2001-05-04 05:00:18 +08:00
|
|
|
HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
|
2001-01-28 01:42:24 +08:00
|
|
|
fileAction * actions = fi->actions;
|
2001-10-16 22:58:57 +08:00
|
|
|
int i, j, k, fc, xx;
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmTagType type = 0;
|
2001-01-27 01:06:09 +08:00
|
|
|
int_32 count = 0;
|
|
|
|
int_32 dirNamesCount, dirCount;
|
2000-07-06 04:39:15 +08:00
|
|
|
void * data, * newdata;
|
|
|
|
int_32 * dirIndexes, * newDirIndexes;
|
|
|
|
uint_32 * fileSizes, fileSize;
|
2001-01-27 01:06:09 +08:00
|
|
|
const char ** dirNames;
|
|
|
|
const char ** newDirNames;
|
2001-06-12 12:10:21 +08:00
|
|
|
static rpmTag mergeTags[] = {
|
2000-07-06 04:39:15 +08:00
|
|
|
RPMTAG_FILESIZES,
|
|
|
|
RPMTAG_FILESTATES,
|
|
|
|
RPMTAG_FILEMODES,
|
|
|
|
RPMTAG_FILERDEVS,
|
|
|
|
RPMTAG_FILEMTIMES,
|
|
|
|
RPMTAG_FILEMD5S,
|
|
|
|
RPMTAG_FILELINKTOS,
|
|
|
|
RPMTAG_FILEFLAGS,
|
|
|
|
RPMTAG_FILEUSERNAME,
|
|
|
|
RPMTAG_FILEGROUPNAME,
|
|
|
|
RPMTAG_FILEVERIFYFLAGS,
|
|
|
|
RPMTAG_FILEDEVICES,
|
|
|
|
RPMTAG_FILEINODES,
|
|
|
|
RPMTAG_FILELANGS,
|
|
|
|
RPMTAG_BASENAMES,
|
|
|
|
0,
|
|
|
|
};
|
2001-06-12 12:10:21 +08:00
|
|
|
static rpmTag requireTags[] = {
|
2000-07-06 04:39:15 +08:00
|
|
|
RPMTAG_REQUIRENAME, RPMTAG_REQUIREVERSION, RPMTAG_REQUIREFLAGS,
|
|
|
|
RPMTAG_PROVIDENAME, RPMTAG_PROVIDEVERSION, RPMTAG_PROVIDEFLAGS,
|
|
|
|
RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTVERSION, RPMTAG_CONFLICTFLAGS
|
|
|
|
};
|
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = hge(h, RPMTAG_SIZE, NULL, (void **) &fileSizes, NULL);
|
2000-07-06 04:39:15 +08:00
|
|
|
fileSize = *fileSizes;
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = hge(newH, RPMTAG_FILESIZES, NULL, (void **) &fileSizes, &count);
|
2001-01-24 07:03:28 +08:00
|
|
|
for (i = 0, fc = 0; i < count; i++)
|
2000-07-06 04:39:15 +08:00
|
|
|
if (actions[i] != FA_SKIPMULTILIB) {
|
2001-01-24 07:03:28 +08:00
|
|
|
fc++;
|
2000-07-06 04:39:15 +08:00
|
|
|
fileSize += fileSizes[i];
|
|
|
|
}
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = hme(h, RPMTAG_SIZE, RPM_INT32_TYPE, &fileSize, 1);
|
2001-02-06 06:22:43 +08:00
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
/*@-sizeoftype@*/
|
2000-12-03 05:53:44 +08:00
|
|
|
for (i = 0; mergeTags[i]; i++) {
|
2001-02-06 06:22:43 +08:00
|
|
|
if (!hge(newH, mergeTags[i], &type, (void **) &data, &count))
|
2000-12-03 05:53:44 +08:00
|
|
|
continue;
|
|
|
|
switch (type) {
|
|
|
|
case RPM_CHAR_TYPE:
|
|
|
|
case RPM_INT8_TYPE:
|
2001-09-25 05:53:14 +08:00
|
|
|
newdata = xcalloc(fc, sizeof(int_8));
|
2000-12-03 05:53:44 +08:00
|
|
|
for (j = 0, k = 0; j < count; j++)
|
|
|
|
if (actions[j] != FA_SKIPMULTILIB)
|
2000-07-06 04:39:15 +08:00
|
|
|
((int_8 *) newdata)[k++] = ((int_8 *) data)[j];
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerAddOrAppendEntry(h, mergeTags[i], type, newdata, fc);
|
2000-12-03 05:53:44 +08:00
|
|
|
free (newdata);
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
2000-12-03 05:53:44 +08:00
|
|
|
case RPM_INT16_TYPE:
|
2001-09-25 05:53:14 +08:00
|
|
|
newdata = xcalloc(fc, sizeof(int_16));
|
2000-12-03 05:53:44 +08:00
|
|
|
for (j = 0, k = 0; j < count; j++)
|
|
|
|
if (actions[j] != FA_SKIPMULTILIB)
|
|
|
|
((int_16 *) newdata)[k++] = ((int_16 *) data)[j];
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerAddOrAppendEntry(h, mergeTags[i], type, newdata, fc);
|
2000-12-03 05:53:44 +08:00
|
|
|
free (newdata);
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
2000-12-03 05:53:44 +08:00
|
|
|
case RPM_INT32_TYPE:
|
2001-09-25 05:53:14 +08:00
|
|
|
newdata = xcalloc(fc, sizeof(int_32));
|
2000-12-03 05:53:44 +08:00
|
|
|
for (j = 0, k = 0; j < count; j++)
|
|
|
|
if (actions[j] != FA_SKIPMULTILIB)
|
|
|
|
((int_32 *) newdata)[k++] = ((int_32 *) data)[j];
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerAddOrAppendEntry(h, mergeTags[i], type, newdata, fc);
|
2000-12-03 05:53:44 +08:00
|
|
|
free (newdata);
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
2000-12-03 05:53:44 +08:00
|
|
|
case RPM_STRING_ARRAY_TYPE:
|
2001-09-25 05:53:14 +08:00
|
|
|
newdata = xcalloc(fc, sizeof(char *));
|
2000-12-03 05:53:44 +08:00
|
|
|
for (j = 0, k = 0; j < count; j++)
|
|
|
|
if (actions[j] != FA_SKIPMULTILIB)
|
|
|
|
((char **) newdata)[k++] = ((char **) data)[j];
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerAddOrAppendEntry(h, mergeTags[i], type, newdata, fc);
|
2000-12-03 05:53:44 +08:00
|
|
|
free (newdata);
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
2000-12-03 05:53:44 +08:00
|
|
|
default:
|
2001-01-04 04:19:27 +08:00
|
|
|
rpmError(RPMERR_DATATYPE, _("Data type %d not supported\n"),
|
|
|
|
(int) type);
|
|
|
|
return 1;
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@notreached@*/ /*@switchbreak@*/ break;
|
2000-12-03 05:53:44 +08:00
|
|
|
}
|
2001-02-06 06:22:43 +08:00
|
|
|
data = hfd(data, type);
|
2000-12-03 05:53:44 +08:00
|
|
|
}
|
2001-10-16 22:58:57 +08:00
|
|
|
/*@=sizeoftype@*/
|
|
|
|
xx = hge(newH, RPMTAG_DIRINDEXES, NULL, (void **) &newDirIndexes, &count);
|
|
|
|
xx = hge(newH, RPMTAG_DIRNAMES, NULL, (void **) &newDirNames, NULL);
|
|
|
|
xx = hge(h, RPMTAG_DIRINDEXES, NULL, (void **) &dirIndexes, NULL);
|
|
|
|
xx = hge(h, RPMTAG_DIRNAMES, NULL, (void **) &data, &dirNamesCount);
|
2000-07-06 04:39:15 +08:00
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
dirNames = xcalloc(dirNamesCount + fc, sizeof(*dirNames));
|
2000-07-06 04:39:15 +08:00
|
|
|
for (i = 0; i < dirNamesCount; i++)
|
|
|
|
dirNames[i] = ((char **) data)[i];
|
|
|
|
dirCount = dirNamesCount;
|
2001-10-16 22:58:57 +08:00
|
|
|
newdata = xcalloc(fc, sizeof(*newDirIndexes));
|
2000-12-03 05:53:44 +08:00
|
|
|
for (i = 0, k = 0; i < count; i++) {
|
|
|
|
if (actions[i] == FA_SKIPMULTILIB)
|
|
|
|
continue;
|
|
|
|
for (j = 0; j < dirCount; j++)
|
|
|
|
if (!strcmp(dirNames[j], newDirNames[newDirIndexes[i]]))
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@innerbreak@*/ break;
|
2000-12-03 05:53:44 +08:00
|
|
|
if (j == dirCount)
|
|
|
|
dirNames[dirCount++] = newDirNames[newDirIndexes[i]];
|
|
|
|
((int_32 *) newdata)[k++] = j;
|
|
|
|
}
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerAddOrAppendEntry(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, newdata, fc);
|
2000-07-06 04:39:15 +08:00
|
|
|
if (dirCount > dirNamesCount)
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerAddOrAppendEntry(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
|
2000-07-06 04:39:15 +08:00
|
|
|
dirNames + dirNamesCount,
|
|
|
|
dirCount - dirNamesCount);
|
2001-02-06 06:22:43 +08:00
|
|
|
data = hfd(data, -1);
|
|
|
|
newDirNames = hfd(newDirNames, -1);
|
2000-07-06 04:39:15 +08:00
|
|
|
free (newdata);
|
|
|
|
free (dirNames);
|
|
|
|
|
|
|
|
for (i = 0; i < 9; i += 3) {
|
2001-01-27 01:06:09 +08:00
|
|
|
const char **Names, **EVR, **newNames, **newEVR;
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmTagType nnt, nvt, rnt;
|
2000-07-06 04:39:15 +08:00
|
|
|
uint_32 *Flags, *newFlags;
|
|
|
|
int Count = 0, newCount = 0;
|
|
|
|
|
2001-02-06 06:22:43 +08:00
|
|
|
if (!hge(newH, requireTags[i], &nnt, (void **) &newNames, &newCount))
|
2000-12-03 05:53:44 +08:00
|
|
|
continue;
|
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = hge(newH, requireTags[i+1], &nvt, (void **) &newEVR, NULL);
|
|
|
|
xx = hge(newH, requireTags[i+2], NULL, (void **) &newFlags, NULL);
|
2001-02-06 06:22:43 +08:00
|
|
|
if (hge(h, requireTags[i], &rnt, (void **) &Names, &Count))
|
2000-12-03 05:53:44 +08:00
|
|
|
{
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = hge(h, requireTags[i+1], NULL, (void **) &EVR, NULL);
|
|
|
|
xx = hge(h, requireTags[i+2], NULL, (void **) &Flags, NULL);
|
2000-12-03 05:53:44 +08:00
|
|
|
for (j = 0; j < newCount; j++)
|
|
|
|
for (k = 0; k < Count; k++)
|
|
|
|
if (!strcmp (newNames[j], Names[k])
|
|
|
|
&& !strcmp (newEVR[j], EVR[k])
|
|
|
|
&& (newFlags[j] & RPMSENSE_SENSEMASK) ==
|
|
|
|
(Flags[k] & RPMSENSE_SENSEMASK))
|
|
|
|
{
|
|
|
|
newNames[j] = NULL;
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@innerbreak@*/ break;
|
2000-12-03 05:53:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for (j = 0, k = 0; j < newCount; j++) {
|
|
|
|
if (!newNames[j] || !isDependsMULTILIB(newFlags[j]))
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@innercontinue@*/ continue;
|
2000-12-03 05:53:44 +08:00
|
|
|
if (j != k) {
|
|
|
|
newNames[k] = newNames[j];
|
|
|
|
newEVR[k] = newEVR[j];
|
|
|
|
newFlags[k] = newFlags[j];
|
2000-07-06 04:39:15 +08:00
|
|
|
}
|
2000-12-03 05:53:44 +08:00
|
|
|
k++;
|
|
|
|
}
|
|
|
|
if (k) {
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerAddOrAppendEntry(h, requireTags[i],
|
2000-07-06 04:39:15 +08:00
|
|
|
RPM_STRING_ARRAY_TYPE, newNames, k);
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerAddOrAppendEntry(h, requireTags[i+1],
|
2000-07-06 04:39:15 +08:00
|
|
|
RPM_STRING_ARRAY_TYPE, newEVR, k);
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerAddOrAppendEntry(h, requireTags[i+2], RPM_INT32_TYPE,
|
2000-07-06 04:39:15 +08:00
|
|
|
newFlags, k);
|
|
|
|
}
|
2001-02-06 06:22:43 +08:00
|
|
|
newNames = hfd(newNames, nnt);
|
|
|
|
newEVR = hfd(newEVR, nvt);
|
|
|
|
Names = hfd(Names, rnt);
|
2000-07-06 04:39:15 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2000-10-24 21:46:51 +08:00
|
|
|
/**
|
2001-01-22 07:48:09 +08:00
|
|
|
* Mark files in database shared with this package as "replaced".
|
2001-03-03 00:17:03 +08:00
|
|
|
* @param psm package state machine data
|
2000-10-24 21:46:51 +08:00
|
|
|
* @return 0 always
|
|
|
|
*/
|
2001-03-03 00:17:03 +08:00
|
|
|
static int markReplacedFiles(PSM_t psm)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals fileSystem@*/
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@modifies psm, fileSystem @*/
|
1999-07-14 06:53:46 +08:00
|
|
|
{
|
2001-03-03 00:17:03 +08:00
|
|
|
const rpmTransactionSet ts = psm->ts;
|
|
|
|
TFI_t fi = psm->fi;
|
2001-02-06 06:22:43 +08:00
|
|
|
HGE_t hge = (HGE_t)fi->hge;
|
2001-01-22 07:48:09 +08:00
|
|
|
const struct sharedFileInfo * replaced = fi->replaced;
|
|
|
|
const struct sharedFileInfo * sfi;
|
2000-04-27 20:50:54 +08:00
|
|
|
rpmdbMatchIterator mi;
|
|
|
|
Header h;
|
|
|
|
unsigned int * offsets;
|
2000-07-16 00:00:14 +08:00
|
|
|
unsigned int prev;
|
2001-10-16 22:58:57 +08:00
|
|
|
int num, xx;
|
2000-04-27 20:50:54 +08:00
|
|
|
|
2001-01-22 07:48:09 +08:00
|
|
|
if (!(fi->fc > 0 && fi->replaced))
|
|
|
|
return 0;
|
|
|
|
|
2000-07-16 00:00:14 +08:00
|
|
|
num = prev = 0;
|
2001-01-22 07:48:09 +08:00
|
|
|
for (sfi = replaced; sfi->otherPkg; sfi++) {
|
|
|
|
if (prev && prev == sfi->otherPkg)
|
2000-07-16 00:00:14 +08:00
|
|
|
continue;
|
2001-01-22 07:48:09 +08:00
|
|
|
prev = sfi->otherPkg;
|
2000-04-27 20:50:54 +08:00
|
|
|
num++;
|
2000-07-16 00:00:14 +08:00
|
|
|
}
|
2000-07-16 02:15:23 +08:00
|
|
|
if (num == 0)
|
|
|
|
return 0;
|
2000-07-16 00:00:14 +08:00
|
|
|
|
2000-04-27 20:50:54 +08:00
|
|
|
offsets = alloca(num * sizeof(*offsets));
|
2000-07-16 00:00:14 +08:00
|
|
|
num = prev = 0;
|
2001-01-22 07:48:09 +08:00
|
|
|
for (sfi = replaced; sfi->otherPkg; sfi++) {
|
|
|
|
if (prev && prev == sfi->otherPkg)
|
2000-07-16 00:00:14 +08:00
|
|
|
continue;
|
2001-01-22 07:48:09 +08:00
|
|
|
prev = sfi->otherPkg;
|
|
|
|
offsets[num++] = sfi->otherPkg;
|
2000-07-16 00:00:14 +08:00
|
|
|
}
|
2000-04-27 20:50:54 +08:00
|
|
|
|
2001-03-03 00:17:03 +08:00
|
|
|
mi = rpmdbInitIterator(ts->rpmdb, RPMDBI_PACKAGES, NULL, 0);
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = rpmdbAppendIterator(mi, offsets, num);
|
|
|
|
xx = rpmdbSetIteratorRewrite(mi, 1);
|
2000-04-27 20:50:54 +08:00
|
|
|
|
2001-01-22 07:48:09 +08:00
|
|
|
sfi = replaced;
|
2000-04-27 20:50:54 +08:00
|
|
|
while ((h = rpmdbNextIterator(mi)) != NULL) {
|
|
|
|
char * secStates;
|
|
|
|
int modified;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
modified = 0;
|
2000-07-17 08:40:17 +08:00
|
|
|
|
2001-02-06 06:22:43 +08:00
|
|
|
if (!hge(h, RPMTAG_FILESTATES, NULL, (void **)&secStates, &count))
|
2000-07-17 08:40:17 +08:00
|
|
|
continue;
|
|
|
|
|
2000-07-16 00:00:14 +08:00
|
|
|
prev = rpmdbGetIteratorOffset(mi);
|
2000-07-16 02:15:23 +08:00
|
|
|
num = 0;
|
2001-01-22 07:48:09 +08:00
|
|
|
while (sfi->otherPkg && sfi->otherPkg == prev) {
|
|
|
|
assert(sfi->otherFileNum < count);
|
|
|
|
if (secStates[sfi->otherFileNum] != RPMFILE_STATE_REPLACED) {
|
|
|
|
secStates[sfi->otherFileNum] = RPMFILE_STATE_REPLACED;
|
2000-07-17 08:40:17 +08:00
|
|
|
if (modified == 0) {
|
|
|
|
/* Modified header will be rewritten. */
|
|
|
|
modified = 1;
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = rpmdbSetIteratorModified(mi, modified);
|
2000-07-17 08:40:17 +08:00
|
|
|
}
|
2000-07-16 02:15:23 +08:00
|
|
|
num++;
|
|
|
|
}
|
2001-01-22 07:48:09 +08:00
|
|
|
sfi++;
|
1999-07-14 06:53:46 +08:00
|
|
|
}
|
1997-07-16 09:44:27 +08:00
|
|
|
}
|
2001-04-30 06:43:01 +08:00
|
|
|
mi = rpmdbFreeIterator(mi);
|
1997-07-16 09:44:27 +08:00
|
|
|
|
1999-07-14 06:53:46 +08:00
|
|
|
return 0;
|
|
|
|
}
|
1998-01-29 00:49:43 +08:00
|
|
|
|
2001-02-13 03:02:15 +08:00
|
|
|
/**
|
2001-06-12 12:10:21 +08:00
|
|
|
* Create directory if it does not exist, make sure path is writable.
|
|
|
|
* @note This will only create last component of directory path.
|
|
|
|
* @param dpath directory path
|
|
|
|
* @param dname directory use
|
|
|
|
* @return rpmRC return code
|
2001-02-13 03:02:15 +08:00
|
|
|
*/
|
2001-02-28 21:59:29 +08:00
|
|
|
static rpmRC chkdir (const char * dpath, const char * dname)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals fileSystem@*/
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@modifies fileSystem @*/
|
2001-01-24 00:07:28 +08:00
|
|
|
{
|
|
|
|
struct stat st;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if ((rc = Stat(dpath, &st)) < 0) {
|
|
|
|
int ut = urlPath(dpath, NULL);
|
|
|
|
switch (ut) {
|
|
|
|
case URL_IS_PATH:
|
|
|
|
case URL_IS_UNKNOWN:
|
|
|
|
if (errno != ENOENT)
|
|
|
|
break;
|
|
|
|
/*@fallthrough@*/
|
|
|
|
case URL_IS_FTP:
|
|
|
|
case URL_IS_HTTP:
|
|
|
|
rc = Mkdir(dpath, 0755);
|
|
|
|
break;
|
|
|
|
case URL_IS_DASH:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (rc < 0) {
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmError(RPMERR_CREATE, _("cannot create %%%s %s\n"),
|
2001-01-24 00:07:28 +08:00
|
|
|
dname, dpath);
|
2001-02-13 03:02:15 +08:00
|
|
|
return RPMRC_FAIL;
|
2001-01-24 00:07:28 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((rc = Access(dpath, W_OK))) {
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmError(RPMERR_CREATE, _("cannot write to %%%s %s\n"), dname, dpath);
|
2001-02-13 03:02:15 +08:00
|
|
|
return RPMRC_FAIL;
|
2001-01-24 00:07:28 +08:00
|
|
|
}
|
2001-02-13 03:02:15 +08:00
|
|
|
return RPMRC_OK;
|
2001-01-24 00:07:28 +08:00
|
|
|
}
|
2001-01-25 20:58:03 +08:00
|
|
|
|
2001-10-26 12:16:19 +08:00
|
|
|
rpmRC rpmInstallSourcePackage(rpmTransactionSet ts,
|
|
|
|
FD_t fd,
|
|
|
|
const char ** specFilePtr,
|
|
|
|
rpmCallbackFunction notify, rpmCallbackData notifyData,
|
|
|
|
const char ** cookie)
|
1999-07-14 06:53:46 +08:00
|
|
|
{
|
2001-03-05 01:15:56 +08:00
|
|
|
TFI_t fi = xcalloc(sizeof(*fi), 1);
|
|
|
|
const char * _sourcedir = NULL;
|
|
|
|
const char * _specdir = NULL;
|
1999-09-18 06:01:34 +08:00
|
|
|
const char * specFile = NULL;
|
2001-03-05 01:15:56 +08:00
|
|
|
HGE_t hge;
|
|
|
|
HFD_t hfd;
|
2001-10-04 00:11:27 +08:00
|
|
|
Header h = NULL;
|
2001-03-05 01:15:56 +08:00
|
|
|
struct psm_s psmbuf;
|
|
|
|
PSM_t psm = &psmbuf;
|
|
|
|
int isSource;
|
|
|
|
rpmRC rc;
|
2001-10-26 12:16:19 +08:00
|
|
|
int i, xx;
|
1996-02-15 01:54:37 +08:00
|
|
|
|
2001-10-26 12:16:19 +08:00
|
|
|
/*@-mods -temptrans -assignexpose@*/
|
2001-03-05 01:15:56 +08:00
|
|
|
ts->notify = notify;
|
|
|
|
ts->notifyData = notifyData;
|
2001-10-26 12:16:19 +08:00
|
|
|
/*@=mods =temptrans =assignexpose@*/
|
1996-02-15 04:09:14 +08:00
|
|
|
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@-mustmod@*/ /* LCL: segfault */
|
2001-10-26 12:16:19 +08:00
|
|
|
xx = rpmReadPackageFile(ts, fd, "InstallSourcePackage", &h);
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@=mustmod@*/
|
2001-10-26 12:16:19 +08:00
|
|
|
if (xx || h == NULL) {
|
|
|
|
rc = RPMRC_FAIL; /* XXX HACK */
|
1999-01-06 07:13:56 +08:00
|
|
|
goto exit;
|
2001-10-26 12:16:19 +08:00
|
|
|
}
|
|
|
|
rc = RPMRC_OK; /* XXX HACK */
|
|
|
|
isSource = headerIsEntry(h, RPMTAG_SOURCEPACKAGE);
|
1997-02-12 13:05:13 +08:00
|
|
|
|
2001-03-05 01:15:56 +08:00
|
|
|
if (!isSource) {
|
|
|
|
rpmError(RPMERR_NOTSRPM, _("source package expected, binary found\n"));
|
2001-02-13 03:02:15 +08:00
|
|
|
rc = RPMRC_FAIL;
|
1999-01-06 07:13:56 +08:00
|
|
|
goto exit;
|
1997-02-12 13:05:13 +08:00
|
|
|
}
|
1996-02-15 01:54:37 +08:00
|
|
|
|
2001-03-05 01:15:56 +08:00
|
|
|
(void) rpmtransAddPackage(ts, h, fd, NULL, 0, NULL);
|
2001-05-04 05:00:18 +08:00
|
|
|
if (ts->addedPackages.list == NULL) { /* XXX can't happen */
|
|
|
|
rc = RPMRC_FAIL;
|
|
|
|
goto exit;
|
|
|
|
}
|
2001-03-05 01:15:56 +08:00
|
|
|
|
|
|
|
fi->type = TR_ADDED;
|
|
|
|
fi->ap = ts->addedPackages.list;
|
2001-10-19 00:39:54 +08:00
|
|
|
loadFi(ts, fi, h, 1);
|
2001-03-05 01:15:56 +08:00
|
|
|
hge = fi->hge;
|
2001-05-04 05:00:18 +08:00
|
|
|
hfd = (fi->hfd ? fi->hfd : headerFreeData);
|
2001-05-23 22:25:19 +08:00
|
|
|
h = headerFree(h); /* XXX reference held by transaction set */
|
2001-03-05 01:15:56 +08:00
|
|
|
|
2001-10-19 00:39:54 +08:00
|
|
|
if (fi->h != NULL) /* XXX can't happen */
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) rpmInstallLoadMacros(fi, fi->h);
|
2001-03-05 01:15:56 +08:00
|
|
|
|
|
|
|
memset(psm, 0, sizeof(*psm));
|
2001-10-26 12:16:19 +08:00
|
|
|
/*@-assignexpose@*/
|
2001-03-05 01:15:56 +08:00
|
|
|
psm->ts = ts;
|
|
|
|
psm->fi = fi;
|
2001-10-26 12:16:19 +08:00
|
|
|
/*@=assignexpose@*/
|
2001-03-05 01:15:56 +08:00
|
|
|
|
|
|
|
if (cookie) {
|
|
|
|
*cookie = NULL;
|
2001-05-23 22:25:19 +08:00
|
|
|
if (hge(fi->h, RPMTAG_COOKIE, NULL, (void **) cookie, NULL))
|
2001-03-05 01:15:56 +08:00
|
|
|
*cookie = xstrdup(*cookie);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX FIXME: can't do endian neutral MD5 verification yet. */
|
|
|
|
fi->fmd5s = hfd(fi->fmd5s, -1);
|
|
|
|
|
|
|
|
/* XXX FIXME: don't do per-file mapping, force global flags. */
|
2001-06-26 04:01:42 +08:00
|
|
|
fi->fmapflags = _free(fi->fmapflags);
|
2001-03-05 01:15:56 +08:00
|
|
|
fi->mapflags = CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
|
|
|
|
|
|
|
|
fi->uid = getuid();
|
|
|
|
fi->gid = getgid();
|
|
|
|
fi->astriplen = 0;
|
|
|
|
fi->striplen = 0;
|
|
|
|
|
|
|
|
fi->fuids = xcalloc(sizeof(*fi->fuids), fi->fc);
|
|
|
|
fi->fgids = xcalloc(sizeof(*fi->fgids), fi->fc);
|
|
|
|
for (i = 0; i < fi->fc; i++) {
|
|
|
|
fi->fuids[i] = fi->uid;
|
|
|
|
fi->fgids[i] = fi->gid;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < fi->fc; i++) {
|
|
|
|
fi->actions[i] = FA_CREATE;
|
|
|
|
}
|
|
|
|
|
2001-01-24 07:03:28 +08:00
|
|
|
i = fi->fc;
|
2001-10-19 00:39:54 +08:00
|
|
|
|
|
|
|
if (fi->h != NULL) { /* XXX can't happen */
|
|
|
|
rpmBuildFileList(fi->h, &fi->apath, NULL);
|
|
|
|
|
|
|
|
if (headerIsEntry(fi->h, RPMTAG_COOKIE))
|
|
|
|
for (i = 0; i < fi->fc; i++)
|
2001-01-24 23:58:35 +08:00
|
|
|
if (fi->fflags[i] & RPMFILE_SPECFILE) break;
|
2001-10-19 00:39:54 +08:00
|
|
|
}
|
1997-10-29 23:53:35 +08:00
|
|
|
|
2001-01-24 07:03:28 +08:00
|
|
|
if (i == fi->fc) {
|
2001-02-02 23:04:44 +08:00
|
|
|
/* Find the spec file by name. */
|
2001-01-24 23:58:35 +08:00
|
|
|
for (i = 0; i < fi->fc; i++) {
|
2001-01-24 07:03:28 +08:00
|
|
|
const char * t = fi->apath[i];
|
|
|
|
t += strlen(fi->apath[i]) - 5;
|
|
|
|
if (!strcmp(t, ".spec")) break;
|
1997-05-07 02:19:19 +08:00
|
|
|
}
|
2001-01-24 00:07:28 +08:00
|
|
|
}
|
1997-05-07 02:19:19 +08:00
|
|
|
|
2001-03-05 01:15:56 +08:00
|
|
|
_sourcedir = rpmGenPath(ts->rootDir, "%{_sourcedir}", "");
|
|
|
|
rc = chkdir(_sourcedir, "sourcedir");
|
|
|
|
if (rc) {
|
|
|
|
rc = RPMRC_FAIL;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
_specdir = rpmGenPath(ts->rootDir, "%{_specdir}", "");
|
|
|
|
rc = chkdir(_specdir, "specdir");
|
|
|
|
if (rc) {
|
|
|
|
rc = RPMRC_FAIL;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
2001-01-26 04:26:35 +08:00
|
|
|
/* Build dnl/dil with {_sourcedir, _specdir} as values. */
|
2001-01-24 07:03:28 +08:00
|
|
|
if (i < fi->fc) {
|
2001-01-26 04:26:35 +08:00
|
|
|
int speclen = strlen(_specdir) + 2;
|
|
|
|
int sourcelen = strlen(_sourcedir) + 2;
|
|
|
|
char * t;
|
|
|
|
|
2001-02-13 03:02:15 +08:00
|
|
|
fi->dnl = hfd(fi->dnl, -1);
|
2001-01-26 04:26:35 +08:00
|
|
|
|
|
|
|
fi->dc = 2;
|
|
|
|
fi->dnl = xmalloc(fi->dc * sizeof(*fi->dnl) + fi->fc * sizeof(*fi->dil) +
|
|
|
|
speclen + sourcelen);
|
|
|
|
fi->dil = (int *)(fi->dnl + fi->dc);
|
|
|
|
memset(fi->dil, 0, fi->fc * sizeof(*fi->dil));
|
|
|
|
fi->dil[i] = 1;
|
2001-04-30 06:43:01 +08:00
|
|
|
/*@-dependenttrans@*/
|
2001-01-26 04:26:35 +08:00
|
|
|
fi->dnl[0] = t = (char *)(fi->dil + fi->fc);
|
|
|
|
fi->dnl[1] = t = stpcpy( stpcpy(t, _sourcedir), "/") + 1;
|
2001-04-30 06:43:01 +08:00
|
|
|
/*@=dependenttrans@*/
|
2001-01-26 04:26:35 +08:00
|
|
|
(void) stpcpy( stpcpy(t, _specdir), "/");
|
|
|
|
|
|
|
|
t = xmalloc(speclen + strlen(fi->bnl[i]) + 1);
|
|
|
|
(void) stpcpy( stpcpy( stpcpy(t, _specdir), "/"), fi->bnl[i]);
|
|
|
|
specFile = t;
|
2001-01-24 00:07:28 +08:00
|
|
|
} else {
|
|
|
|
rpmError(RPMERR_NOSPEC, _("source package contains no .spec file\n"));
|
2001-03-03 01:27:30 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2001-01-24 00:07:28 +08:00
|
|
|
goto exit;
|
1997-05-07 02:19:19 +08:00
|
|
|
}
|
1996-07-26 00:39:01 +08:00
|
|
|
|
2001-03-05 01:15:56 +08:00
|
|
|
psm->goal = PSM_PKGINSTALL;
|
2001-03-02 00:01:16 +08:00
|
|
|
|
2001-05-23 22:25:19 +08:00
|
|
|
/*@-compmempass@*/ /* FIX: psm->fi->dnl should be owned. */
|
2001-03-05 01:15:56 +08:00
|
|
|
rc = psmStage(psm, PSM_PROCESS);
|
2001-03-02 23:03:29 +08:00
|
|
|
|
2001-03-05 01:15:56 +08:00
|
|
|
(void) psmStage(psm, PSM_FINI);
|
2001-05-23 22:25:19 +08:00
|
|
|
/*@=compmempass@*/
|
2001-01-22 07:48:09 +08:00
|
|
|
|
2001-03-05 01:15:56 +08:00
|
|
|
if (rc) rc = RPMRC_FAIL;
|
1996-02-15 04:09:14 +08:00
|
|
|
|
1999-01-06 07:13:56 +08:00
|
|
|
exit:
|
2001-06-01 06:31:14 +08:00
|
|
|
if (specFilePtr && specFile && rc == RPMRC_OK)
|
2001-01-26 04:26:35 +08:00
|
|
|
*specFilePtr = specFile;
|
|
|
|
else
|
2001-02-13 03:02:15 +08:00
|
|
|
specFile = _free(specFile);
|
2001-03-05 01:15:56 +08:00
|
|
|
|
2001-02-13 03:02:15 +08:00
|
|
|
_specdir = _free(_specdir);
|
|
|
|
_sourcedir = _free(_sourcedir);
|
1996-02-16 05:08:48 +08:00
|
|
|
|
2001-10-04 00:11:27 +08:00
|
|
|
if (h) h = headerFree(h);
|
1996-02-16 05:08:48 +08:00
|
|
|
|
2001-01-25 20:58:03 +08:00
|
|
|
if (fi) {
|
|
|
|
freeFi(fi);
|
2001-04-30 06:43:01 +08:00
|
|
|
fi = _free(fi);
|
2001-01-25 20:58:03 +08:00
|
|
|
}
|
2001-03-05 01:15:56 +08:00
|
|
|
|
2001-01-25 20:58:03 +08:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@observer@*/ /*@unchecked@*/
|
|
|
|
static char * SCRIPT_PATH = "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin";
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return scriptlet name from tag.
|
|
|
|
* @param tag scriptlet tag
|
|
|
|
* @return name of scriptlet
|
|
|
|
*/
|
|
|
|
static /*@observer@*/ const char * const tag2sln(int tag)
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
{
|
|
|
|
switch (tag) {
|
|
|
|
case RPMTAG_PREIN: return "%pre";
|
|
|
|
case RPMTAG_POSTIN: return "%post";
|
|
|
|
case RPMTAG_PREUN: return "%preun";
|
|
|
|
case RPMTAG_POSTUN: return "%postun";
|
|
|
|
case RPMTAG_VERIFYSCRIPT: return "%verify";
|
|
|
|
}
|
|
|
|
return "%unknownscript";
|
|
|
|
}
|
|
|
|
|
2001-02-13 00:33:08 +08:00
|
|
|
/**
|
2001-02-28 23:49:23 +08:00
|
|
|
* Run scriptlet with args.
|
|
|
|
*
|
|
|
|
* Run a script with an interpreter. If the interpreter is not specified,
|
|
|
|
* /bin/sh will be used. If the interpreter is /bin/sh, then the args from
|
|
|
|
* the header will be ignored, passing instead arg1 and arg2.
|
|
|
|
*
|
2001-02-28 07:12:30 +08:00
|
|
|
* @param psm package state machine data
|
2001-02-28 23:49:23 +08:00
|
|
|
* @param h header
|
|
|
|
* @param sln name of scriptlet section
|
|
|
|
* @param progArgc no. of args from header
|
|
|
|
* @param progArgv args from header, progArgv[0] is the interpreter to use
|
|
|
|
* @param script scriptlet from header
|
|
|
|
* @param arg1 no. instances of package installed after scriptlet exec
|
|
|
|
* (-1 is no arg)
|
|
|
|
* @param arg2 ditto, but for the target package
|
|
|
|
* @return 0 on success, 1 on error
|
2001-02-13 00:33:08 +08:00
|
|
|
*/
|
2001-02-28 23:49:23 +08:00
|
|
|
static int runScript(PSM_t psm, Header h,
|
|
|
|
const char * sln,
|
|
|
|
int progArgc, const char ** progArgv,
|
|
|
|
const char * script, int arg1, int arg2)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals rpmGlobalMacroContext,
|
|
|
|
fileSystem, internalState@*/
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@modifies psm, rpmGlobalMacroContext, fileSystem, internalState @*/
|
2001-02-13 00:33:08 +08:00
|
|
|
{
|
2001-02-28 07:12:30 +08:00
|
|
|
const rpmTransactionSet ts = psm->ts;
|
|
|
|
TFI_t fi = psm->fi;
|
2001-02-28 23:49:23 +08:00
|
|
|
HGE_t hge = fi->hge;
|
2001-05-04 05:00:18 +08:00
|
|
|
HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
|
2001-02-28 23:49:23 +08:00
|
|
|
const char ** argv = NULL;
|
|
|
|
int argc = 0;
|
|
|
|
const char ** prefixes = NULL;
|
|
|
|
int numPrefixes;
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmTagType ipt;
|
2001-02-28 23:49:23 +08:00
|
|
|
const char * oldPrefix;
|
|
|
|
int maxPrefixLength;
|
|
|
|
int len;
|
|
|
|
char * prefixBuf = NULL;
|
|
|
|
pid_t child;
|
|
|
|
int status = 0;
|
|
|
|
const char * fn = NULL;
|
2001-10-16 22:58:57 +08:00
|
|
|
int i, xx;
|
2001-02-28 23:49:23 +08:00
|
|
|
int freePrefixes = 0;
|
|
|
|
FD_t out;
|
2001-03-03 01:27:30 +08:00
|
|
|
rpmRC rc = RPMRC_OK;
|
2001-02-28 23:49:23 +08:00
|
|
|
const char *n, *v, *r;
|
2001-02-13 00:33:08 +08:00
|
|
|
|
2001-10-19 00:39:54 +08:00
|
|
|
if (progArgv == NULL && script == NULL)
|
2001-02-28 23:49:23 +08:00
|
|
|
return 0;
|
2001-02-13 00:33:08 +08:00
|
|
|
|
2001-10-19 00:39:54 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("%s: running %s scriptlet\n"),
|
|
|
|
psm->stepName, tag2sln(psm->scriptTag));
|
|
|
|
|
2001-02-28 23:49:23 +08:00
|
|
|
if (!progArgv) {
|
2001-10-16 22:58:57 +08:00
|
|
|
argv = alloca(5 * sizeof(*argv));
|
2001-02-28 23:49:23 +08:00
|
|
|
argv[0] = "/bin/sh";
|
|
|
|
argc = 1;
|
|
|
|
} else {
|
2001-10-16 22:58:57 +08:00
|
|
|
argv = alloca((progArgc + 4) * sizeof(*argv));
|
|
|
|
memcpy(argv, progArgv, progArgc * sizeof(*argv));
|
2001-02-28 23:49:23 +08:00
|
|
|
argc = progArgc;
|
|
|
|
}
|
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerNVR(h, &n, &v, &r);
|
2001-02-28 23:49:23 +08:00
|
|
|
if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &prefixes, &numPrefixes)) {
|
|
|
|
freePrefixes = 1;
|
|
|
|
} else if (hge(h, RPMTAG_INSTALLPREFIX, NULL, (void **) &oldPrefix, NULL)) {
|
|
|
|
prefixes = &oldPrefix;
|
|
|
|
numPrefixes = 1;
|
|
|
|
} else {
|
|
|
|
numPrefixes = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
maxPrefixLength = 0;
|
|
|
|
for (i = 0; i < numPrefixes; i++) {
|
|
|
|
len = strlen(prefixes[i]);
|
|
|
|
if (len > maxPrefixLength) maxPrefixLength = len;
|
|
|
|
}
|
|
|
|
prefixBuf = alloca(maxPrefixLength + 50);
|
|
|
|
|
|
|
|
if (script) {
|
|
|
|
FD_t fd;
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
if (makeTempFile((!ts->chrootDone ? ts->rootDir : "/"), &fn, &fd)) {
|
|
|
|
if (freePrefixes) free(prefixes);
|
|
|
|
return 1;
|
|
|
|
}
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
if (rpmIsDebug() &&
|
|
|
|
(!strcmp(argv[0], "/bin/sh") || !strcmp(argv[0], "/bin/bash")))
|
2001-10-16 22:58:57 +08:00
|
|
|
{
|
|
|
|
static const char set_x[] = "set -x\n";
|
|
|
|
xx = Fwrite(set_x, sizeof(set_x[0]), sizeof(set_x)-1, fd);
|
|
|
|
}
|
2001-02-28 23:49:23 +08:00
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = Fwrite(script, sizeof(script[0]), strlen(script), fd);
|
|
|
|
xx = Fclose(fd);
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
{ const char * sn = fn;
|
|
|
|
if (!ts->chrootDone &&
|
|
|
|
!(ts->rootDir[0] == '/' && ts->rootDir[1] == '\0'))
|
|
|
|
{
|
|
|
|
sn += strlen(ts->rootDir)-1;
|
|
|
|
}
|
|
|
|
argv[argc++] = sn;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (arg1 >= 0) {
|
|
|
|
char *av = alloca(20);
|
|
|
|
sprintf(av, "%d", arg1);
|
|
|
|
argv[argc++] = av;
|
|
|
|
}
|
|
|
|
if (arg2 >= 0) {
|
|
|
|
char *av = alloca(20);
|
|
|
|
sprintf(av, "%d", arg2);
|
|
|
|
argv[argc++] = av;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
argv[argc] = NULL;
|
|
|
|
|
|
|
|
if (ts->scriptFd != NULL) {
|
|
|
|
if (rpmIsVerbose()) {
|
|
|
|
out = fdDup(Fileno(ts->scriptFd));
|
|
|
|
} else {
|
|
|
|
out = Fopen("/dev/null", "w.fdio");
|
|
|
|
if (Ferror(out)) {
|
|
|
|
out = fdDup(Fileno(ts->scriptFd));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
out = fdDup(STDOUT_FILENO);
|
2001-07-20 05:14:05 +08:00
|
|
|
#ifdef DYING
|
2001-02-28 23:49:23 +08:00
|
|
|
out = fdLink(out, "runScript persist");
|
2001-07-20 05:14:05 +08:00
|
|
|
#endif
|
2001-02-28 23:49:23 +08:00
|
|
|
}
|
2001-05-04 05:00:18 +08:00
|
|
|
if (out == NULL) return 1; /* XXX can't happen */
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
if (!(child = fork())) {
|
|
|
|
const char * rootDir;
|
|
|
|
int pipes[2];
|
|
|
|
|
|
|
|
pipes[0] = pipes[1] = 0;
|
|
|
|
/* make stdin inaccessible */
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = pipe(pipes);
|
|
|
|
xx = close(pipes[1]);
|
|
|
|
xx = dup2(pipes[0], STDIN_FILENO);
|
|
|
|
xx = close(pipes[0]);
|
2001-02-28 23:49:23 +08:00
|
|
|
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
if (ts->scriptFd != NULL) {
|
2001-10-15 11:22:10 +08:00
|
|
|
int sfdno = Fileno(ts->scriptFd);
|
|
|
|
int ofdno = Fileno(out);
|
|
|
|
if (sfdno != STDERR_FILENO)
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = dup2(sfdno, STDERR_FILENO);
|
2001-10-15 11:22:10 +08:00
|
|
|
if (ofdno != STDOUT_FILENO)
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = dup2(ofdno, STDOUT_FILENO);
|
2001-02-28 23:49:23 +08:00
|
|
|
/* make sure we don't close stdin/stderr/stdout by mistake! */
|
2001-10-15 11:22:10 +08:00
|
|
|
if (ofdno > STDERR_FILENO && ofdno != sfdno) {
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = Fclose (out);
|
2001-02-28 23:49:23 +08:00
|
|
|
}
|
2001-10-15 11:22:10 +08:00
|
|
|
if (sfdno > STDERR_FILENO) {
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = Fclose (ts->scriptFd);
|
2001-02-28 23:49:23 +08:00
|
|
|
}
|
|
|
|
}
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
{ const char *ipath = rpmExpand("PATH=%{_install_script_path}", NULL);
|
|
|
|
const char *path = SCRIPT_PATH;
|
|
|
|
|
|
|
|
if (ipath && ipath[5] != '%')
|
|
|
|
path = ipath;
|
2001-10-16 01:53:34 +08:00
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = doputenv(path);
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@-modobserver@*/
|
2001-04-29 09:05:43 +08:00
|
|
|
ipath = _free(ipath);
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@=modobserver@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
}
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
for (i = 0; i < numPrefixes; i++) {
|
|
|
|
sprintf(prefixBuf, "RPM_INSTALL_PREFIX%d=%s", i, prefixes[i]);
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = doputenv(prefixBuf);
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
/* backwards compatibility */
|
|
|
|
if (i == 0) {
|
|
|
|
sprintf(prefixBuf, "RPM_INSTALL_PREFIX=%s", prefixes[i]);
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = doputenv(prefixBuf);
|
2001-02-13 00:33:08 +08:00
|
|
|
}
|
2001-02-28 23:49:23 +08:00
|
|
|
}
|
2001-02-13 00:33:08 +08:00
|
|
|
|
2001-05-04 05:00:18 +08:00
|
|
|
if ((rootDir = ts->rootDir) != NULL) /* XXX can't happen */
|
2001-02-28 23:49:23 +08:00
|
|
|
switch(urlIsURL(rootDir)) {
|
|
|
|
case URL_IS_PATH:
|
|
|
|
rootDir += sizeof("file://") - 1;
|
|
|
|
rootDir = strchr(rootDir, '/');
|
|
|
|
/*@fallthrough@*/
|
|
|
|
case URL_IS_UNKNOWN:
|
|
|
|
if (!ts->chrootDone && !(rootDir[0] == '/' && rootDir[1] == '\0')) {
|
2001-10-14 03:35:58 +08:00
|
|
|
/*@-superuser -noeffect @*/
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = chroot(rootDir);
|
2001-10-14 03:35:58 +08:00
|
|
|
/*@=superuser =noeffect @*/
|
2001-02-28 23:49:23 +08:00
|
|
|
}
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = chdir("/");
|
|
|
|
xx = execv(argv[0], (char *const *)argv);
|
2001-02-28 23:49:23 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2001-02-13 00:33:08 +08:00
|
|
|
}
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
_exit(-1);
|
|
|
|
/*@notreached@*/
|
|
|
|
}
|
|
|
|
|
|
|
|
if (waitpid(child, &status, 0) < 0) {
|
|
|
|
rpmError(RPMERR_SCRIPT,
|
2001-03-04 04:41:37 +08:00
|
|
|
_("execution of %s scriptlet from %s-%s-%s failed, waitpid returned %s\n"),
|
2001-02-28 23:49:23 +08:00
|
|
|
sln, n, v, r, strerror (errno));
|
|
|
|
/* XXX what to do here? */
|
2001-03-03 01:27:30 +08:00
|
|
|
rc = RPMRC_OK;
|
2001-02-13 00:33:08 +08:00
|
|
|
} else {
|
2001-02-28 23:49:23 +08:00
|
|
|
if (!WIFEXITED(status) || WEXITSTATUS(status)) {
|
|
|
|
rpmError(RPMERR_SCRIPT,
|
2001-03-04 04:41:37 +08:00
|
|
|
_("execution of %s scriptlet from %s-%s-%s failed, exit status %d\n"),
|
2001-02-28 23:49:23 +08:00
|
|
|
sln, n, v, r, WEXITSTATUS(status));
|
2001-03-03 01:27:30 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2001-02-28 23:49:23 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (freePrefixes) prefixes = hfd(prefixes, ipt);
|
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = Fclose(out); /* XXX dup'd STDOUT_FILENO */
|
2001-02-28 23:49:23 +08:00
|
|
|
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
if (script) {
|
2001-05-01 06:32:22 +08:00
|
|
|
if (!rpmIsDebug())
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = unlink(fn);
|
2001-04-29 09:05:43 +08:00
|
|
|
fn = _free(fn);
|
2001-02-28 23:49:23 +08:00
|
|
|
}
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve and run scriptlet from header.
|
|
|
|
* @param psm package state machine data
|
2001-03-03 01:27:30 +08:00
|
|
|
* @return rpmRC return code
|
2001-02-28 23:49:23 +08:00
|
|
|
*/
|
2001-03-03 01:27:30 +08:00
|
|
|
static rpmRC runInstScript(PSM_t psm)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals rpmGlobalMacroContext,
|
2001-10-18 00:43:36 +08:00
|
|
|
fileSystem, internalState @*/
|
|
|
|
/*@modifies psm, rpmGlobalMacroContext,
|
|
|
|
fileSystem, internalState @*/
|
2001-02-28 23:49:23 +08:00
|
|
|
{
|
|
|
|
TFI_t fi = psm->fi;
|
|
|
|
HGE_t hge = fi->hge;
|
2001-05-04 05:00:18 +08:00
|
|
|
HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
|
2001-10-19 00:39:54 +08:00
|
|
|
void ** progArgv;
|
|
|
|
int progArgc;
|
2001-02-28 23:49:23 +08:00
|
|
|
const char ** argv;
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmTagType ptt, stt;
|
2001-02-28 23:49:23 +08:00
|
|
|
const char * script;
|
2001-03-03 01:27:30 +08:00
|
|
|
rpmRC rc = RPMRC_OK;
|
2001-10-16 22:58:57 +08:00
|
|
|
int xx;
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* headerGetEntry() sets the data pointer to NULL if the entry does
|
|
|
|
* not exist.
|
|
|
|
*/
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = hge(fi->h, psm->scriptTag, &stt, (void **) &script, NULL);
|
2001-10-19 00:39:54 +08:00
|
|
|
xx = hge(fi->h, psm->progTag, &ptt, (void **) &progArgv, &progArgc);
|
|
|
|
if (progArgv == NULL && script == NULL)
|
|
|
|
goto exit;
|
2001-02-28 23:49:23 +08:00
|
|
|
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
2001-10-19 00:39:54 +08:00
|
|
|
if (progArgv && ptt == RPM_STRING_TYPE) {
|
2001-10-16 22:58:57 +08:00
|
|
|
argv = alloca(sizeof(*argv));
|
2001-10-19 00:39:54 +08:00
|
|
|
*argv = (const char *) progArgv;
|
2001-02-28 23:49:23 +08:00
|
|
|
} else {
|
2001-10-19 00:39:54 +08:00
|
|
|
argv = (const char **) progArgv;
|
2001-02-28 23:49:23 +08:00
|
|
|
}
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
|
2001-10-19 00:39:54 +08:00
|
|
|
if (fi->h != NULL) /* XXX can't happen */
|
|
|
|
rc = runScript(psm, fi->h, tag2sln(psm->scriptTag), progArgc, argv,
|
2001-02-28 23:49:23 +08:00
|
|
|
script, psm->scriptArg, -1);
|
2001-03-04 04:41:37 +08:00
|
|
|
|
2001-10-19 00:39:54 +08:00
|
|
|
exit:
|
|
|
|
progArgv = hfd(progArgv, ptt);
|
2001-02-28 23:49:23 +08:00
|
|
|
script = hfd(script, stt);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param psm package state machine data
|
|
|
|
* @param sourceH
|
|
|
|
* @param triggeredH
|
|
|
|
* @param arg2
|
|
|
|
* @param triggersAlreadyRun
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
static int handleOneTrigger(PSM_t psm, Header sourceH, Header triggeredH,
|
2001-04-29 09:05:43 +08:00
|
|
|
int arg2, unsigned char * triggersAlreadyRun)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals rpmGlobalMacroContext,
|
|
|
|
fileSystem, internalState@*/
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@modifies psm, *triggersAlreadyRun, rpmGlobalMacroContext,
|
|
|
|
fileSystem, internalState @*/
|
2001-02-28 23:49:23 +08:00
|
|
|
{
|
|
|
|
const rpmTransactionSet ts = psm->ts;
|
|
|
|
TFI_t fi = psm->fi;
|
|
|
|
HGE_t hge = fi->hge;
|
2001-05-04 05:00:18 +08:00
|
|
|
HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
|
2001-02-28 23:49:23 +08:00
|
|
|
const char ** triggerNames;
|
|
|
|
const char ** triggerEVR;
|
|
|
|
const char ** triggerScripts;
|
|
|
|
const char ** triggerProgs;
|
|
|
|
int_32 * triggerFlags;
|
|
|
|
int_32 * triggerIndices;
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmTagType tnt, tvt, tft;
|
2001-02-28 23:49:23 +08:00
|
|
|
const char * triggerPackageName;
|
|
|
|
const char * sourceName;
|
|
|
|
int numTriggers;
|
2001-03-03 01:27:30 +08:00
|
|
|
rpmRC rc = RPMRC_OK;
|
2001-10-16 22:58:57 +08:00
|
|
|
int i, xx;
|
2001-02-28 23:49:23 +08:00
|
|
|
int skip;
|
|
|
|
|
2001-05-23 22:25:19 +08:00
|
|
|
if (!( hge(triggeredH, RPMTAG_TRIGGERNAME, &tnt,
|
|
|
|
(void **) &triggerNames, &numTriggers) &&
|
|
|
|
hge(triggeredH, RPMTAG_TRIGGERFLAGS, &tft,
|
|
|
|
(void **) &triggerFlags, NULL) &&
|
|
|
|
hge(triggeredH, RPMTAG_TRIGGERVERSION, &tvt,
|
|
|
|
(void **) &triggerEVR, NULL))
|
|
|
|
)
|
2001-02-28 23:49:23 +08:00
|
|
|
return 0;
|
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerNVR(sourceH, &sourceName, NULL, NULL);
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
for (i = 0; i < numTriggers; i++) {
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmTagType tit, tst, tpt;
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
if (!(triggerFlags[i] & psm->sense)) continue;
|
|
|
|
if (strcmp(triggerNames[i], sourceName)) continue;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* For some reason, the TRIGGERVERSION stuff includes the name of
|
|
|
|
* the package which the trigger is based on. We need to skip
|
|
|
|
* over that here. I suspect that we'll change our minds on this
|
|
|
|
* and remove that, so I'm going to just 'do the right thing'.
|
|
|
|
*/
|
|
|
|
skip = strlen(triggerNames[i]);
|
|
|
|
if (!strncmp(triggerEVR[i], triggerNames[i], skip) &&
|
|
|
|
(triggerEVR[i][skip] == '-'))
|
|
|
|
skip++;
|
|
|
|
else
|
|
|
|
skip = 0;
|
|
|
|
|
|
|
|
if (!headerMatchesDepFlags(sourceH, triggerNames[i],
|
|
|
|
triggerEVR[i] + skip, triggerFlags[i]))
|
|
|
|
continue;
|
|
|
|
|
2001-05-23 22:25:19 +08:00
|
|
|
if (!( hge(triggeredH, RPMTAG_TRIGGERINDEX, &tit,
|
|
|
|
(void **) &triggerIndices, NULL) &&
|
|
|
|
hge(triggeredH, RPMTAG_TRIGGERSCRIPTS, &tst,
|
|
|
|
(void **) &triggerScripts, NULL) &&
|
|
|
|
hge(triggeredH, RPMTAG_TRIGGERSCRIPTPROG, &tpt,
|
|
|
|
(void **) &triggerProgs, NULL))
|
|
|
|
)
|
|
|
|
continue;
|
2001-02-28 23:49:23 +08:00
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerNVR(triggeredH, &triggerPackageName, NULL, NULL);
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
{ int arg1;
|
|
|
|
int index;
|
|
|
|
|
|
|
|
arg1 = rpmdbCountPackages(ts->rpmdb, triggerPackageName);
|
|
|
|
if (arg1 < 0) {
|
2001-03-03 01:27:30 +08:00
|
|
|
/* XXX W2DO? same as "execution of script failed" */
|
|
|
|
rc = RPMRC_FAIL;
|
2001-02-28 23:49:23 +08:00
|
|
|
} else {
|
|
|
|
arg1 += psm->countCorrection;
|
|
|
|
index = triggerIndices[i];
|
2001-04-29 09:05:43 +08:00
|
|
|
if (triggersAlreadyRun == NULL ||
|
|
|
|
triggersAlreadyRun[index] == 0)
|
|
|
|
{
|
2001-02-28 23:49:23 +08:00
|
|
|
rc = runScript(psm, triggeredH, "%trigger", 1,
|
|
|
|
triggerProgs + index, triggerScripts[index],
|
|
|
|
arg1, arg2);
|
2001-04-29 09:05:43 +08:00
|
|
|
if (triggersAlreadyRun != NULL)
|
|
|
|
triggersAlreadyRun[index] = 1;
|
2001-02-28 23:49:23 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
triggerIndices = hfd(triggerIndices, tit);
|
|
|
|
triggerScripts = hfd(triggerScripts, tst);
|
|
|
|
triggerProgs = hfd(triggerProgs, tpt);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Each target/source header pair can only result in a single
|
|
|
|
* script being run.
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
triggerNames = hfd(triggerNames, tnt);
|
|
|
|
triggerFlags = hfd(triggerFlags, tft);
|
|
|
|
triggerEVR = hfd(triggerEVR, tvt);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run trigger scripts in the database that are fired by this header.
|
|
|
|
* @param psm package state machine data
|
|
|
|
* @return 0 on success, 1 on error
|
|
|
|
*/
|
|
|
|
static int runTriggers(PSM_t psm)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals rpmGlobalMacroContext,
|
|
|
|
fileSystem, internalState @*/
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@modifies psm, rpmGlobalMacroContext,
|
|
|
|
fileSystem, internalState @*/
|
2001-02-28 23:49:23 +08:00
|
|
|
{
|
|
|
|
const rpmTransactionSet ts = psm->ts;
|
|
|
|
TFI_t fi = psm->fi;
|
|
|
|
int numPackage;
|
2001-03-03 01:27:30 +08:00
|
|
|
rpmRC rc = RPMRC_OK;
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
numPackage = rpmdbCountPackages(ts->rpmdb, fi->name) + psm->countCorrection;
|
|
|
|
if (numPackage < 0)
|
|
|
|
return 1;
|
|
|
|
|
2001-10-19 00:39:54 +08:00
|
|
|
if (fi->h != NULL) /* XXX can't happen */
|
2001-02-28 23:49:23 +08:00
|
|
|
{ Header triggeredH;
|
|
|
|
rpmdbMatchIterator mi;
|
|
|
|
int countCorrection = psm->countCorrection;
|
|
|
|
|
|
|
|
psm->countCorrection = 0;
|
|
|
|
mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_TRIGGERNAME, fi->name, 0);
|
|
|
|
while((triggeredH = rpmdbNextIterator(mi)) != NULL) {
|
|
|
|
rc |= handleOneTrigger(psm, fi->h, triggeredH, numPackage, NULL);
|
|
|
|
}
|
|
|
|
|
2001-04-30 06:43:01 +08:00
|
|
|
mi = rpmdbFreeIterator(mi);
|
2001-02-28 23:49:23 +08:00
|
|
|
psm->countCorrection = countCorrection;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run triggers from this header that are fired by headers in the database.
|
|
|
|
* @param psm package state machine data
|
|
|
|
* @return 0 on success, 1 on error
|
|
|
|
*/
|
|
|
|
static int runImmedTriggers(PSM_t psm)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals rpmGlobalMacroContext,
|
|
|
|
fileSystem, internalState @*/
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@modifies psm, rpmGlobalMacroContext,
|
|
|
|
fileSystem, internalState @*/
|
2001-02-28 23:49:23 +08:00
|
|
|
{
|
|
|
|
const rpmTransactionSet ts = psm->ts;
|
|
|
|
TFI_t fi = psm->fi;
|
|
|
|
HGE_t hge = fi->hge;
|
2001-05-04 05:00:18 +08:00
|
|
|
HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
|
2001-02-28 23:49:23 +08:00
|
|
|
const char ** triggerNames;
|
|
|
|
int numTriggers;
|
|
|
|
int_32 * triggerIndices;
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmTagType tnt, tit;
|
2001-02-28 23:49:23 +08:00
|
|
|
int numTriggerIndices;
|
2001-04-29 09:05:43 +08:00
|
|
|
unsigned char * triggersRun;
|
2001-03-03 01:27:30 +08:00
|
|
|
rpmRC rc = RPMRC_OK;
|
2001-02-28 23:49:23 +08:00
|
|
|
|
2001-10-19 00:39:54 +08:00
|
|
|
if (fi->h == NULL) return 0; /* XXX can't happen */
|
|
|
|
|
2001-05-23 22:25:19 +08:00
|
|
|
if (!( hge(fi->h, RPMTAG_TRIGGERNAME, &tnt,
|
|
|
|
(void **) &triggerNames, &numTriggers) &&
|
|
|
|
hge(fi->h, RPMTAG_TRIGGERINDEX, &tit,
|
|
|
|
(void **) &triggerIndices, &numTriggerIndices))
|
|
|
|
)
|
2001-02-28 23:49:23 +08:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
triggersRun = alloca(sizeof(*triggersRun) * numTriggerIndices);
|
|
|
|
memset(triggersRun, 0, sizeof(*triggersRun) * numTriggerIndices);
|
|
|
|
|
|
|
|
{ Header sourceH = NULL;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < numTriggers; i++) {
|
|
|
|
rpmdbMatchIterator mi;
|
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
if (triggersRun[triggerIndices[i]] != 0) continue;
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, triggerNames[i], 0);
|
|
|
|
|
|
|
|
while((sourceH = rpmdbNextIterator(mi)) != NULL) {
|
|
|
|
rc |= handleOneTrigger(psm, sourceH, fi->h,
|
|
|
|
rpmdbGetIteratorCount(mi),
|
|
|
|
triggersRun);
|
|
|
|
}
|
|
|
|
|
2001-04-30 06:43:01 +08:00
|
|
|
mi = rpmdbFreeIterator(mi);
|
2001-02-13 00:33:08 +08:00
|
|
|
}
|
|
|
|
}
|
2001-03-15 07:09:09 +08:00
|
|
|
triggerIndices = hfd(triggerIndices, tit);
|
2001-02-28 23:49:23 +08:00
|
|
|
triggerNames = hfd(triggerNames, tnt);
|
2001-02-13 00:33:08 +08:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2001-10-14 03:35:58 +08:00
|
|
|
/*@observer@*/ static const char *const pkgStageString(pkgStage a)
|
|
|
|
/*@*/
|
|
|
|
{
|
2001-03-03 03:47:45 +08:00
|
|
|
switch(a) {
|
|
|
|
case PSM_UNKNOWN: return "unknown";
|
|
|
|
|
|
|
|
case PSM_PKGINSTALL: return " install";
|
|
|
|
case PSM_PKGERASE: return " erase";
|
|
|
|
case PSM_PKGCOMMIT: return " commit";
|
|
|
|
case PSM_PKGSAVE: return "repackage";
|
|
|
|
|
|
|
|
case PSM_INIT: return "init";
|
|
|
|
case PSM_PRE: return "pre";
|
|
|
|
case PSM_PROCESS: return "process";
|
|
|
|
case PSM_POST: return "post";
|
|
|
|
case PSM_UNDO: return "undo";
|
|
|
|
case PSM_FINI: return "fini";
|
|
|
|
|
|
|
|
case PSM_CREATE: return "create";
|
|
|
|
case PSM_NOTIFY: return "notify";
|
|
|
|
case PSM_DESTROY: return "destroy";
|
|
|
|
case PSM_COMMIT: return "commit";
|
|
|
|
|
|
|
|
case PSM_CHROOT_IN: return "chrootin";
|
|
|
|
case PSM_CHROOT_OUT: return "chrootout";
|
|
|
|
case PSM_SCRIPT: return "script";
|
|
|
|
case PSM_TRIGGERS: return "triggers";
|
|
|
|
case PSM_IMMED_TRIGGERS: return "immedtriggers";
|
|
|
|
|
|
|
|
case PSM_RPMIO_FLAGS: return "rpmioflags";
|
|
|
|
|
|
|
|
case PSM_RPMDB_LOAD: return "rpmdbload";
|
|
|
|
case PSM_RPMDB_ADD: return "rpmdbadd";
|
|
|
|
case PSM_RPMDB_REMOVE: return "rpmdbremove";
|
|
|
|
|
|
|
|
default: return "???";
|
|
|
|
}
|
|
|
|
/*@noteached@*/
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @todo Packages w/o files never get a callback, hence don't get displayed
|
|
|
|
* on install with -v.
|
|
|
|
*/
|
2001-10-19 00:39:54 +08:00
|
|
|
/*@-nullpass@*/ /* FIX: testing null annotation for fi->h */
|
2001-02-28 23:49:23 +08:00
|
|
|
int psmStage(PSM_t psm, pkgStage stage)
|
2001-02-28 06:08:53 +08:00
|
|
|
{
|
2001-02-28 23:49:23 +08:00
|
|
|
const rpmTransactionSet ts = psm->ts;
|
|
|
|
TFI_t fi = psm->fi;
|
2001-03-03 03:47:45 +08:00
|
|
|
HGE_t hge = fi->hge;
|
2001-06-12 12:10:21 +08:00
|
|
|
HME_t hme = fi->hme;
|
2001-05-04 05:00:18 +08:00
|
|
|
HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
|
2001-03-03 01:27:30 +08:00
|
|
|
rpmRC rc = psm->rc;
|
2001-03-02 23:03:29 +08:00
|
|
|
int saveerrno;
|
2001-10-16 22:58:57 +08:00
|
|
|
int xx;
|
2001-02-28 06:08:53 +08:00
|
|
|
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
2001-02-28 06:08:53 +08:00
|
|
|
switch (stage) {
|
2001-02-28 23:49:23 +08:00
|
|
|
case PSM_UNKNOWN:
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
2001-02-28 23:49:23 +08:00
|
|
|
case PSM_INIT:
|
2001-03-02 16:28:18 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("%s: %s-%s-%s has %d files, test = %d\n"),
|
|
|
|
psm->stepName, fi->name, fi->version, fi->release,
|
|
|
|
fi->fc, (ts->transFlags & RPMTRANS_FLAG_TEST));
|
2001-03-03 03:47:45 +08:00
|
|
|
|
2001-03-04 04:41:37 +08:00
|
|
|
/*
|
|
|
|
* When we run scripts, we pass an argument which is the number of
|
|
|
|
* versions of this package that will be installed when we are
|
|
|
|
* finished.
|
|
|
|
*/
|
|
|
|
psm->npkgs_installed = rpmdbCountPackages(ts->rpmdb, fi->name);
|
|
|
|
if (psm->npkgs_installed < 0) {
|
|
|
|
rc = RPMRC_FAIL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-03-03 00:17:03 +08:00
|
|
|
if (psm->goal == PSM_PKGINSTALL) {
|
2001-03-04 04:41:37 +08:00
|
|
|
psm->scriptArg = psm->npkgs_installed + 1;
|
2001-03-03 00:17:03 +08:00
|
|
|
|
2001-03-03 03:47:45 +08:00
|
|
|
assert(psm->mi == NULL);
|
2001-03-03 01:27:30 +08:00
|
|
|
psm->mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, fi->name, 0);
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = rpmdbSetIteratorRE(psm->mi, RPMTAG_VERSION,
|
2001-06-15 12:56:33 +08:00
|
|
|
RPMMIRE_DEFAULT, fi->version);
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = rpmdbSetIteratorRE(psm->mi, RPMTAG_RELEASE,
|
2001-06-15 12:56:33 +08:00
|
|
|
RPMMIRE_DEFAULT, fi->release);
|
|
|
|
|
2001-03-03 01:27:30 +08:00
|
|
|
while ((psm->oh = rpmdbNextIterator(psm->mi))) {
|
|
|
|
fi->record = rpmdbGetIteratorOffset(psm->mi);
|
2001-04-30 06:43:01 +08:00
|
|
|
if (ts->transFlags & RPMTRANS_FLAG_MULTILIB)
|
|
|
|
psm->oh = headerCopy(psm->oh);
|
|
|
|
else
|
|
|
|
psm->oh = NULL;
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@loopbreak@*/ break;
|
2001-03-03 00:17:03 +08:00
|
|
|
}
|
2001-04-30 06:43:01 +08:00
|
|
|
psm->mi = rpmdbFreeIterator(psm->mi);
|
2001-03-03 01:27:30 +08:00
|
|
|
rc = RPMRC_OK;
|
2001-03-03 03:47:45 +08:00
|
|
|
|
|
|
|
if (fi->fc > 0 && fi->fstates == NULL) {
|
|
|
|
fi->fstates = xmalloc(sizeof(*fi->fstates) * fi->fc);
|
|
|
|
memset(fi->fstates, RPMFILE_STATE_NORMAL, fi->fc);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fi->fc <= 0) break;
|
|
|
|
if (ts->transFlags & RPMTRANS_FLAG_JUSTDB) break;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Old format relocateable packages need the entire default
|
|
|
|
* prefix stripped to form the cpio list, while all other packages
|
|
|
|
* need the leading / stripped.
|
|
|
|
*/
|
|
|
|
{ const char * p;
|
|
|
|
rc = hge(fi->h, RPMTAG_DEFAULTPREFIX, NULL, (void **) &p, NULL);
|
|
|
|
fi->striplen = (rc ? strlen(p) + 1 : 1);
|
|
|
|
}
|
|
|
|
fi->mapflags =
|
|
|
|
CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
|
|
|
|
|
|
|
|
if (headerIsEntry(fi->h, RPMTAG_ORIGBASENAMES))
|
|
|
|
buildOrigFileList(fi->h, &fi->apath, NULL);
|
|
|
|
else
|
|
|
|
rpmBuildFileList(fi->h, &fi->apath, NULL);
|
|
|
|
|
|
|
|
if (fi->fuser == NULL)
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = hge(fi->h, RPMTAG_FILEUSERNAME, NULL,
|
2001-03-03 03:47:45 +08:00
|
|
|
(void **) &fi->fuser, NULL);
|
|
|
|
if (fi->fgroup == NULL)
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = hge(fi->h, RPMTAG_FILEGROUPNAME, NULL,
|
2001-03-03 03:47:45 +08:00
|
|
|
(void **) &fi->fgroup, NULL);
|
|
|
|
if (fi->fuids == NULL)
|
|
|
|
fi->fuids = xcalloc(sizeof(*fi->fuids), fi->fc);
|
|
|
|
if (fi->fgids == NULL)
|
|
|
|
fi->fgids = xcalloc(sizeof(*fi->fgids), fi->fc);
|
|
|
|
rc = RPMRC_OK;
|
2001-03-03 00:17:03 +08:00
|
|
|
}
|
2001-03-04 05:35:41 +08:00
|
|
|
if (psm->goal == PSM_PKGERASE || psm->goal == PSM_PKGSAVE) {
|
2001-03-04 04:41:37 +08:00
|
|
|
psm->scriptArg = psm->npkgs_installed - 1;
|
2001-03-03 00:17:03 +08:00
|
|
|
|
|
|
|
/* Retrieve installed header. */
|
|
|
|
rc = psmStage(psm, PSM_RPMDB_LOAD);
|
|
|
|
}
|
|
|
|
if (psm->goal == PSM_PKGSAVE) {
|
2001-03-04 04:41:37 +08:00
|
|
|
/* Open output package for writing. */
|
|
|
|
{ const char * bfmt = rpmGetPath("%{_repackage_name_fmt}", NULL);
|
|
|
|
const char * pkgbn =
|
|
|
|
headerSprintf(fi->h, bfmt, rpmTagTable, rpmHeaderFormats, NULL);
|
|
|
|
|
|
|
|
bfmt = _free(bfmt);
|
|
|
|
psm->pkgURL = rpmGenPath("%{?_repackage_root:%{_repackage_root}}",
|
|
|
|
"%{?_repackage_dir:%{_repackage_dir}}",
|
|
|
|
pkgbn);
|
|
|
|
pkgbn = _free(pkgbn);
|
|
|
|
(void) urlPath(psm->pkgURL, &psm->pkgfn);
|
|
|
|
psm->fd = Fopen(psm->pkgfn, "w.ufdio");
|
|
|
|
if (psm->fd == NULL || Ferror(psm->fd)) {
|
|
|
|
rc = RPMRC_FAIL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-03-03 00:17:03 +08:00
|
|
|
}
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
2001-02-28 23:49:23 +08:00
|
|
|
case PSM_PRE:
|
2001-03-03 03:47:45 +08:00
|
|
|
if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
|
|
|
|
|
2001-03-04 04:41:37 +08:00
|
|
|
/* Change root directory if requested and not already done. */
|
|
|
|
rc = psmStage(psm, PSM_CHROOT_IN);
|
|
|
|
|
2001-03-02 16:28:18 +08:00
|
|
|
if (psm->goal == PSM_PKGINSTALL) {
|
|
|
|
psm->scriptTag = RPMTAG_PREIN;
|
|
|
|
psm->progTag = RPMTAG_PREINPROG;
|
2001-03-04 04:45:47 +08:00
|
|
|
|
2001-03-04 23:34:53 +08:00
|
|
|
if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERPREIN)) {
|
|
|
|
/* XXX FIXME: implement %triggerprein. */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(ts->transFlags & RPMTRANS_FLAG_NOPRE)) {
|
|
|
|
rc = psmStage(psm, PSM_SCRIPT);
|
|
|
|
if (rc) {
|
|
|
|
rpmError(RPMERR_SCRIPT,
|
2001-03-02 23:03:29 +08:00
|
|
|
_("%s: %s scriptlet failed (%d), skipping %s-%s-%s\n"),
|
|
|
|
psm->stepName, tag2sln(psm->scriptTag), rc,
|
|
|
|
fi->name, fi->version, fi->release);
|
2001-03-04 23:34:53 +08:00
|
|
|
break;
|
|
|
|
}
|
2001-03-02 23:03:29 +08:00
|
|
|
}
|
2001-03-02 16:28:18 +08:00
|
|
|
}
|
2001-03-04 04:45:47 +08:00
|
|
|
|
2001-03-02 16:28:18 +08:00
|
|
|
if (psm->goal == PSM_PKGERASE) {
|
|
|
|
psm->scriptTag = RPMTAG_PREUN;
|
|
|
|
psm->progTag = RPMTAG_PREUNPROG;
|
|
|
|
psm->sense = RPMSENSE_TRIGGERUN;
|
|
|
|
psm->countCorrection = -1;
|
2001-03-02 23:03:29 +08:00
|
|
|
|
2001-03-04 23:34:53 +08:00
|
|
|
if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERUN)) {
|
|
|
|
/* Run triggers in other package(s) this package sets off. */
|
|
|
|
rc = psmStage(psm, PSM_TRIGGERS);
|
|
|
|
if (rc) break;
|
2001-03-02 16:28:18 +08:00
|
|
|
|
2001-03-04 23:34:53 +08:00
|
|
|
/* Run triggers in this package other package(s) set off. */
|
|
|
|
rc = psmStage(psm, PSM_IMMED_TRIGGERS);
|
|
|
|
if (rc) break;
|
|
|
|
}
|
2001-03-02 16:28:18 +08:00
|
|
|
|
2001-03-04 23:34:53 +08:00
|
|
|
if (!(ts->transFlags & RPMTRANS_FLAG_NOPREUN))
|
|
|
|
rc = psmStage(psm, PSM_SCRIPT);
|
2001-03-02 16:28:18 +08:00
|
|
|
}
|
2001-03-02 23:03:29 +08:00
|
|
|
if (psm->goal == PSM_PKGSAVE) {
|
2001-03-03 00:17:03 +08:00
|
|
|
/* Regenerate original header. */
|
|
|
|
{ void * uh = NULL;
|
|
|
|
int_32 uht, uhc;
|
|
|
|
|
|
|
|
if (headerGetEntry(fi->h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc)) {
|
|
|
|
psm->oh = headerCopyLoad(uh);
|
|
|
|
uh = hfd(uh, uht);
|
|
|
|
} else {
|
|
|
|
psm->oh = headerLink(fi->h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-07-07 04:37:42 +08:00
|
|
|
/* Add remove transaction id to header. */
|
|
|
|
if (psm->oh)
|
|
|
|
{ int_32 tid = ts->id;
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerAddEntry(psm->oh, RPMTAG_REMOVETID,
|
2001-07-07 04:37:42 +08:00
|
|
|
RPM_INT32_TYPE, &tid, 1);
|
|
|
|
}
|
|
|
|
|
2001-03-03 00:17:03 +08:00
|
|
|
/* Retrieve type of payload compression. */
|
2001-05-06 03:28:32 +08:00
|
|
|
/*@-nullstate@*/ /* FIX: psm->oh may be NULL */
|
2001-03-03 00:17:03 +08:00
|
|
|
rc = psmStage(psm, PSM_RPMIO_FLAGS);
|
2001-05-06 03:28:32 +08:00
|
|
|
/*@=nullstate@*/
|
2001-03-03 00:17:03 +08:00
|
|
|
|
|
|
|
/* Write the lead section into the package. */
|
|
|
|
{ int archnum = -1;
|
|
|
|
int osnum = -1;
|
|
|
|
struct rpmlead lead;
|
|
|
|
|
|
|
|
#ifndef DYING
|
|
|
|
rpmGetArchInfo(NULL, &archnum);
|
|
|
|
rpmGetOsInfo(NULL, &osnum);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
memset(&lead, 0, sizeof(lead));
|
|
|
|
/* XXX Set package version conditioned on noDirTokens. */
|
|
|
|
lead.major = 4;
|
|
|
|
lead.minor = 0;
|
|
|
|
lead.type = RPMLEAD_BINARY;
|
|
|
|
lead.archnum = archnum;
|
|
|
|
lead.osnum = osnum;
|
|
|
|
lead.signature_type = RPMSIGTYPE_HEADERSIG;
|
|
|
|
|
|
|
|
{ char buf[256];
|
|
|
|
sprintf(buf, "%s-%s-%s", fi->name, fi->version, fi->release);
|
|
|
|
strncpy(lead.name, buf, sizeof(lead.name));
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = writeLead(psm->fd, &lead);
|
|
|
|
if (rc) {
|
|
|
|
rpmError(RPMERR_NOSPACE, _("Unable to write package: %s\n"),
|
|
|
|
Fstrerror(psm->fd));
|
2001-03-03 01:27:30 +08:00
|
|
|
rc = RPMRC_FAIL;
|
2001-03-03 00:17:03 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write the signature section into the package. */
|
|
|
|
{ Header sig = headerRegenSigHeader(fi->h);
|
|
|
|
rc = rpmWriteSignature(psm->fd, sig);
|
2001-05-23 22:25:19 +08:00
|
|
|
sig = rpmFreeSignature(sig);
|
2001-03-03 00:17:03 +08:00
|
|
|
if (rc) break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write the metadata section into the package. */
|
|
|
|
rc = headerWrite(psm->fd, psm->oh, HEADER_MAGIC_YES);
|
|
|
|
if (rc) break;
|
2001-03-02 23:03:29 +08:00
|
|
|
}
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
2001-02-28 23:49:23 +08:00
|
|
|
case PSM_PROCESS:
|
2001-03-03 03:47:45 +08:00
|
|
|
if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
|
2001-03-04 04:41:37 +08:00
|
|
|
|
2001-03-02 16:28:18 +08:00
|
|
|
if (psm->goal == PSM_PKGINSTALL) {
|
2001-03-02 23:03:29 +08:00
|
|
|
struct availablePackage * alp = fi->ap;
|
2001-03-05 01:15:56 +08:00
|
|
|
int i;
|
2001-03-02 23:03:29 +08:00
|
|
|
|
2001-03-03 01:27:30 +08:00
|
|
|
if (fi->fc <= 0) break;
|
|
|
|
if (ts->transFlags & RPMTRANS_FLAG_JUSTDB) break;
|
|
|
|
|
2001-03-05 01:15:56 +08:00
|
|
|
for (i = 0; i < fi->fc; i++) {
|
|
|
|
uid_t uid;
|
|
|
|
gid_t gid;
|
|
|
|
|
|
|
|
uid = fi->uid;
|
|
|
|
gid = fi->gid;
|
|
|
|
if (fi->fuser && unameToUid(fi->fuser[i], &uid)) {
|
|
|
|
rpmMessage(RPMMESS_WARNING,
|
|
|
|
_("user %s does not exist - using root\n"),
|
|
|
|
fi->fuser[i]);
|
|
|
|
uid = 0;
|
|
|
|
/* XXX this diddles header memory. */
|
|
|
|
fi->fmodes[i] &= ~S_ISUID; /* turn off the suid bit */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fi->fgroup && gnameToGid(fi->fgroup[i], &gid)) {
|
|
|
|
rpmMessage(RPMMESS_WARNING,
|
|
|
|
_("group %s does not exist - using root\n"),
|
|
|
|
fi->fgroup[i]);
|
|
|
|
gid = 0;
|
|
|
|
/* XXX this diddles header memory. */
|
|
|
|
fi->fmodes[i] &= ~S_ISGID; /* turn off the sgid bit */
|
|
|
|
}
|
|
|
|
if (fi->fuids) fi->fuids[i] = uid;
|
|
|
|
if (fi->fgids) fi->fgids[i] = gid;
|
|
|
|
}
|
2001-03-03 01:27:30 +08:00
|
|
|
|
2001-03-02 23:03:29 +08:00
|
|
|
/* Retrieve type of payload compression. */
|
|
|
|
rc = psmStage(psm, PSM_RPMIO_FLAGS);
|
|
|
|
|
2001-05-04 05:00:18 +08:00
|
|
|
if (alp->fd == NULL) { /* XXX can't happen */
|
|
|
|
rc = RPMRC_FAIL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/*@-nullpass@*/ /* LCL: alp->fd != NULL here. */
|
2001-03-02 23:03:29 +08:00
|
|
|
psm->cfd = Fdopen(fdDup(Fileno(alp->fd)), psm->rpmio_flags);
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@=nullpass@*/
|
|
|
|
if (psm->cfd == NULL) { /* XXX can't happen */
|
|
|
|
rc = RPMRC_FAIL;
|
|
|
|
break;
|
|
|
|
}
|
2001-03-02 23:03:29 +08:00
|
|
|
|
2001-03-02 16:28:18 +08:00
|
|
|
rc = fsmSetup(fi->fsm, FSM_PKGINSTALL, ts, fi,
|
|
|
|
psm->cfd, NULL, &psm->failedFile);
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = fsmTeardown(fi->fsm);
|
2001-03-02 23:03:29 +08:00
|
|
|
|
|
|
|
saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = Fclose(psm->cfd);
|
2001-03-02 23:03:29 +08:00
|
|
|
psm->cfd = NULL;
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@-mods@*/
|
2001-03-02 23:03:29 +08:00
|
|
|
errno = saveerrno; /* XXX FIXME: Fclose with libio destroys errno */
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@=mods@*/
|
2001-03-03 01:27:30 +08:00
|
|
|
|
|
|
|
if (!rc)
|
|
|
|
rc = psmStage(psm, PSM_COMMIT);
|
|
|
|
|
|
|
|
if (rc) {
|
|
|
|
rpmError(RPMERR_CPIO,
|
|
|
|
_("unpacking of archive failed%s%s: %s\n"),
|
|
|
|
(psm->failedFile != NULL ? _(" on file ") : ""),
|
|
|
|
(psm->failedFile != NULL ? psm->failedFile : ""),
|
|
|
|
cpioStrerror(rc));
|
|
|
|
rc = RPMRC_FAIL;
|
|
|
|
break;
|
|
|
|
}
|
2001-03-04 05:35:41 +08:00
|
|
|
psm->what = RPMCALLBACK_INST_PROGRESS;
|
|
|
|
psm->amount = (fi->archiveSize ? fi->archiveSize : 100);
|
|
|
|
psm->total = psm->amount;
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = psmStage(psm, PSM_NOTIFY);
|
2001-03-02 16:28:18 +08:00
|
|
|
}
|
|
|
|
if (psm->goal == PSM_PKGERASE) {
|
|
|
|
|
|
|
|
if (fi->fc <= 0) break;
|
|
|
|
if (ts->transFlags & RPMTRANS_FLAG_JUSTDB) break;
|
2001-03-04 23:34:53 +08:00
|
|
|
if (ts->transFlags & RPMTRANS_FLAG_APPLYONLY) break;
|
2001-03-02 16:28:18 +08:00
|
|
|
|
2001-03-04 05:35:41 +08:00
|
|
|
psm->what = RPMCALLBACK_UNINST_START;
|
|
|
|
psm->amount = fi->fc; /* XXX W2DO? looks wrong. */
|
|
|
|
psm->total = fi->fc;
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = psmStage(psm, PSM_NOTIFY);
|
2001-03-02 16:28:18 +08:00
|
|
|
|
|
|
|
rc = fsmSetup(fi->fsm, FSM_PKGERASE, ts, fi,
|
|
|
|
NULL, NULL, &psm->failedFile);
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = fsmTeardown(fi->fsm);
|
2001-03-02 16:28:18 +08:00
|
|
|
|
2001-03-04 05:35:41 +08:00
|
|
|
psm->what = RPMCALLBACK_UNINST_STOP;
|
|
|
|
psm->amount = 0; /* XXX W2DO? looks wrong. */
|
|
|
|
psm->total = fi->fc;
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = psmStage(psm, PSM_NOTIFY);
|
2001-03-04 05:35:41 +08:00
|
|
|
|
2001-03-02 16:28:18 +08:00
|
|
|
}
|
|
|
|
if (psm->goal == PSM_PKGSAVE) {
|
|
|
|
fileAction * actions = fi->actions;
|
|
|
|
fileAction action = fi->action;
|
|
|
|
|
|
|
|
fi->action = FA_COPYOUT;
|
|
|
|
fi->actions = NULL;
|
|
|
|
|
2001-05-04 05:00:18 +08:00
|
|
|
if (psm->fd == NULL) { /* XXX can't happen */
|
|
|
|
rc = RPMRC_FAIL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/*@-nullpass@*/ /* LCL: psm->fd != NULL here. */
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = Fflush(psm->fd);
|
2001-03-02 23:03:29 +08:00
|
|
|
psm->cfd = Fdopen(fdDup(Fileno(psm->fd)), psm->rpmio_flags);
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@=nullpass@*/
|
|
|
|
if (psm->cfd == NULL) { /* XXX can't happen */
|
|
|
|
rc = RPMRC_FAIL;
|
|
|
|
break;
|
|
|
|
}
|
2001-03-02 23:03:29 +08:00
|
|
|
|
2001-06-26 04:01:42 +08:00
|
|
|
rc = fsmSetup(fi->fsm, FSM_PKGBUILD, ts, fi, psm->cfd,
|
|
|
|
NULL, &psm->failedFile);
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = fsmTeardown(fi->fsm);
|
2001-03-02 16:28:18 +08:00
|
|
|
|
2001-03-02 23:03:29 +08:00
|
|
|
saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = Fclose(psm->cfd);
|
2001-03-02 23:03:29 +08:00
|
|
|
psm->cfd = NULL;
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@-mods@*/
|
2001-03-02 23:03:29 +08:00
|
|
|
errno = saveerrno;
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@=mods@*/
|
2001-03-02 23:03:29 +08:00
|
|
|
|
2001-03-02 16:28:18 +08:00
|
|
|
fi->action = action;
|
|
|
|
fi->actions = actions;
|
|
|
|
}
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
2001-02-28 23:49:23 +08:00
|
|
|
case PSM_POST:
|
2001-03-03 03:47:45 +08:00
|
|
|
if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
|
2001-03-04 04:41:37 +08:00
|
|
|
|
2001-03-02 16:28:18 +08:00
|
|
|
if (psm->goal == PSM_PKGINSTALL) {
|
2001-08-03 13:04:13 +08:00
|
|
|
int_32 installTime = (int_32) time(NULL);
|
2001-03-03 00:17:03 +08:00
|
|
|
|
2001-10-19 00:39:54 +08:00
|
|
|
if (fi->h == NULL) break; /* XXX can't happen */
|
2001-05-23 22:25:19 +08:00
|
|
|
if (fi->fstates != NULL && fi->fc > 0)
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerAddEntry(fi->h, RPMTAG_FILESTATES, RPM_CHAR_TYPE,
|
2001-03-03 00:17:03 +08:00
|
|
|
fi->fstates, fi->fc);
|
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = headerAddEntry(fi->h, RPMTAG_INSTALLTIME, RPM_INT32_TYPE,
|
2001-03-03 00:17:03 +08:00
|
|
|
&installTime, 1);
|
|
|
|
|
|
|
|
if (ts->transFlags & RPMTRANS_FLAG_MULTILIB) {
|
|
|
|
uint_32 multiLib, * newMultiLib, * p;
|
|
|
|
|
2001-05-23 22:25:19 +08:00
|
|
|
if (hge(fi->h, RPMTAG_MULTILIBS, NULL,
|
|
|
|
(void **) &newMultiLib, NULL) &&
|
|
|
|
hge(psm->oh, RPMTAG_MULTILIBS, NULL,
|
|
|
|
(void **) &p, NULL))
|
2001-05-01 06:32:22 +08:00
|
|
|
{
|
2001-03-03 00:17:03 +08:00
|
|
|
multiLib = *p;
|
|
|
|
multiLib |= *newMultiLib;
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = hme(psm->oh, RPMTAG_MULTILIBS, RPM_INT32_TYPE,
|
2001-03-03 00:17:03 +08:00
|
|
|
&multiLib, 1);
|
|
|
|
}
|
|
|
|
rc = mergeFiles(fi, psm->oh, fi->h);
|
|
|
|
if (rc) break;
|
|
|
|
}
|
|
|
|
|
2001-03-04 23:34:53 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If this package has already been installed, remove it from
|
|
|
|
* the database before adding the new one.
|
|
|
|
*/
|
|
|
|
if (fi->record && !(ts->transFlags & RPMTRANS_FLAG_APPLYONLY)) {
|
|
|
|
rc = psmStage(psm, PSM_RPMDB_REMOVE);
|
|
|
|
if (rc) break;
|
|
|
|
}
|
2001-03-02 16:28:18 +08:00
|
|
|
|
|
|
|
rc = psmStage(psm, PSM_RPMDB_ADD);
|
|
|
|
if (rc) break;
|
|
|
|
|
2001-03-04 23:34:53 +08:00
|
|
|
psm->scriptTag = RPMTAG_POSTIN;
|
|
|
|
psm->progTag = RPMTAG_POSTINPROG;
|
|
|
|
psm->sense = RPMSENSE_TRIGGERIN;
|
|
|
|
psm->countCorrection = 0;
|
2001-03-02 16:28:18 +08:00
|
|
|
|
2001-03-04 23:34:53 +08:00
|
|
|
if (!(ts->transFlags & RPMTRANS_FLAG_NOPOST)) {
|
|
|
|
rc = psmStage(psm, PSM_SCRIPT);
|
|
|
|
if (rc) break;
|
|
|
|
}
|
|
|
|
if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERIN)) {
|
|
|
|
/* Run triggers in other package(s) this package sets off. */
|
|
|
|
rc = psmStage(psm, PSM_TRIGGERS);
|
|
|
|
if (rc) break;
|
2001-03-02 16:28:18 +08:00
|
|
|
|
2001-03-04 23:34:53 +08:00
|
|
|
/* Run triggers in this package other package(s) set off. */
|
|
|
|
rc = psmStage(psm, PSM_IMMED_TRIGGERS);
|
|
|
|
if (rc) break;
|
|
|
|
}
|
2001-03-02 16:28:18 +08:00
|
|
|
|
2001-03-04 23:34:53 +08:00
|
|
|
if (!(ts->transFlags & RPMTRANS_FLAG_APPLYONLY))
|
|
|
|
rc = markReplacedFiles(psm);
|
2001-03-02 23:03:29 +08:00
|
|
|
|
2001-03-02 16:28:18 +08:00
|
|
|
}
|
|
|
|
if (psm->goal == PSM_PKGERASE) {
|
2001-03-04 23:34:53 +08:00
|
|
|
|
2001-03-02 16:28:18 +08:00
|
|
|
psm->scriptTag = RPMTAG_POSTUN;
|
|
|
|
psm->progTag = RPMTAG_POSTUNPROG;
|
|
|
|
psm->sense = RPMSENSE_TRIGGERPOSTUN;
|
|
|
|
psm->countCorrection = -1;
|
|
|
|
|
2001-03-04 23:34:53 +08:00
|
|
|
if (!(ts->transFlags & RPMTRANS_FLAG_NOPOSTUN)) {
|
|
|
|
rc = psmStage(psm, PSM_SCRIPT);
|
|
|
|
/* XXX WTFO? postun failures don't cause erasure failure. */
|
|
|
|
}
|
2001-03-02 16:28:18 +08:00
|
|
|
|
2001-03-04 23:34:53 +08:00
|
|
|
if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERPOSTUN)) {
|
|
|
|
/* Run triggers in other package(s) this package sets off. */
|
|
|
|
rc = psmStage(psm, PSM_TRIGGERS);
|
|
|
|
if (rc) break;
|
|
|
|
}
|
2001-03-02 23:03:29 +08:00
|
|
|
|
2001-03-04 23:34:53 +08:00
|
|
|
if (!(ts->transFlags & RPMTRANS_FLAG_APPLYONLY))
|
|
|
|
rc = psmStage(psm, PSM_RPMDB_REMOVE);
|
2001-03-02 16:28:18 +08:00
|
|
|
}
|
2001-03-03 01:27:30 +08:00
|
|
|
if (psm->goal == PSM_PKGSAVE) {
|
|
|
|
}
|
2001-03-04 04:41:37 +08:00
|
|
|
|
|
|
|
/* Restore root directory if changed. */
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = psmStage(psm, PSM_CHROOT_OUT);
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
2001-02-28 23:49:23 +08:00
|
|
|
case PSM_UNDO:
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
2001-02-28 23:49:23 +08:00
|
|
|
case PSM_FINI:
|
2001-03-04 04:41:37 +08:00
|
|
|
/* Restore root directory if changed. */
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = psmStage(psm, PSM_CHROOT_OUT);
|
2001-03-04 04:41:37 +08:00
|
|
|
|
2001-03-02 23:03:29 +08:00
|
|
|
if (psm->fd) {
|
|
|
|
saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = Fclose(psm->fd);
|
2001-03-02 23:03:29 +08:00
|
|
|
psm->fd = NULL;
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@-mods@*/
|
2001-03-02 23:03:29 +08:00
|
|
|
errno = saveerrno;
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@=mods@*/
|
2001-03-02 23:03:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (psm->goal == PSM_PKGSAVE) {
|
2001-06-26 04:01:42 +08:00
|
|
|
if (!rc) {
|
2001-05-06 03:28:32 +08:00
|
|
|
rpmMessage(RPMMESS_VERBOSE, _("Wrote: %s\n"),
|
|
|
|
(psm->pkgURL ? psm->pkgURL : "???"));
|
2001-06-26 04:01:42 +08:00
|
|
|
}
|
2001-03-02 23:03:29 +08:00
|
|
|
}
|
|
|
|
|
2001-08-28 02:39:17 +08:00
|
|
|
if (rc) {
|
|
|
|
if (psm->failedFile)
|
|
|
|
rpmError(RPMERR_CPIO,
|
|
|
|
_("%s failed on file %s: %s\n"),
|
|
|
|
psm->stepName, psm->failedFile, cpioStrerror(rc));
|
|
|
|
else
|
|
|
|
rpmError(RPMERR_CPIO, _("%s failed: %s\n"),
|
|
|
|
psm->stepName, cpioStrerror(rc));
|
|
|
|
}
|
|
|
|
|
2001-05-23 22:25:19 +08:00
|
|
|
if (fi->h && (psm->goal == PSM_PKGERASE || psm->goal == PSM_PKGSAVE))
|
|
|
|
fi->h = headerFree(fi->h);
|
|
|
|
psm->oh = headerFree(psm->oh);
|
2001-03-02 16:28:18 +08:00
|
|
|
psm->pkgURL = _free(psm->pkgURL);
|
|
|
|
psm->rpmio_flags = _free(psm->rpmio_flags);
|
|
|
|
psm->failedFile = _free(psm->failedFile);
|
2001-03-03 03:47:45 +08:00
|
|
|
|
|
|
|
fi->fgids = _free(fi->fgids);
|
|
|
|
fi->fuids = _free(fi->fuids);
|
|
|
|
fi->fgroup = hfd(fi->fgroup, -1);
|
|
|
|
fi->fuser = hfd(fi->fuser, -1);
|
|
|
|
fi->apath = _free(fi->apath);
|
|
|
|
fi->fstates = _free(fi->fstates);
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
2001-03-02 00:01:16 +08:00
|
|
|
|
|
|
|
case PSM_PKGINSTALL:
|
|
|
|
case PSM_PKGERASE:
|
2001-03-03 03:47:45 +08:00
|
|
|
case PSM_PKGSAVE:
|
|
|
|
psm->goal = stage;
|
|
|
|
psm->rc = RPMRC_OK;
|
|
|
|
psm->stepName = pkgStageString(stage);
|
|
|
|
|
|
|
|
rc = psmStage(psm, PSM_INIT);
|
|
|
|
if (!rc) rc = psmStage(psm, PSM_PRE);
|
|
|
|
if (!rc) rc = psmStage(psm, PSM_PROCESS);
|
|
|
|
if (!rc) rc = psmStage(psm, PSM_POST);
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = psmStage(psm, PSM_FINI);
|
2001-03-02 16:28:18 +08:00
|
|
|
break;
|
2001-03-02 00:01:16 +08:00
|
|
|
case PSM_PKGCOMMIT:
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
2001-03-02 00:01:16 +08:00
|
|
|
|
2001-02-28 23:49:23 +08:00
|
|
|
case PSM_CREATE:
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
2001-03-02 00:01:16 +08:00
|
|
|
case PSM_NOTIFY:
|
2001-10-16 22:58:57 +08:00
|
|
|
if (ts && ts->notify) {
|
|
|
|
/*@-noeffectuncon @*/ /* FIX: check rc */
|
2001-03-04 05:35:41 +08:00
|
|
|
(void) ts->notify(fi->h, psm->what, psm->amount, psm->total,
|
|
|
|
(fi->ap ? fi->ap->key : NULL), ts->notifyData);
|
2001-10-16 22:58:57 +08:00
|
|
|
/*@=noeffectuncon @*/
|
|
|
|
}
|
2001-03-02 00:01:16 +08:00
|
|
|
break;
|
2001-02-28 23:49:23 +08:00
|
|
|
case PSM_DESTROY:
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
2001-03-02 00:01:16 +08:00
|
|
|
case PSM_COMMIT:
|
2001-03-02 23:03:29 +08:00
|
|
|
if (!(ts->transFlags & RPMTRANS_FLAG_PKGCOMMIT)) break;
|
2001-03-04 23:34:53 +08:00
|
|
|
if (ts->transFlags & RPMTRANS_FLAG_APPLYONLY) break;
|
|
|
|
|
2001-03-02 23:03:29 +08:00
|
|
|
rc = fsmSetup(fi->fsm, FSM_PKGCOMMIT, ts, fi,
|
|
|
|
NULL, NULL, &psm->failedFile);
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = fsmTeardown(fi->fsm);
|
2001-03-02 00:01:16 +08:00
|
|
|
break;
|
2001-02-28 23:49:23 +08:00
|
|
|
|
|
|
|
case PSM_CHROOT_IN:
|
|
|
|
/* Change root directory if requested and not already done. */
|
|
|
|
if (ts->rootDir && !ts->chrootDone && !psm->chrootDone) {
|
|
|
|
static int _loaded = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This loads all of the name services libraries, in case we
|
|
|
|
* don't have access to them in the chroot().
|
|
|
|
*/
|
|
|
|
if (!_loaded) {
|
|
|
|
(void)getpwnam("root");
|
|
|
|
endpwent();
|
|
|
|
_loaded++;
|
|
|
|
}
|
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = chdir("/");
|
2001-10-14 03:35:58 +08:00
|
|
|
/*@-superuser@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
rc = chroot(ts->rootDir);
|
2001-10-14 03:35:58 +08:00
|
|
|
/*@=superuser@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
psm->chrootDone = ts->chrootDone = 1;
|
2001-08-03 23:17:55 +08:00
|
|
|
if (ts->rpmdb != NULL) ts->rpmdb->db_chrootDone = 1;
|
|
|
|
/*@-onlytrans@*/
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@-mods@*/
|
2001-07-28 08:33:07 +08:00
|
|
|
chroot_prefix = ts->rootDir;
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@=mods@*/
|
2001-08-03 23:17:55 +08:00
|
|
|
/*@=onlytrans@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
}
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
2001-02-28 23:49:23 +08:00
|
|
|
case PSM_CHROOT_OUT:
|
|
|
|
/* Restore root directory if changed. */
|
|
|
|
if (psm->chrootDone) {
|
2001-10-14 03:35:58 +08:00
|
|
|
/*@-superuser@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
rc = chroot(".");
|
2001-10-14 03:35:58 +08:00
|
|
|
/*@=superuser@*/
|
2001-02-28 23:49:23 +08:00
|
|
|
psm->chrootDone = ts->chrootDone = 0;
|
2001-08-03 23:17:55 +08:00
|
|
|
if (ts->rpmdb != NULL) ts->rpmdb->db_chrootDone = 0;
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@-mods@*/
|
2001-07-28 08:33:07 +08:00
|
|
|
chroot_prefix = NULL;
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@=mods@*/
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = chdir(ts->currDir);
|
2001-02-28 23:49:23 +08:00
|
|
|
}
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
2001-10-19 09:24:21 +08:00
|
|
|
case PSM_SCRIPT: /* Run current package scriptlets. */
|
2001-02-28 23:49:23 +08:00
|
|
|
rc = runInstScript(psm);
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
2001-03-01 00:41:19 +08:00
|
|
|
case PSM_TRIGGERS:
|
2001-03-04 05:35:41 +08:00
|
|
|
/* Run triggers in other package(s) this package sets off. */
|
2001-03-02 00:01:16 +08:00
|
|
|
rc = runTriggers(psm);
|
2001-03-01 00:41:19 +08:00
|
|
|
break;
|
2001-10-19 09:24:21 +08:00
|
|
|
case PSM_IMMED_TRIGGERS:
|
2001-03-04 05:35:41 +08:00
|
|
|
/* Run triggers in this package other package(s) set off. */
|
2001-03-02 00:01:16 +08:00
|
|
|
rc = runImmedTriggers(psm);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PSM_RPMIO_FLAGS:
|
|
|
|
{ const char * payload_compressor = NULL;
|
|
|
|
char * t;
|
|
|
|
|
|
|
|
if (!hge(fi->h, RPMTAG_PAYLOADCOMPRESSOR, NULL,
|
|
|
|
(void **) &payload_compressor, NULL))
|
|
|
|
payload_compressor = "gzip";
|
|
|
|
psm->rpmio_flags = t = xmalloc(sizeof("w9.gzdio"));
|
2001-03-02 16:28:18 +08:00
|
|
|
*t = '\0';
|
|
|
|
t = stpcpy(t, ((psm->goal == PSM_PKGSAVE) ? "w9" : "r"));
|
2001-03-02 00:01:16 +08:00
|
|
|
if (!strcmp(payload_compressor, "gzip"))
|
|
|
|
t = stpcpy(t, ".gzdio");
|
|
|
|
if (!strcmp(payload_compressor, "bzip2"))
|
|
|
|
t = stpcpy(t, ".bzdio");
|
2001-03-03 01:27:30 +08:00
|
|
|
rc = RPMRC_OK;
|
2001-03-02 00:01:16 +08:00
|
|
|
} break;
|
|
|
|
|
|
|
|
case PSM_RPMDB_LOAD:
|
2001-03-03 03:47:45 +08:00
|
|
|
assert(psm->mi == NULL);
|
|
|
|
psm->mi = rpmdbInitIterator(ts->rpmdb, RPMDBI_PACKAGES,
|
2001-03-02 00:01:16 +08:00
|
|
|
&fi->record, sizeof(fi->record));
|
|
|
|
|
2001-03-03 03:47:45 +08:00
|
|
|
fi->h = rpmdbNextIterator(psm->mi);
|
2001-03-02 00:01:16 +08:00
|
|
|
if (fi->h)
|
|
|
|
fi->h = headerLink(fi->h);
|
2001-05-14 01:55:58 +08:00
|
|
|
else {
|
|
|
|
fprintf(stderr, "*** PSM_RDB_LOAD: header #%u not found\n", fi->record);
|
|
|
|
}
|
2001-04-30 06:43:01 +08:00
|
|
|
psm->mi = rpmdbFreeIterator(psm->mi);
|
2001-03-03 03:47:45 +08:00
|
|
|
rc = (fi->h ? RPMRC_OK : RPMRC_FAIL);
|
|
|
|
break;
|
2001-03-02 00:01:16 +08:00
|
|
|
case PSM_RPMDB_ADD:
|
|
|
|
if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
|
2001-10-19 00:39:54 +08:00
|
|
|
if (fi->h != NULL) /* XXX can't happen */
|
2001-03-02 00:01:16 +08:00
|
|
|
rc = rpmdbAdd(ts->rpmdb, ts->id, fi->h);
|
|
|
|
break;
|
|
|
|
case PSM_RPMDB_REMOVE:
|
|
|
|
if (ts->transFlags & RPMTRANS_FLAG_TEST) break;
|
|
|
|
rc = rpmdbRemove(ts->rpmdb, ts->id, fi->record);
|
2001-02-28 06:08:53 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
2001-02-28 06:08:53 +08:00
|
|
|
|
2001-05-06 03:28:32 +08:00
|
|
|
/*@-nullstate@*/ /* FIX: psm->oh and psm->fi->h may be NULL. */
|
2001-02-28 06:08:53 +08:00
|
|
|
return rc;
|
2001-05-06 03:28:32 +08:00
|
|
|
/*@=nullstate@*/
|
2001-02-28 06:08:53 +08:00
|
|
|
}
|
2001-10-19 00:39:54 +08:00
|
|
|
/*@=nullpass@*/
|