|
|
2ff057 |
/** \ingroup rpmdep
|
|
|
2ff057 |
* \file lib/rpmte.c
|
|
|
2ff057 |
* Routine(s) to handle an "rpmte" transaction element.
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
#include "system.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
#include <rpm/rpmtypes.h>
|
|
|
2ff057 |
#include <rpm/rpmlib.h> /* RPM_MACHTABLE_* */
|
|
|
2ff057 |
#include <rpm/rpmmacro.h>
|
|
|
2ff057 |
#include <rpm/rpmds.h>
|
|
|
2ff057 |
#include <rpm/rpmfi.h>
|
|
|
2ff057 |
#include <rpm/rpmts.h>
|
|
|
2ff057 |
#include <rpm/rpmdb.h>
|
|
|
2ff057 |
#include <rpm/rpmlog.h>
|
|
|
2ff057 |
|
|
|
2ff057 |
#include "lib/misc.h"
|
|
|
2ff057 |
#include "lib/rpmplugins.h"
|
|
|
2ff057 |
#include "lib/rpmte_internal.h"
|
|
|
2ff057 |
/* strpool-related interfaces */
|
|
|
2ff057 |
#include "lib/rpmfi_internal.h"
|
|
|
2ff057 |
#include "lib/rpmds_internal.h"
|
|
|
2ff057 |
#include "lib/rpmts_internal.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
#include "debug.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
/** \ingroup rpmte
|
|
|
2ff057 |
* A single package instance to be installed/removed atomically.
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
struct rpmte_s {
|
|
|
2ff057 |
rpmElementType type; /*!< Package disposition (installed/removed). */
|
|
|
2ff057 |
|
|
|
2ff057 |
Header h; /*!< Package header. */
|
|
|
2ff057 |
char * NEVR; /*!< Package name-version-release. */
|
|
|
2ff057 |
char * NEVRA; /*!< Package name-version-release.arch. */
|
|
|
2ff057 |
char * name; /*!< Name: */
|
|
|
2ff057 |
char * epoch;
|
|
|
2ff057 |
char * version; /*!< Version: */
|
|
|
2ff057 |
char * release; /*!< Release: */
|
|
|
2ff057 |
char * arch; /*!< Architecture hint. */
|
|
|
2ff057 |
char * os; /*!< Operating system hint. */
|
|
|
2ff057 |
int isSource; /*!< (TR_ADDED) source rpm? */
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmte depends; /*!< Package updated by this package (ERASE te) */
|
|
|
2ff057 |
rpmte parent; /*!< Parent transaction element. */
|
|
|
2ff057 |
unsigned int db_instance; /*!< Database instance (of removed pkgs) */
|
|
|
2ff057 |
tsortInfo tsi; /*!< Dependency ordering chains. */
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmds thisds; /*!< This package's provided NEVR. */
|
|
|
2ff057 |
rpmds provides; /*!< Provides: dependencies. */
|
|
|
2ff057 |
rpmds requires; /*!< Requires: dependencies. */
|
|
|
2ff057 |
rpmds conflicts; /*!< Conflicts: dependencies. */
|
|
|
2ff057 |
rpmds obsoletes; /*!< Obsoletes: dependencies. */
|
|
|
2ff057 |
rpmds order; /*!< Order: dependencies. */
|
|
|
2ff057 |
rpmds recommends; /*!< Recommends: dependencies. */
|
|
|
2ff057 |
rpmds suggests; /*!< Suggests: dependencies. */
|
|
|
2ff057 |
rpmds supplements; /*!< Supplements: dependencies. */
|
|
|
2ff057 |
rpmds enhances; /*!< Enhances: dependencies. */
|
|
|
2ff057 |
rpmfiles files; /*!< File information. */
|
|
|
2ff057 |
rpmfi fi; /*!< File iterator (backwards compat) */
|
|
|
2ff057 |
rpmps probs; /*!< Problems (relocations) */
|
|
|
2ff057 |
rpmts ts; /*!< Parent transaction */
|
|
|
2ff057 |
|
|
|
2ff057 |
rpm_color_t color; /*!< Color bit(s) from package dependencies. */
|
|
|
2ff057 |
rpm_loff_t pkgFileSize; /*!< No. of bytes in package file (approx). */
|
|
|
2ff057 |
unsigned int headerSize; /*!< No. of bytes in package header */
|
|
|
2ff057 |
|
|
|
2ff057 |
fnpyKey key; /*!< (TR_ADDED) Retrieval key. */
|
|
|
2ff057 |
rpmRelocation * relocs; /*!< (TR_ADDED) Payload file relocations. */
|
|
|
2ff057 |
int nrelocs; /*!< (TR_ADDED) No. of relocations. */
|
|
|
2ff057 |
uint8_t *badrelocs; /*!< (TR_ADDED) Bad relocations (or NULL) */
|
|
|
2ff057 |
FD_t fd; /*!< (TR_ADDED) Payload file descriptor. */
|
|
Panu Matilainen |
d6b3d4 |
int verified; /*!< (TR_ADDED) Verification status */
|
|
|
2ff057 |
|
|
|
2ff057 |
#define RPMTE_HAVE_PRETRANS (1 << 0)
|
|
|
2ff057 |
#define RPMTE_HAVE_POSTTRANS (1 << 1)
|
|
|
2ff057 |
int transscripts; /*!< pre/posttrans script existence */
|
|
|
2ff057 |
int failed; /*!< (parent) install/erase failed */
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmfs fs;
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
/* forward declarations */
|
|
|
2ff057 |
static void rpmteColorDS(rpmte te, rpmTag tag);
|
|
|
2ff057 |
static int rpmteClose(rpmte te, int reset_fi);
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmteCleanDS(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
te->thisds = rpmdsFree(te->thisds);
|
|
|
2ff057 |
te->provides = rpmdsFree(te->provides);
|
|
|
2ff057 |
te->requires = rpmdsFree(te->requires);
|
|
|
2ff057 |
te->conflicts = rpmdsFree(te->conflicts);
|
|
|
2ff057 |
te->obsoletes = rpmdsFree(te->obsoletes);
|
|
|
2ff057 |
te->recommends = rpmdsFree(te->recommends);
|
|
|
2ff057 |
te->suggests = rpmdsFree(te->suggests);
|
|
|
2ff057 |
te->supplements = rpmdsFree(te->supplements);
|
|
|
2ff057 |
te->enhances = rpmdsFree(te->enhances);
|
|
|
2ff057 |
te->order = rpmdsFree(te->order);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmfiles getFiles(rpmte p, Header h)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmfiFlags fiflags;
|
|
|
2ff057 |
fiflags = (p->type == TR_ADDED) ? (RPMFI_NOHEADER | RPMFI_FLAGS_INSTALL) :
|
|
|
2ff057 |
(RPMFI_NOHEADER | RPMFI_FLAGS_ERASE);
|
|
|
2ff057 |
|
|
|
2ff057 |
/* relocate stuff in header if necessary */
|
|
|
2ff057 |
if (rpmteType(p) == TR_ADDED && rpmfsFC(p->fs) > 0) {
|
|
|
2ff057 |
if (!headerIsEntry(h, RPMTAG_ORIGBASENAMES)) {
|
|
|
2ff057 |
if (rpmteIsSource(p)) {
|
|
|
2ff057 |
/* Unlike binary packages, source relocation can fail */
|
|
|
2ff057 |
if (rpmRelocateSrpmFileList(h, rpmtsRootDir(p->ts)) < 0) {
|
|
|
2ff057 |
return NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
rpmRelocateFileList(p->relocs, p->nrelocs, p->fs, h);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return rpmfilesNew(rpmtsPool(p->ts), h, RPMTAG_BASENAMES, fiflags);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/**
|
|
|
2ff057 |
* Initialize transaction element data from header.
|
|
|
2ff057 |
* @param p transaction element
|
|
|
2ff057 |
* @param h header
|
|
|
2ff057 |
* @param key (TR_ADDED) package retrieval key (e.g. file name)
|
|
|
2ff057 |
* @param relocs (TR_ADDED) package file relocations
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmstrPool tspool = rpmtsPool(p->ts);
|
|
|
2ff057 |
struct rpmtd_s bnames;
|
|
|
2ff057 |
int rc = 1; /* assume failure */
|
|
|
2ff057 |
|
|
|
2ff057 |
p->name = headerGetAsString(h, RPMTAG_NAME);
|
|
|
2ff057 |
p->version = headerGetAsString(h, RPMTAG_VERSION);
|
|
|
2ff057 |
p->release = headerGetAsString(h, RPMTAG_RELEASE);
|
|
|
2ff057 |
|
|
|
2ff057 |
/* name, version and release are required in all packages */
|
|
|
2ff057 |
if (p->name == NULL || p->version == NULL || p->release == NULL)
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
|
|
|
2ff057 |
p->epoch = headerGetAsString(h, RPMTAG_EPOCH);
|
|
|
2ff057 |
|
|
|
2ff057 |
p->arch = headerGetAsString(h, RPMTAG_ARCH);
|
|
|
2ff057 |
p->os = headerGetAsString(h, RPMTAG_OS);
|
|
|
2ff057 |
|
|
|
2ff057 |
/* gpg-pubkey's dont have os or arch (sigh), for others they are required */
|
|
|
2ff057 |
if (!rstreq(p->name, "gpg-pubkey") && (p->arch == NULL || p->os == NULL))
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
|
|
|
2ff057 |
p->isSource = headerIsSource(h);
|
|
|
2ff057 |
|
|
|
2ff057 |
p->NEVR = headerGetAsString(h, RPMTAG_NEVR);
|
|
|
2ff057 |
p->NEVRA = headerGetAsString(h, RPMTAG_NEVRA);
|
|
|
2ff057 |
|
|
|
2ff057 |
p->nrelocs = 0;
|
|
|
2ff057 |
p->relocs = NULL;
|
|
|
2ff057 |
p->badrelocs = NULL;
|
|
|
2ff057 |
if (relocs != NULL)
|
|
|
2ff057 |
rpmRelocationBuild(h, relocs, &p->nrelocs, &p->relocs, &p->badrelocs);
|
|
|
2ff057 |
|
|
|
2ff057 |
p->db_instance = headerGetInstance(h);
|
|
|
2ff057 |
p->key = key;
|
|
|
2ff057 |
p->fd = NULL;
|
|
|
2ff057 |
|
|
|
2ff057 |
p->pkgFileSize = 0;
|
|
|
2ff057 |
p->headerSize = headerSizeof(h, HEADER_MAGIC_NO);
|
|
|
2ff057 |
|
|
|
2ff057 |
p->thisds = rpmdsThisPool(tspool, h, RPMTAG_PROVIDENAME, RPMSENSE_EQUAL);
|
|
|
2ff057 |
p->provides = rpmdsNewPool(tspool, h, RPMTAG_PROVIDENAME, 0);
|
|
|
2ff057 |
p->requires = rpmdsNewPool(tspool, h, RPMTAG_REQUIRENAME, 0);
|
|
|
2ff057 |
p->conflicts = rpmdsNewPool(tspool, h, RPMTAG_CONFLICTNAME, 0);
|
|
|
2ff057 |
p->obsoletes = rpmdsNewPool(tspool, h, RPMTAG_OBSOLETENAME, 0);
|
|
|
2ff057 |
p->order = rpmdsNewPool(tspool, h, RPMTAG_ORDERNAME, 0);
|
|
|
2ff057 |
p->recommends = rpmdsNewPool(tspool, h, RPMTAG_RECOMMENDNAME, 0);
|
|
|
2ff057 |
p->suggests = rpmdsNewPool(tspool, h, RPMTAG_SUGGESTNAME, 0);
|
|
|
2ff057 |
p->supplements = rpmdsNewPool(tspool, h, RPMTAG_SUPPLEMENTNAME, 0);
|
|
|
2ff057 |
p->enhances = rpmdsNewPool(tspool, h, RPMTAG_ENHANCENAME, 0);
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Relocation needs to know file count before rpmfiNew() */
|
|
|
2ff057 |
headerGet(h, RPMTAG_BASENAMES, &bnames, HEADERGET_MINMEM);
|
|
|
2ff057 |
p->fs = rpmfsNew(rpmtdCount(&bnames), (p->type == TR_ADDED));
|
|
|
2ff057 |
rpmtdFreeData(&bnames);
|
|
|
2ff057 |
|
|
|
2ff057 |
p->files = getFiles(p, h);
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Packages with no files return an empty file info set, NULL is an error */
|
|
|
2ff057 |
if (p->files == NULL)
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* See if we have pre/posttrans scripts. */
|
|
|
2ff057 |
p->transscripts |= (headerIsEntry(h, RPMTAG_PRETRANS) ||
|
|
|
2ff057 |
headerIsEntry(h, RPMTAG_PRETRANSPROG)) ?
|
|
|
2ff057 |
RPMTE_HAVE_PRETRANS : 0;
|
|
|
2ff057 |
p->transscripts |= (headerIsEntry(h, RPMTAG_POSTTRANS) ||
|
|
|
2ff057 |
headerIsEntry(h, RPMTAG_POSTTRANSPROG)) ?
|
|
|
2ff057 |
RPMTE_HAVE_POSTTRANS : 0;
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmteColorDS(p, RPMTAG_PROVIDENAME);
|
|
|
2ff057 |
rpmteColorDS(p, RPMTAG_REQUIRENAME);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (p->type == TR_ADDED)
|
|
|
2ff057 |
p->pkgFileSize = headerGetNumber(h, RPMTAG_LONGSIGSIZE) + 96 + 256;
|
|
|
2ff057 |
|
|
|
2ff057 |
rc = 0;
|
|
|
2ff057 |
|
|
|
2ff057 |
exit:
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmte rpmteFree(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (te != NULL) {
|
|
|
2ff057 |
if (te->relocs) {
|
|
|
2ff057 |
for (int i = 0; i < te->nrelocs; i++) {
|
|
|
2ff057 |
free(te->relocs[i].oldPath);
|
|
|
2ff057 |
free(te->relocs[i].newPath);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
free(te->relocs);
|
|
|
2ff057 |
free(te->badrelocs);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
free(te->os);
|
|
|
2ff057 |
free(te->arch);
|
|
|
2ff057 |
free(te->epoch);
|
|
|
2ff057 |
free(te->name);
|
|
|
2ff057 |
free(te->version);
|
|
|
2ff057 |
free(te->release);
|
|
|
2ff057 |
free(te->NEVR);
|
|
|
2ff057 |
free(te->NEVRA);
|
|
|
2ff057 |
|
|
|
2ff057 |
fdFree(te->fd);
|
|
|
2ff057 |
rpmfiFree(te->fi);
|
|
|
2ff057 |
rpmfilesFree(te->files);
|
|
|
2ff057 |
headerFree(te->h);
|
|
|
2ff057 |
rpmfsFree(te->fs);
|
|
|
2ff057 |
rpmpsFree(te->probs);
|
|
|
2ff057 |
rpmteCleanDS(te);
|
|
|
2ff057 |
|
|
|
2ff057 |
memset(te, 0, sizeof(*te)); /* XXX trash and burn */
|
|
|
2ff057 |
free(te);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmte rpmteNew(rpmts ts, Header h, rpmElementType type, fnpyKey key,
|
|
|
2ff057 |
rpmRelocation * relocs)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmte p = xcalloc(1, sizeof(*p));
|
|
|
2ff057 |
p->ts = ts;
|
|
|
2ff057 |
p->type = type;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (addTE(p, h, key, relocs)) {
|
|
|
2ff057 |
rpmteFree(p);
|
|
|
2ff057 |
return NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
return p;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
unsigned int rpmteDBInstance(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->db_instance : 0);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmteSetDBInstance(rpmte te, unsigned int instance)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (te != NULL)
|
|
|
2ff057 |
te->db_instance = instance;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
Header rpmteHeader(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL && te->h != NULL ? headerLink(te->h) : NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
Header rpmteSetHeader(rpmte te, Header h)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (te != NULL) {
|
|
|
2ff057 |
te->h = headerFree(te->h);
|
|
|
2ff057 |
if (h != NULL)
|
|
|
2ff057 |
te->h = headerLink(h);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmElementType rpmteType(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
/* XXX returning negative for unsigned type */
|
|
|
2ff057 |
return (te != NULL ? te->type : -1);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
const char * rpmteN(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->name : NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
const char * rpmteE(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->epoch : NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
const char * rpmteV(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->version : NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
const char * rpmteR(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->release : NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
const char * rpmteA(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->arch : NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
const char * rpmteO(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->os : NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmteIsSource(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->isSource : 0);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpm_color_t rpmteColor(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->color : 0);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpm_color_t rpmteSetColor(rpmte te, rpm_color_t color)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpm_color_t ocolor = 0;
|
|
|
2ff057 |
if (te != NULL) {
|
|
|
2ff057 |
ocolor = te->color;
|
|
|
2ff057 |
te->color = color;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return ocolor;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpm_loff_t rpmtePkgFileSize(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->pkgFileSize : 0);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
unsigned int rpmteHeaderSize(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->headerSize : 0);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmte rpmteParent(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->parent : NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmte rpmteSetParent(rpmte te, rpmte pte)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmte opte = NULL;
|
|
|
2ff057 |
if (te != NULL) {
|
|
|
2ff057 |
opte = te->parent;
|
|
|
2ff057 |
te->parent = pte;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return opte;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
tsortInfo rpmteTSI(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return te->tsi;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmteSetTSI(rpmte te, tsortInfo tsi)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
te->tsi = tsi;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmteSetDependsOn(rpmte te, rpmte depends)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
te->depends = depends;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmte rpmteDependsOn(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return te->depends;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmteDBOffset(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return rpmteDBInstance(te);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
const char * rpmteEVR(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->NEVR + strlen(te->name) + 1 : NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
const char * rpmteNEVR(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->NEVR : NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
const char * rpmteNEVRA(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->NEVRA : NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
FD_t rpmteSetFd(rpmte te, FD_t fd)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (te != NULL) {
|
|
|
2ff057 |
if (te->fd != NULL)
|
|
|
2ff057 |
te->fd = fdFree(te->fd);
|
|
|
2ff057 |
if (fd != NULL)
|
|
|
2ff057 |
te->fd = fdLink(fd);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
fnpyKey rpmteKey(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL ? te->key : NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmds rpmteDS(rpmte te, rpmTagVal tag)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (te == NULL)
|
|
|
2ff057 |
return NULL;
|
|
|
2ff057 |
|
|
|
2ff057 |
switch (tag) {
|
|
|
2ff057 |
case RPMTAG_NAME: return te->thisds;
|
|
|
2ff057 |
case RPMTAG_PROVIDENAME: return te->provides;
|
|
|
2ff057 |
case RPMTAG_REQUIRENAME: return te->requires;
|
|
|
2ff057 |
case RPMTAG_CONFLICTNAME: return te->conflicts;
|
|
|
2ff057 |
case RPMTAG_OBSOLETENAME: return te->obsoletes;
|
|
|
2ff057 |
case RPMTAG_ORDERNAME: return te->order;
|
|
|
2ff057 |
case RPMTAG_RECOMMENDNAME: return te->recommends;
|
|
|
2ff057 |
case RPMTAG_SUGGESTNAME: return te->suggests;
|
|
|
2ff057 |
case RPMTAG_SUPPLEMENTNAME: return te->supplements;
|
|
|
2ff057 |
case RPMTAG_ENHANCENAME: return te->enhances;
|
|
|
2ff057 |
default: break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmteCleanFiles(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (te != NULL) {
|
|
|
2ff057 |
te->fi = rpmfiFree(te->fi);
|
|
|
2ff057 |
te->files = rpmfilesFree(te->files);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmfi rpmteFI(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (te == NULL)
|
|
|
2ff057 |
return NULL;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (te->fi == NULL)
|
|
|
2ff057 |
te->fi = rpmfilesIter(te->files, RPMFI_ITER_FWD);
|
|
|
2ff057 |
|
|
|
2ff057 |
return te->fi; /* XXX take fi reference here? */
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmfiles rpmteFiles(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL) ? rpmfilesLink(te->files) : NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static void rpmteColorDS(rpmte te, rpmTag tag)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmfi fi;
|
|
|
2ff057 |
rpmds ds = rpmteDS(te, tag);
|
|
|
2ff057 |
char deptype = 'R';
|
|
|
2ff057 |
char mydt;
|
|
|
2ff057 |
const uint32_t * ddict;
|
|
|
2ff057 |
rpm_color_t * colors;
|
|
|
2ff057 |
rpm_color_t val;
|
|
|
2ff057 |
int Count;
|
|
|
2ff057 |
unsigned ix;
|
|
|
2ff057 |
int ndx, i;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!(te && (Count = rpmdsCount(ds)) > 0 && rpmfilesFC(te->files) > 0))
|
|
|
2ff057 |
return;
|
|
|
2ff057 |
|
|
|
2ff057 |
switch (tag) {
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
return;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case RPMTAG_PROVIDENAME:
|
|
|
2ff057 |
deptype = 'P';
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case RPMTAG_REQUIRENAME:
|
|
|
2ff057 |
deptype = 'R';
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
colors = xcalloc(Count, sizeof(*colors));
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Calculate dependency color. */
|
|
|
2ff057 |
fi = rpmfilesIter(te->files, RPMFI_ITER_FWD);
|
|
|
2ff057 |
while (rpmfiNext(fi) >= 0) {
|
|
|
2ff057 |
val = rpmfiFColor(fi);
|
|
|
2ff057 |
ddict = NULL;
|
|
|
2ff057 |
ndx = rpmfiFDepends(fi, &ddict);
|
|
|
2ff057 |
if (ddict != NULL)
|
|
|
2ff057 |
while (ndx-- > 0) {
|
|
|
2ff057 |
ix = *ddict++;
|
|
|
2ff057 |
mydt = ((ix >> 24) & 0xff);
|
|
|
2ff057 |
if (mydt != deptype)
|
|
|
2ff057 |
continue;
|
|
|
2ff057 |
ix &= 0x00ffffff;
|
|
|
2ff057 |
assert (ix < Count);
|
|
|
2ff057 |
colors[ix] |= val;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Set color values in dependency set. */
|
|
|
2ff057 |
ds = rpmdsInit(ds);
|
|
|
2ff057 |
while ((i = rpmdsNext(ds)) >= 0) {
|
|
|
2ff057 |
val = colors[i];
|
|
|
2ff057 |
te->color |= val;
|
|
|
2ff057 |
(void) rpmdsSetColor(ds, val);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
free(colors);
|
|
|
2ff057 |
rpmfiFree(fi);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static Header rpmteDBHeader(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
Header h = NULL;
|
|
|
2ff057 |
rpmdbMatchIterator mi;
|
|
|
2ff057 |
|
|
|
2ff057 |
mi = rpmtsInitIterator(te->ts, RPMDBI_PACKAGES,
|
|
|
2ff057 |
&te->db_instance, sizeof(te->db_instance));
|
|
|
2ff057 |
/* iterator returns weak refs, grab hold of header */
|
|
|
2ff057 |
if ((h = rpmdbNextIterator(mi)))
|
|
|
2ff057 |
h = headerLink(h);
|
|
|
2ff057 |
rpmdbFreeIterator(mi);
|
|
|
2ff057 |
return h;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static Header rpmteFDHeader(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
Header h = NULL;
|
|
|
2ff057 |
te->fd = rpmtsNotify(te->ts, te, RPMCALLBACK_INST_OPEN_FILE, 0, 0);
|
|
|
2ff057 |
if (te->fd != NULL) {
|
|
|
2ff057 |
rpmVSFlags ovsflags;
|
|
|
2ff057 |
rpmRC pkgrc;
|
|
|
2ff057 |
|
|
|
2ff057 |
ovsflags = rpmtsSetVSFlags(te->ts,
|
|
|
2ff057 |
rpmtsVSFlags(te->ts) | RPMVSF_NEEDPAYLOAD);
|
|
|
2ff057 |
pkgrc = rpmReadPackageFile(te->ts, te->fd, rpmteNEVRA(te), &h);
|
|
|
2ff057 |
rpmtsSetVSFlags(te->ts, ovsflags);
|
|
|
2ff057 |
switch (pkgrc) {
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
rpmteClose(te, 1);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case RPMRC_NOTTRUSTED:
|
|
|
2ff057 |
case RPMRC_NOKEY:
|
|
|
2ff057 |
case RPMRC_OK:
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return h;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpmteOpen(rpmte te, int reload_fi)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
int rc = 0; /* assume failure */
|
|
|
2ff057 |
Header h = NULL;
|
|
|
2ff057 |
if (te == NULL || te->ts == NULL || rpmteFailed(te))
|
|
|
2ff057 |
goto exit;
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmteSetHeader(te, NULL);
|
|
|
2ff057 |
|
|
|
2ff057 |
switch (rpmteType(te)) {
|
|
|
2ff057 |
case TR_ADDED:
|
|
|
2ff057 |
h = rpmteDBInstance(te) ? rpmteDBHeader(te) : rpmteFDHeader(te);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case TR_REMOVED:
|
|
|
2ff057 |
h = rpmteDBHeader(te);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (h != NULL) {
|
|
|
2ff057 |
if (reload_fi) {
|
|
|
2ff057 |
/* This can fail if we get a different, bad header from callback */
|
|
|
2ff057 |
te->files = getFiles(te, h);
|
|
|
2ff057 |
rc = (te->files != NULL);
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
rc = 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmteSetHeader(te, h);
|
|
|
2ff057 |
headerFree(h);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
exit:
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpmteClose(rpmte te, int reset_fi)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (te == NULL || te->ts == NULL)
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
|
|
|
2ff057 |
switch (te->type) {
|
|
|
2ff057 |
case TR_ADDED:
|
|
|
2ff057 |
if (te->fd) {
|
|
|
2ff057 |
rpmtsNotify(te->ts, te, RPMCALLBACK_INST_CLOSE_FILE, 0, 0);
|
|
|
2ff057 |
te->fd = NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case TR_REMOVED:
|
|
|
2ff057 |
/* eventually we'll want notifications for erase open too */
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
rpmteSetHeader(te, NULL);
|
|
|
2ff057 |
if (reset_fi) {
|
|
|
2ff057 |
rpmteCleanFiles(te);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
FD_t rpmtePayload(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
FD_t payload = NULL;
|
|
|
2ff057 |
if (te->fd && te->h) {
|
|
|
2ff057 |
const char *compr = headerGetString(te->h, RPMTAG_PAYLOADCOMPRESSOR);
|
|
|
2ff057 |
char *ioflags = rstrscat(NULL, "r.", compr ? compr : "gzip", NULL);
|
|
|
2ff057 |
payload = Fdopen(fdDup(Fileno(te->fd)), ioflags);
|
|
|
2ff057 |
free(ioflags);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return payload;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpmteMarkFailed(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmtsi pi = rpmtsiInit(te->ts);
|
|
|
2ff057 |
rpmte p;
|
|
|
2ff057 |
|
|
|
2ff057 |
te->failed++;
|
|
|
2ff057 |
/* XXX we can do a much better here than this... */
|
|
|
2ff057 |
while ((p = rpmtsiNext(pi, TR_REMOVED))) {
|
|
|
2ff057 |
if (rpmteDependsOn(p) == te) {
|
|
|
2ff057 |
p->failed++;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
rpmtsiFree(pi);
|
|
|
2ff057 |
return te->failed;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmteFailed(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL) ? te->failed : -1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmteHaveTransScript(rpmte te, rpmTagVal tag)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
int rc = 0;
|
|
|
2ff057 |
if (tag == RPMTAG_PRETRANS) {
|
|
|
2ff057 |
rc = (te->transscripts & RPMTE_HAVE_PRETRANS);
|
|
|
2ff057 |
} else if (tag == RPMTAG_POSTTRANS) {
|
|
|
2ff057 |
rc = (te->transscripts & RPMTE_HAVE_POSTTRANS);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmps rpmteProblems(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (te != NULL) ? rpmpsLink(te->probs) : NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmteCleanProblems(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (te != NULL && te->probs != NULL) {
|
|
|
2ff057 |
te->probs = rpmpsFree(te->probs);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static void appendProblem(rpmte te, rpmProblemType type,
|
|
|
2ff057 |
fnpyKey key, const char * altNEVR,
|
|
|
2ff057 |
const char * str, uint64_t number)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmProblem o;
|
|
|
2ff057 |
rpmProblem p = rpmProblemCreate(type, te->NEVRA, key, altNEVR, str, number);
|
|
|
2ff057 |
rpmpsi psi = rpmpsInitIterator(te->probs);
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Only add new, unique problems to the set */
|
|
|
2ff057 |
while ((o = rpmpsiNext(psi))) {
|
|
|
2ff057 |
if (rpmProblemCompare(p, o) == 0)
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
rpmpsFreeIterator(psi);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (o == NULL) {
|
|
|
2ff057 |
if (te->probs == NULL)
|
|
|
2ff057 |
te->probs = rpmpsCreate();
|
|
|
2ff057 |
rpmpsAppendProblem(te->probs, p);
|
|
Panu Matilainen |
ec599b |
rpmteMarkFailed(te);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
rpmProblemFree(p);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmteAddProblem(rpmte te, rpmProblemType type,
|
|
|
2ff057 |
const char *altNEVR, const char *str, uint64_t number)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (te != NULL) {
|
|
|
2ff057 |
appendProblem(te, type, rpmteKey(te), altNEVR, str, number);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmteAddDepProblem(rpmte te, const char * altNEVR, rpmds ds,
|
|
|
2ff057 |
fnpyKey * suggestedKeys)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (te != NULL) {
|
|
|
2ff057 |
const char * DNEVR = rpmdsDNEVR(ds);
|
|
|
2ff057 |
rpmProblemType type;
|
|
|
2ff057 |
fnpyKey key = (suggestedKeys ? suggestedKeys[0] : NULL);
|
|
|
2ff057 |
|
|
|
2ff057 |
switch ((unsigned)DNEVR[0]) {
|
|
|
2ff057 |
case 'O': type = RPMPROB_OBSOLETES; break;
|
|
|
2ff057 |
case 'C': type = RPMPROB_CONFLICT; break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
case 'R': type = RPMPROB_REQUIRES; break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
appendProblem(te, type, key, altNEVR, DNEVR+2, rpmdsInstance(ds));
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmteAddRelocProblems(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (te && te->badrelocs) {
|
|
|
2ff057 |
for (int i = 0; i < te->nrelocs; i++) {
|
|
|
2ff057 |
if (te->badrelocs[i]) {
|
|
|
2ff057 |
rpmteAddProblem(te, RPMPROB_BADRELOCATE, NULL,
|
|
|
2ff057 |
te->relocs[i].oldPath, 0);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
const char * rpmteTypeString(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
switch (rpmteType(te)) {
|
|
|
2ff057 |
case TR_ADDED: return _("install");
|
|
|
2ff057 |
case TR_REMOVED: return _("erase");
|
|
|
2ff057 |
default: return "???";
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmfs rpmteGetFileStates(rpmte te)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return te->fs;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
Panu Matilainen |
d6b3d4 |
void rpmteSetVerified(rpmte te, int verified)
|
|
Panu Matilainen |
d6b3d4 |
{
|
|
Panu Matilainen |
d6b3d4 |
te->verified = verified;
|
|
Panu Matilainen |
d6b3d4 |
}
|
|
Panu Matilainen |
d6b3d4 |
|
|
Panu Matilainen |
d6b3d4 |
int rpmteGetVerified(rpmte te)
|
|
Panu Matilainen |
d6b3d4 |
{
|
|
Panu Matilainen |
d6b3d4 |
return te->verified;
|
|
Panu Matilainen |
d6b3d4 |
}
|
|
Panu Matilainen |
d6b3d4 |
|
|
|
2ff057 |
int rpmteProcess(rpmte te, pkgGoal goal, int num)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
/* Only install/erase resets pkg file info */
|
|
|
2ff057 |
int scriptstage = (goal != PKG_INSTALL && goal != PKG_ERASE);
|
|
|
2ff057 |
int test = (rpmtsFlags(te->ts) & RPMTRANS_FLAG_TEST);
|
|
|
2ff057 |
int reset_fi = (scriptstage == 0 && test == 0);
|
|
|
2ff057 |
int failed = 1;
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Dont bother opening for elements without pre/posttrans scripts */
|
|
|
2ff057 |
if (goal == PKG_PRETRANS || goal == PKG_POSTTRANS) {
|
|
|
2ff057 |
if (!rpmteHaveTransScript(te, goal)) {
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (rpmteOpen(te, reset_fi)) {
|
|
|
2ff057 |
if (!scriptstage) {
|
|
|
2ff057 |
rpmtsNotify(te->ts, te, RPMCALLBACK_ELEM_PROGRESS, num,
|
|
|
2ff057 |
rpmtsMembers(te->ts)->orderCount);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
failed = rpmpsmRun(te->ts, te, goal);
|
|
|
2ff057 |
rpmteClose(te, reset_fi);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (failed) {
|
|
|
2ff057 |
failed = rpmteMarkFailed(te);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
return failed;
|
|
|
2ff057 |
}
|