summaryrefslogtreecommitdiff
path: root/lib/rpmte.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rpmte.c')
-rw-r--r--lib/rpmte.c290
1 files changed, 42 insertions, 248 deletions
diff --git a/lib/rpmte.c b/lib/rpmte.c
index da6f48c5c..66194dc3b 100644
--- a/lib/rpmte.c
+++ b/lib/rpmte.c
@@ -13,6 +13,7 @@
#include <rpm/rpmdb.h>
#include <rpm/rpmlog.h>
+#include "lib/misc.h"
#include "lib/rpmplugins.h"
#include "lib/rpmte_internal.h"
/* strpool-related interfaces */
@@ -50,7 +51,8 @@ struct rpmte_s {
rpmds conflicts; /*!< Conflicts: dependencies. */
rpmds obsoletes; /*!< Obsoletes: dependencies. */
rpmds order; /*!< Order: dependencies. */
- rpmfi fi; /*!< File information. */
+ rpmfiles files; /*!< File information. */
+ rpmfi fi; /*!< File iterator (backwards compat) */
rpmps probs; /*!< Problems (relocations) */
rpmts ts; /*!< Parent transaction */
@@ -70,11 +72,6 @@ struct rpmte_s {
int failed; /*!< (parent) install/erase failed */
rpmfs fs;
-
- ARGV_t lastInCollectionsAny; /*!< list of collections this te is the last to be installed or removed */
- ARGV_t lastInCollectionsAdd; /*!< list of collections this te is the last to be only installed */
- ARGV_t firstInCollectionsRemove; /*!< list of collections this te is the first to be only removed */
- ARGV_t collections; /*!< list of collections */
};
/* forward declarations */
@@ -91,111 +88,26 @@ void rpmteCleanDS(rpmte te)
te->order = rpmdsFree(te->order);
}
-static rpmfi getFI(rpmte p, Header h)
+static rpmfiles getFiles(rpmte p, Header h)
{
rpmfiFlags fiflags;
fiflags = (p->type == TR_ADDED) ? (RPMFI_NOHEADER | RPMFI_FLAGS_INSTALL) :
(RPMFI_NOHEADER | RPMFI_FLAGS_ERASE);
/* relocate stuff in header if necessary */
- if (rpmteType(p) == TR_ADDED && rpmfsFC(p->fs) > 0 && p->nrelocs) {
- if (!headerIsSource(h) && !headerIsEntry(h, RPMTAG_ORIGBASENAMES)) {
- rpmRelocateFileList(p->relocs, p->nrelocs, p->fs, h);
- }
- }
- return rpmfiNewPool(rpmtsPool(p->ts), h, RPMTAG_BASENAMES, fiflags);
-}
-
-/* stupid bubble sort, but it's probably faster here */
-static void sortRelocs(rpmRelocation *relocations, int numRelocations)
-{
- for (int i = 0; i < numRelocations; i++) {
- int madeSwap = 0;
- for (int 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)
- continue;
- tmpReloc = relocations[j - 1];
- relocations[j - 1] = relocations[j];
- relocations[j] = tmpReloc;
- madeSwap = 1;
- }
- if (!madeSwap) break;
- }
-}
-
-static char * stripTrailingChar(char * s, char c)
-{
- char * t;
- for (t = s + strlen(s) - 1; *t == c && t >= s; t--)
- *t = '\0';
- return s;
-}
-
-static void buildRelocs(rpmte p, Header h, rpmRelocation *relocs)
-{
- int i;
- struct rpmtd_s validRelocs;
-
- for (rpmRelocation *r = relocs; r->oldPath || r->newPath; r++)
- p->nrelocs++;
-
- headerGet(h, RPMTAG_PREFIXES, &validRelocs, HEADERGET_MINMEM);
- p->relocs = xmalloc(sizeof(*p->relocs) * (p->nrelocs+1));
-
- /* Build sorted relocation list from raw relocations. */
- for (i = 0; i < p->nrelocs; i++) {
- char * t;
-
- /*
- * Default relocations (oldPath == NULL) are handled in the UI,
- * not rpmlib.
- */
- if (relocs[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 = xstrdup(relocs[i].oldPath);
- p->relocs[i].oldPath = (t[0] == '/' && t[1] == '\0')
- ? t
- : stripTrailingChar(t, '/');
-
- /* An old path w/o a new path is valid, and indicates exclusion */
- if (relocs[i].newPath) {
- int valid = 0;
- const char *validprefix;
-
- t = xstrdup(relocs[i].newPath);
- p->relocs[i].newPath = (t[0] == '/' && t[1] == '\0')
- ? t
- : stripTrailingChar(t, '/');
-
- /* FIX: relocations[i].oldPath == NULL */
- /* Verify that the relocation's old path is in the header. */
- rpmtdInit(&validRelocs);
- while ((validprefix = rpmtdNextString(&validRelocs))) {
- if (rstreq(validprefix, p->relocs[i].oldPath)) {
- valid = 1;
- break;
+ if (rpmteType(p) == TR_ADDED && rpmfsFC(p->fs) > 0) {
+ if (!headerIsEntry(h, RPMTAG_ORIGBASENAMES)) {
+ if (rpmteIsSource(p)) {
+ /* Unlike binary packages, source relocation can fail */
+ if (rpmRelocateSrpmFileList(h, rpmtsRootDir(p->ts)) < 0) {
+ return NULL;
}
+ } else {
+ rpmRelocateFileList(p->relocs, p->nrelocs, p->fs, h);
}
-
- if (!valid) {
- if (p->badrelocs == NULL)
- p->badrelocs = xcalloc(p->nrelocs, sizeof(*p->badrelocs));
- p->badrelocs[i] = 1;
- }
- } else {
- p->relocs[i].newPath = NULL;
}
}
- p->relocs[i].oldPath = NULL;
- p->relocs[i].newPath = NULL;
- sortRelocs(p->relocs, p->nrelocs);
-
- rpmtdFreeData(&validRelocs);
+ return rpmfilesNew(rpmtsPool(p->ts), h, RPMTAG_BASENAMES, fiflags);
}
/**
@@ -208,7 +120,7 @@ static void buildRelocs(rpmte p, Header h, rpmRelocation *relocs)
static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs)
{
rpmstrPool tspool = rpmtsPool(p->ts);
- struct rpmtd_s colls, bnames;
+ struct rpmtd_s bnames;
int rc = 1; /* assume failure */
p->name = headerGetAsString(h, RPMTAG_NAME);
@@ -237,7 +149,7 @@ static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs)
p->relocs = NULL;
p->badrelocs = NULL;
if (relocs != NULL)
- buildRelocs(p, h, relocs);
+ rpmRelocationBuild(h, relocs, &p->nrelocs, &p->relocs, &p->badrelocs);
p->db_instance = headerGetInstance(h);
p->key = key;
@@ -258,10 +170,10 @@ static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs)
p->fs = rpmfsNew(rpmtdCount(&bnames), (p->type == TR_ADDED));
rpmtdFreeData(&bnames);
- p->fi = getFI(p, h);
+ p->files = getFiles(p, h);
/* Packages with no files return an empty file info set, NULL is an error */
- if (p->fi == NULL)
+ if (p->files == NULL)
goto exit;
/* See if we have pre/posttrans scripts. */
@@ -272,19 +184,6 @@ static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs)
headerIsEntry(h, RPMTAG_POSTTRANSPROG)) ?
RPMTE_HAVE_POSTTRANS : 0;
- p->lastInCollectionsAny = NULL;
- p->lastInCollectionsAdd = NULL;
- p->firstInCollectionsRemove = NULL;
- p->collections = NULL;
- if (headerGet(h, RPMTAG_COLLECTIONS, &colls, HEADERGET_MINMEM)) {
- const char *collname;
- while ((collname = rpmtdNextString(&colls))) {
- argvAdd(&p->collections, collname);
- }
- argvSort(p->collections, NULL);
- rpmtdFreeData(&colls);
- }
-
rpmteColorDS(p, RPMTAG_PROVIDENAME);
rpmteColorDS(p, RPMTAG_REQUIRENAME);
@@ -320,16 +219,12 @@ rpmte rpmteFree(rpmte te)
fdFree(te->fd);
rpmfiFree(te->fi);
+ rpmfilesFree(te->files);
headerFree(te->h);
rpmfsFree(te->fs);
rpmpsFree(te->probs);
rpmteCleanDS(te);
- argvFree(te->collections);
- argvFree(te->lastInCollectionsAny);
- argvFree(te->lastInCollectionsAdd);
- argvFree(te->firstInCollectionsRemove);
-
memset(te, 0, sizeof(*te)); /* XXX trash and burn */
free(te);
}
@@ -433,46 +328,6 @@ rpm_color_t rpmteSetColor(rpmte te, rpm_color_t color)
return ocolor;
}
-ARGV_const_t rpmteCollections(rpmte te)
-{
- return (te != NULL) ? te->collections : NULL;
-}
-
-int rpmteHasCollection(rpmte te, const char *collname)
-{
- return (argvSearch(rpmteCollections(te), collname, NULL) != NULL);
-}
-
-int rpmteAddToLastInCollectionAdd(rpmte te, const char *collname)
-{
- if (te != NULL) {
- argvAdd(&te->lastInCollectionsAdd, collname);
- argvSort(te->lastInCollectionsAdd, NULL);
- return 0;
- }
- return -1;
-}
-
-int rpmteAddToLastInCollectionAny(rpmte te, const char *collname)
-{
- if (te != NULL) {
- argvAdd(&te->lastInCollectionsAny, collname);
- argvSort(te->lastInCollectionsAny, NULL);
- return 0;
- }
- return -1;
-}
-
-int rpmteAddToFirstInCollectionRemove(rpmte te, const char *collname)
-{
- if (te != NULL) {
- argvAdd(&te->firstInCollectionsRemove, collname);
- argvSort(te->firstInCollectionsRemove, NULL);
- return 0;
- }
- return -1;
-}
-
rpm_loff_t rpmtePkgFileSize(rpmte te)
{
return (te != NULL ? te->pkgFileSize : 0);
@@ -571,14 +426,12 @@ rpmds rpmteDS(rpmte te, rpmTagVal tag)
return NULL;
}
-rpmfi rpmteSetFI(rpmte te, rpmfi fi)
+void rpmteCleanFiles(rpmte te)
{
if (te != NULL) {
te->fi = rpmfiFree(te->fi);
- if (fi != NULL)
- te->fi = rpmfiLink(fi);
+ te->files = rpmfilesFree(te->files);
}
- return NULL;
}
rpmfi rpmteFI(rpmte te)
@@ -586,12 +439,20 @@ rpmfi rpmteFI(rpmte te)
if (te == NULL)
return NULL;
+ if (te->fi == NULL)
+ te->fi = rpmfilesIter(te->files, RPMFI_ITER_FWD);
+
return te->fi; /* XXX take fi reference here? */
}
+rpmfiles rpmteFiles(rpmte te)
+{
+ return (te != NULL) ? rpmfilesLink(te->files) : NULL;
+}
+
static void rpmteColorDS(rpmte te, rpmTag tag)
{
- rpmfi fi = rpmteFI(te);
+ rpmfi fi;
rpmds ds = rpmteDS(te, tag);
char deptype = 'R';
char mydt;
@@ -602,7 +463,7 @@ static void rpmteColorDS(rpmte te, rpmTag tag)
unsigned ix;
int ndx, i;
- if (!(te && (Count = rpmdsCount(ds)) > 0 && rpmfiFC(fi) > 0))
+ if (!(te && (Count = rpmdsCount(ds)) > 0 && rpmfilesFC(te->files) > 0))
return;
switch (tag) {
@@ -620,8 +481,7 @@ static void rpmteColorDS(rpmte te, rpmTag tag)
colors = xcalloc(Count, sizeof(*colors));
/* Calculate dependency color. */
- fi = rpmfiInit(fi, 0);
- if (fi != NULL)
+ fi = rpmfilesIter(te->files, RPMFI_ITER_FWD);
while (rpmfiNext(fi) >= 0) {
val = rpmfiFColor(fi);
ddict = NULL;
@@ -646,6 +506,7 @@ assert (ix < Count);
(void) rpmdsSetColor(ds, val);
}
free(colors);
+ rpmfiFree(fi);
}
static Header rpmteDBHeader(rpmte te)
@@ -707,8 +568,8 @@ static int rpmteOpen(rpmte te, int reload_fi)
if (h != NULL) {
if (reload_fi) {
/* This can fail if we get a different, bad header from callback */
- te->fi = getFI(te, h);
- rc = (te->fi != NULL);
+ te->files = getFiles(te, h);
+ rc = (te->files != NULL);
} else {
rc = 1;
}
@@ -739,7 +600,7 @@ static int rpmteClose(rpmte te, int reset_fi)
}
rpmteSetHeader(te, NULL);
if (reset_fi) {
- rpmteSetFI(te, NULL);
+ rpmteCleanFiles(te);
}
return 1;
}
@@ -864,7 +725,7 @@ void rpmteAddRelocProblems(rpmte te)
const char * rpmteTypeString(rpmte te)
{
- switch(rpmteType(te)) {
+ switch (rpmteType(te)) {
case TR_ADDED: return _("install");
case TR_REMOVED: return _("erase");
default: return "???";
@@ -876,70 +737,7 @@ rpmfs rpmteGetFileStates(rpmte te)
return te->fs;
}
-rpmRC rpmteSetupCollectionPlugins(rpmte te)
-{
- ARGV_const_t colls = rpmteCollections(te);
- rpmPlugins plugins = rpmtsPlugins(te->ts);
- rpmRC rc = RPMRC_OK;
-
- if (!colls) {
- return rc;
- }
-
- rpmteOpen(te, 0);
- for (; colls && *colls; colls++) {
- if (!rpmpluginsPluginAdded(plugins, *colls)) {
- rc = rpmpluginsAddPlugin(plugins, "collection", *colls);
- if (rc != RPMRC_OK) {
- break;
- }
- }
- rc = rpmpluginsCallOpenTE(plugins, *colls, te);
- if (rc != RPMRC_OK) {
- break;
- }
- }
- rpmteClose(te, 0);
-
- return rc;
-}
-
-static rpmRC rpmteRunAllCollections(rpmte te, rpmPluginHook hook)
-{
- ARGV_const_t colls;
- rpmRC(*collHook) (rpmPlugins, const char *);
- rpmRC rc = RPMRC_OK;
-
- if (rpmtsFlags(te->ts) & RPMTRANS_FLAG_NOCOLLECTIONS) {
- goto exit;
- }
-
- switch (hook) {
- case PLUGINHOOK_COLL_POST_ADD:
- colls = te->lastInCollectionsAdd;
- collHook = rpmpluginsCallCollectionPostAdd;
- break;
- case PLUGINHOOK_COLL_POST_ANY:
- colls = te->lastInCollectionsAny;
- collHook = rpmpluginsCallCollectionPostAny;
- break;
- case PLUGINHOOK_COLL_PRE_REMOVE:
- colls = te->firstInCollectionsRemove;
- collHook = rpmpluginsCallCollectionPreRemove;
- break;
- default:
- goto exit;
- }
-
- for (; colls && *colls; colls++) {
- rc = collHook(rpmtsPlugins(te->ts), *colls);
- }
-
- exit:
- return rc;
-}
-
-int rpmteProcess(rpmte te, pkgGoal goal)
+int rpmteProcess(rpmte te, pkgGoal goal, int num)
{
/* Only install/erase resets pkg file info */
int scriptstage = (goal != PKG_INSTALL && goal != PKG_ERASE);
@@ -954,20 +752,16 @@ int rpmteProcess(rpmte te, pkgGoal goal)
}
}
- if (!scriptstage) {
- rpmteRunAllCollections(te, PLUGINHOOK_COLL_PRE_REMOVE);
- }
-
if (rpmteOpen(te, reset_fi)) {
+ if (!scriptstage) {
+ rpmtsNotify(te->ts, te, RPMCALLBACK_ELEM_PROGRESS, num,
+ rpmtsMembers(te->ts)->orderCount);
+ }
+
failed = rpmpsmRun(te->ts, te, goal);
rpmteClose(te, reset_fi);
}
- if (!scriptstage) {
- rpmteRunAllCollections(te, PLUGINHOOK_COLL_POST_ADD);
- rpmteRunAllCollections(te, PLUGINHOOK_COLL_POST_ANY);
- }
-
if (failed) {
failed = rpmteMarkFailed(te);
}