Reorganize sources before implementing --repackage.

CVS patchset: 4543
CVS date: 2001/02/10 16:47:40
This commit is contained in:
jbj 2001-02-10 16:47:40 +00:00
parent d304bac9be
commit eccb6f66fc
21 changed files with 3680 additions and 3208 deletions

View File

@ -286,12 +286,12 @@ INPUT = \
./lib/fprint.c \
./lib/fprint.h \
./lib/fs.c \
./lib/fsm.c \
./lib/fsm.h \
./lib/hash.c \
./lib/hash.h \
./lib/header.c \
./lib/header.h \
./lib/install.c \
./lib/install.h \
./lib/md5.c \
./lib/md5.h \
./lib/md5sum.c \
@ -301,8 +301,9 @@ INPUT = \
./lib/poptBT.c \
./lib/poptQV.c \
./lib/problems.c \
./lib/psm.c \
./lib/psm.h \
./lib/query.c \
./lib/rollback.c \
./lib/rpmchecksig.c \
./lib/rpmdb.c \
./lib/rpmdb.h \
@ -320,7 +321,6 @@ INPUT = \
./lib/tagName.c \
./lib/tagtable.c \
./lib/transaction.c \
./lib/uninstall.c \
./lib/verify.c \
./rpmio/base64.c \
./rpmio/base64.h \

View File

@ -4,7 +4,6 @@
#include <rpmurl.h>
#include "build.h"
#include "install.h"
#include "debug.h"
static int checkSpec(Header h)

View File

@ -6,7 +6,7 @@
* XXX this information will move elsewhere eventually
*/
#include "rollback.h"
#include "psm.h"
/**
*/

View File

@ -11,8 +11,8 @@ pkgincdir = $(pkgincludedir)
pkginc_HEADERS = \
header.h misc.h rpmlib.h stringbuf.h
noinst_HEADERS = \
cpio.h depends.h falloc.h fprint.h hash.h install.h \
md5.h rollback.h \
cpio.h depends.h falloc.h fprint.h fsm.h hash.h \
md5.h psm.h \
rpmdb.h rpmlead.h signature.h
mylibpaths = -L$(top_builddir)/lib/.libs -L$(top_builddir)/rpmio/.libs \
@ -23,12 +23,12 @@ LIBS =
lib_LTLIBRARIES = librpm.la
librpm_la_SOURCES = \
cpio.c $(DBLIBSRCS) depends.c \
formats.c fprint.c fs.c hash.c header.c install.c \
formats.c fprint.c fs.c fsm.c hash.c header.c \
md5.c md5sum.c misc.c package.c problems.c \
poptBT.c poptQV.c query.c rollback.c \
poptBT.c poptQV.c psm.c query.c \
rpmchecksig.c rpmdb.c rpminstall.c \
rpmlead.c rpmlibprov.c rpmrc.c scriptlet.c signature.c stringbuf.c \
tagName.c tagtable.c transaction.c uninstall.c verify.c
tagName.c tagtable.c transaction.c verify.c
librpm_la_LDFLAGS = @libdb3@ @libdb2@ @libdb1@
librpm_la_LIBADD = $(DBLIBOBJS)
librpm_la_DEPENDENCIES = $(DBLIBOBJS)

1895
lib/cpio.c

File diff suppressed because it is too large Load Diff

1905
lib/fsm.c Normal file

File diff suppressed because it is too large Load Diff

255
lib/fsm.h Normal file
View File

@ -0,0 +1,255 @@
#ifndef H_FSM
#define H_FSM
/** \file lib/fsm.h
*/
#include <rpmlib.h>
#include "cpio.h"
/**
*/
#define FSM_VERBOSE 0x8000
#define FSM_INTERNAL 0x4000
#define FSM_SYSCALL 0x2000
#define FSM_DEAD 0x1000
#define _fv(_a) ((_a) | FSM_VERBOSE)
#define _fi(_a) ((_a) | FSM_INTERNAL)
#define _fs(_a) ((_a) | (FSM_INTERNAL | FSM_SYSCALL))
#define _fd(_a) ((_a) | (FSM_INTERNAL | FSM_DEAD))
typedef enum fileStage_e {
FSM_UNKNOWN = 0,
FSM_INIT = _fd(1),
FSM_PRE = _fd(2),
FSM_PROCESS = _fv(3),
FSM_POST = _fd(4),
FSM_UNDO = 5,
FSM_FINI = 6,
FSM_PKGINSTALL = _fd(7),
FSM_PKGERASE = _fd(8),
FSM_PKGBUILD = _fd(9),
FSM_PKGCOMMIT = _fd(10),
FSM_PKGUNDO = _fd(11),
FSM_CREATE = _fd(17),
FSM_MAP = _fd(18),
FSM_MKDIRS = _fi(19),
FSM_RMDIRS = _fi(20),
FSM_MKLINKS = _fi(21),
FSM_NOTIFY = _fd(22),
FSM_DESTROY = _fd(23),
FSM_VERIFY = _fd(24),
FSM_COMMIT = _fd(25),
FSM_UNLINK = _fs(33),
FSM_RENAME = _fs(34),
FSM_MKDIR = _fs(35),
FSM_RMDIR = _fs(36),
FSM_CHOWN = _fs(37),
FSM_LCHOWN = _fs(38),
FSM_CHMOD = _fs(39),
FSM_UTIME = _fs(40),
FSM_SYMLINK = _fs(41),
FSM_LINK = _fs(42),
FSM_MKFIFO = _fs(43),
FSM_MKNOD = _fs(44),
FSM_LSTAT = _fs(45),
FSM_STAT = _fs(46),
FSM_READLINK= _fs(47),
FSM_CHROOT = _fs(48),
FSM_NEXT = _fd(65),
FSM_EAT = _fd(66),
FSM_POS = _fd(67),
FSM_PAD = _fd(68),
FSM_TRAILER = _fd(69),
FSM_HREAD = _fd(70),
FSM_HWRITE = _fd(71),
FSM_DREAD = _fs(72),
FSM_DWRITE = _fs(73),
FSM_ROPEN = _fs(129),
FSM_READ = _fs(130),
FSM_RCLOSE = _fs(131),
FSM_WOPEN = _fs(132),
FSM_WRITE = _fs(133),
FSM_WCLOSE = _fs(134),
} fileStage;
#undef _fv
#undef _fi
#undef _fs
#undef _fd
/** \ingroup payload
* Keeps track of the set of all hard links to a file in an archive.
*/
struct hardLink {
/*@owned@*/ struct hardLink * next;
/*@owned@*/ const char ** nsuffix;
/*@owned@*/ int * filex;
dev_t dev;
ino_t inode;
int nlink;
int linksLeft;
int linkIndex;
int createdPath;
};
/** \ingroup payload
* Iterator across package file info, forward on install, backward on erase.
*/
struct fsmIterator_s {
/*@kept@*/ rpmTransactionSet ts; /*!< transaction set. */
/*@kept@*/ TFI_t fi; /*!< transaction element file info. */
int isave; /*!< last returned iterator index. */
int i; /*!< iterator index. */
};
/** \ingroup payload
* File name and stat information.
*/
struct fsm_s {
/*@owned@*/ const char * path; /*!< Current file name. */
/*@owned@*/ const char * opath; /*!< Original file name. */
FD_t cfd; /*!< Payload file handle. */
FD_t rfd; /*!< read: File handle. */
/*@dependent@*/ char * rdbuf; /*!< read: Buffer. */
/*@owned@*/ char * rdb; /*!< read: Buffer allocated. */
size_t rdsize; /*!< read: Buffer allocated size. */
size_t rdlen; /*!< read: Number of bytes requested. */
size_t rdnb; /*!< read: Number of bytes returned. */
FD_t wfd; /*!< write: File handle. */
/*@dependent@*/ char * wrbuf; /*!< write: Buffer. */
/*@owned@*/ char * wrb; /*!< write: Buffer allocated. */
size_t wrsize; /*!< write: Buffer allocated size. */
size_t wrlen; /*!< write: Number of bytes requested. */
size_t wrnb; /*!< write: Number of bytes returned. */
/*@only@*/ FSMI_t iter; /*!< File iterator. */
int ix; /*!< Current file iterator index. */
/*@only@*/ struct hardLink * links; /*!< Pending hard linked file(s). */
/*@only@*/ struct hardLink * li; /*!< Current hard linked file(s). */
/*@kept@*/ unsigned int * archiveSize; /*!< Pointer to archive size. */
/*@kept@*/ const char ** failedFile; /*!< First file name that failed. */
/*@shared@*/ const char * subdir; /*!< Current file sub-directory. */
char subbuf[64]; /* XXX eliminate */
/*@observer@*/ const char * osuffix; /*!< Old, preserved, file suffix. */
/*@observer@*/ const char * nsuffix; /*!< New, created, file suffix. */
/*@shared@*/ const char * suffix; /*!< Current file suffix. */
char sufbuf[64]; /* XXX eliminate */
/*@only@*/ short * dnlx; /*!< Last dirpath verified indexes. */
/*@only@*/ char * ldn; /*!< Last dirpath verified. */
int ldnlen; /*!< Last dirpath current length. */
int ldnalloc; /*!< Last dirpath allocated length. */
int postpone; /*!< Skip remaining stages? */
int diskchecked; /*!< Has stat(2) been performed? */
int exists; /*!< Does current file exist on disk? */
int mkdirsdone; /*!< Have "orphan" dirs been created? */
int astriplen; /*!< Length of buildroot prefix. */
int rc; /*!< External file stage return code. */
int commit; /*!< Commit synchronously? */
cpioMapFlags mapFlags; /*!< Bit(s) to control mapping. */
/*@shared@*/ const char * archivePath; /*!< Path to store in cpio archive. */
/*@shared@*/ const char * dirName; /*!< File directory name. */
/*@shared@*/ const char * baseName; /*!< File base name. */
/*@shared@*/ const char * fmd5sum; /*!< File MD5 sum (NULL disables). */
unsigned fflags; /*!< File flags. */
fileAction action; /*!< File disposition. */
fileStage goal; /*!< Package state machine goal. */
fileStage stage; /*!< External file stage. */
struct stat sb; /*!< Current file stat(2) info. */
struct stat osb; /*!< Original file stat(2) info. */
};
#ifdef __cplusplus
extern "C" {
#endif
/**
* Return formatted string representation of file stages.
* @param a file stage
* @return formatted string
*/
/*@observer@*/ const char *const fileStageString(fileStage a);
/**
* Create file state machine instance.
* @return file state machine data
*/
/*@only@*/ /*@null@*/ FSM_t newFSM(void);
/**
* Destroy file state machine instance.
* @param fsm file state machine data
* @return always NULL
*/
/*@null@*/ FSM_t freeFSM(/*@only@*/ /*@null@*/ FSM_t fsm);
/**
* Load external data into file state machine.
* @param fsm file state machine data
* @param goal
* @param ts transaction set
* @param fi transaction element file info
* @param archiveSize pointer to archive size
* @param failedFile pointer to first file name that failed.
* @return 0 on success
*/
int fsmSetup(FSM_t fsm, fileStage goal,
/*@kept@*/ const rpmTransactionSet ts,
/*@kept@*/ const TFI_t fi,
FD_t cfd,
/*@out@*/ unsigned int * archiveSize,
/*@out@*/ const char ** failedFile)
/*@modifies fsm, *archiveSize, *failedFile @*/;
/**
* Clean file state machine.
* @param fsm file state machine data
* @return 0 on success
*/
int fsmTeardown(FSM_t fsm)
/*@modifies fsm @*/;
/**
* Retrieve transaction set from file state machine iterator.
* @param fsm file state machine data
* @return transaction set
*/
/*@kept@*/ rpmTransactionSet fsmGetTs(const FSM_t fsm) /*@*/;
/**
* Retrieve transaction element file info from file state machine iterator.
* @param fsm file state machine data
* @return transaction element file info
*/
/*@kept@*/ TFI_t fsmGetFi(const FSM_t fsm) /*@*/;
/**
* Map next file path and action.
* @param fsm file state machine data
*/
int fsmMapPath(FSM_t fsm)
/*@modifies fsm @*/;
/**
* Map file stat(2) info.
* @param fsm file state machine data
*/
int fsmMapAttrs(FSM_t fsm)
/*@modifies fsm @*/;
/**
* File state machine driver.
* @param fsm file state machine data
* @param stage next stage
* @return 0 on success
*/
int fsmStage(FSM_t fsm, fileStage stage)
/*@modifies fsm @*/;
#ifdef __cplusplus
}
#endif
#endif /* H_FSM */

View File

@ -1,5 +1,5 @@
/** \ingroup rpmtrans payload
* \file lib/install.c
* \file lib/psm.c
*/
#include "system.h"
@ -8,12 +8,276 @@
#include <rpmmacro.h>
#include <rpmurl.h>
#include "rollback.h"
#include "psm.h"
#include "misc.h"
#include "debug.h"
/*@access Header @*/ /* XXX compared with NULL */
/*@access rpmTransactionSet @*/ /* XXX compared with NULL */
/*@access Header @*/ /* compared with NULL */
/*@access rpmTransactionSet @*/ /* compared with NULL */
/*@access TFI_t @*/ /* compared with NULL */
extern int _fsm_debug;
/**
* Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
* @param this memory to free
* @retval NULL always
*/
static /*@null@*/ void * _free(/*@only@*/ /*@null@*/ const void * this) {
if (this) free((void *)this);
return NULL;
}
void loadFi(Header h, TFI_t fi)
{
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) */
hge = (fi->type == TR_ADDED)
? (HGE_t) headerGetEntryMinMemory : (HGE_t) headerGetEntry;
fi->hge = hge;
fi->hfd = hfd = headerFreeData;
if (h && fi->h == NULL) fi->h = headerLink(h);
/* Duplicate name-version-release so that headers can be free'd. */
hge(fi->h, RPMTAG_NAME, NULL, (void **) &fi->name, NULL);
fi->name = xstrdup(fi->name);
hge(fi->h, RPMTAG_VERSION, NULL, (void **) &fi->version, NULL);
fi->version = xstrdup(fi->version);
hge(fi->h, RPMTAG_RELEASE, NULL, (void **) &fi->release, NULL);
fi->release = xstrdup(fi->release);
/* -1 means not found */
rc = hge(fi->h, RPMTAG_EPOCH, NULL, (void **) &uip, NULL);
fi->epoch = (rc ? *uip : -1);
/* 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;
}
hge(fi->h, RPMTAG_DIRINDEXES, NULL, (void **) &fi->dil, NULL);
hge(fi->h, RPMTAG_DIRNAMES, NULL, (void **) &fi->dnl, &fi->dc);
hge(fi->h, RPMTAG_FILEMODES, NULL, (void **) &fi->fmodes, NULL);
hge(fi->h, RPMTAG_FILEFLAGS, NULL, (void **) &fi->fflags, NULL);
hge(fi->h, RPMTAG_FILESIZES, NULL, (void **) &fi->fsizes, NULL);
hge(fi->h, RPMTAG_FILESTATES, NULL, (void **) &fi->fstates, NULL);
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:
fi->mapflags = CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
hge(fi->h, RPMTAG_FILEMD5S, NULL, (void **) &fi->fmd5s, NULL);
hge(fi->h, RPMTAG_FILELINKTOS, NULL, (void **) &fi->flinks, NULL);
hge(fi->h, RPMTAG_FILELANGS, NULL, (void **) &fi->flangs, NULL);
hge(fi->h, RPMTAG_FILEMTIMES, NULL, (void **) &fi->fmtimes, NULL);
/* 0 makes for noops */
fi->replacedSizes = xcalloc(fi->fc, sizeof(*fi->replacedSizes));
break;
case TR_REMOVED:
fi->mapflags = CPIO_MAP_PATH;
hge(fi->h, RPMTAG_FILEMD5S, NULL, (void **) &fi->fmd5s, NULL);
hge(fi->h, RPMTAG_FILELINKTOS, NULL, (void **) &fi->flinks, NULL);
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));
headerFree(fi->h);
fi->h = NULL;
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:
break;
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;
}
if (fi->h) {
headerFree(fi->h); fi->h = NULL;
}
}
/*@observer@*/ const char *const fiTypeString(TFI_t fi) {
switch(fi->type) {
case TR_ADDED: return " install";
case TR_REMOVED: return " erase";
default: return "???";
}
/*@noteached@*/
}
/*@obserever@*/ const char *const fileActionString(fileAction a)
{
switch (a) {
case FA_UNKNOWN: return "unknown";
case FA_CREATE: return "create";
case FA_BACKUP: return "backup";
case FA_SAVE: return "save";
case FA_SKIP: return "skip";
case FA_ALTNAME: return "altname";
case FA_ERASE: return "erase";
case FA_SKIPNSTATE: return "skipnstate";
case FA_SKIPNETSHARED: return "skipnetshared";
case FA_SKIPMULTILIB: return "skipmultilib";
default: return "???";
}
/*@notreached@*/
}
#ifdef DYING
/**
*/
struct pkgIterator {
/*@dependent@*/ /*@kept@*/ TFI_t fi;
int i;
};
/**
*/
static /*@null@*/ void * pkgFreeIterator(/*@only@*/ /*@null@*/ void * this) {
return _free(this);
}
/**
*/
static /*@only@*/ void * pkgInitIterator(/*@kept@*/ rpmTransactionSet ts,
/*@kept@*/ TFI_t fi)
{
struct pkgIterator * pi = NULL;
if (ts && fi) {
pi = xcalloc(sizeof(*pi), 1);
pi->fi = fi;
switch (fi->type) {
case TR_ADDED: pi->i = 0; break;
case TR_REMOVED: pi->i = fi->fc; break;
}
}
return pi;
}
/**
*/
static int pkgNextIterator(/*@null@*/ void * this) {
struct pkgIterator * pi = this;
int i = -1;
if (pi) {
TFI_t fi = pi->fi;
switch (fi->type) {
case TR_ADDED:
if (pi->i < fi->fc)
i = pi->i++;
break;
case TR_REMOVED:
if (pi->i >= 0)
i = --pi->i;
break;
}
}
return i;
}
int pkgActions(const rpmTransactionSet ts, TFI_t fi, fileStage a)
{
int rc = 0;
if (fi->actions) {
void * pi = pkgInitIterator(ts, fi);
int i;
while ((i = pkgNextIterator(pi)) != -1) {
if (pkgAction(ts, fi, i, a))
rc++;
}
pi = pkgFreeIterator(pi);
}
return rc;
}
#endif
/**
* Macros to be defined from per-header tag values.
@ -911,3 +1175,103 @@ exit:
headerFree(oldH);
return ec;
}
int removeBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
{
/*@observer@*/ static char * stepName = " erase";
Header h;
int chrootDone = 0;
const char * failedFile = NULL;
const void * pkgKey = NULL;
int rc = 0;
rpmMessage(RPMMESS_DEBUG, _("%s: %s-%s-%s has %d files, test = %d\n"),
stepName, fi->name, fi->version, fi->release,
fi->fc, (ts->transFlags & RPMTRANS_FLAG_TEST));
/*
* 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.
*/
fi->scriptArg = rpmdbCountPackages(ts->rpmdb, fi->name) - 1;
if (fi->scriptArg < 0)
return 1;
{ rpmdbMatchIterator mi = NULL;
mi = rpmdbInitIterator(ts->rpmdb, RPMDBI_PACKAGES,
&fi->record, sizeof(fi->record));
h = rpmdbNextIterator(mi);
if (h == NULL) {
rpmdbFreeIterator(mi);
return 2;
}
h = headerLink(h);
rpmdbFreeIterator(mi);
}
if (ts->rootDir && !ts->chrootDone) {
chdir("/");
/*@-unrecog@*/ chroot(ts->rootDir); /*@=unrecog@*/
chrootDone = ts->chrootDone = 1;
}
if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERS)) {
/* run triggers from this package which are keyed on installed
packages */
if (runImmedTriggers(ts, RPMSENSE_TRIGGERUN, h, -1))
return 2;
/* run triggers which are set off by the removal of this package */
if (runTriggers(ts, RPMSENSE_TRIGGERUN, h, -1))
return 1;
}
rpmMessage(RPMMESS_DEBUG, _("%s: running %s script(s) (if any)\n"),
stepName, "pre-erase");
rc = runInstScript(ts, h, RPMTAG_PREUN, RPMTAG_PREUNPROG, fi->scriptArg,
(ts->transFlags & RPMTRANS_FLAG_NOSCRIPTS));
if (rc)
return 1;
if (fi->fc > 0 && !(ts->transFlags & RPMTRANS_FLAG_JUSTDB)) {
if (ts->notify)
(void)ts->notify(h, RPMCALLBACK_UNINST_START, fi->fc, fi->fc,
pkgKey, ts->notifyData);
rc = fsmSetup(fi->fsm, FSM_PKGERASE, ts, fi, NULL, NULL, &failedFile);
(void) fsmTeardown(fi->fsm);
if (ts->notify)
(void)ts->notify(h, RPMCALLBACK_UNINST_STOP, 0, fi->fc,
pkgKey, ts->notifyData);
}
rpmMessage(RPMMESS_DEBUG, _("%s: running %s script(s) (if any)\n"),
stepName, "post-erase");
rc = runInstScript(ts, h, RPMTAG_POSTUN, RPMTAG_POSTUNPROG,
fi->scriptArg, (ts->transFlags & RPMTRANS_FLAG_NOSCRIPTS));
/* XXX postun failures are not cause for erasure failure. */
if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERS)) {
/* Run postun triggers which are set off by this package's removal. */
rc = runTriggers(ts, RPMSENSE_TRIGGERPOSTUN, h, -1);
if (rc)
return 2;
}
if (ts->rootDir && chrootDone) {
/*@-unrecog@*/ chroot("."); /*@=unrecog@*/
chrootDone = ts->chrootDone = 0;
chdir(ts->currDir);
}
if (!(ts->transFlags & RPMTRANS_FLAG_TEST))
rpmdbRemove(ts->rpmdb, ts->id, fi->record);
return 0;
}

152
lib/psm.h Normal file
View File

@ -0,0 +1,152 @@
#ifndef H_PSM
#define H_PSM
/** \file lib/psm.h
*/
#include <rpmlib.h>
#include "depends.h"
#include "scriptlet.h"
#include "fsm.h"
/**
*/
typedef enum rollbackDir_e {
ROLLBACK_SAVE = 1, /*!< Save files. */
ROLLBACK_RESTORE = 2, /*!< Restore files. */
} rollbackDir;
/**
*/
struct sharedFile {
int mainFileNumber;
int secRecOffset;
int secFileNumber;
} ;
/**
*/
struct sharedFileInfo {
int pkgFileNum;
int otherFileNum;
int otherPkg;
int isRemoved;
};
/**
*/
struct transactionFileInfo_s {
/* for all packages */
enum rpmTransactionType type;
fileAction action; /*!< File disposition default. */
/*@owned@*/ fileAction * actions; /*!< File disposition(s) */
/*@owned@*/ struct fingerPrint_s * fps; /*!< File fingerprint(s) */
HGE_t hge; /*!< Vector to headerGetEntry() */
HFD_t hfd; /*!< Vector to headerFreeData() */
Header h; /*!< Package header */
/*@owned@*/ const char * name;
/*@owned@*/ const char * version;
/*@owned@*/ const char * release;
int_32 epoch;
uint_32 flags; /*!< File flag default. */
const uint_32 * fflags; /*!< File flag(s) (from header) */
const uint_32 * fsizes; /*!< File size(s) (from header) */
const uint_32 * fmtimes; /*!< File modification time(s) (from header) */
/*@owned@*/ const char ** bnl; /*!< Base name(s) (from header) */
/*@owned@*/ const char ** dnl; /*!< Directory name(s) (from header) */
int_32 * dil; /*!< Directory indice(s) (from header) */
/*@owned@*/ const char ** obnl; /*!< Original base name(s) (from header) */
/*@owned@*/ const char ** odnl; /*!< Original directory name(s) (from header) */
int_32 * odil; /*!< Original directory indice(s) (from header) */
/*@owned@*/ const char ** fmd5s;/*!< File MD5 sum(s) (from header) */
/*@owned@*/ const char ** flinks; /*!< File link(s) (from header) */
/* XXX setuid/setgid bits are turned off if fuser/fgroup doesn't map. */
uint_16 * fmodes; /*!< File mode(s) (from header) */
/*@owned@*/ char * fstates; /*!< File state(s) (from header) */
/*@owned@*/ const char ** fuser; /*!< File owner(s) */
/*@owned@*/ const char ** fgroup; /*!< File group(s) */
/*@owned@*/ const char ** flangs; /*!< File lang(s) */
int fc; /*!< No. of files. */
int dc; /*!< No. of directories. */
int bnlmax; /*!< Length (in bytes) of longest base name. */
int dnlmax; /*!< Length (in bytes) of longest dir name. */
int astriplen;
int striplen;
int scriptArg;
unsigned int archiveSize;
mode_t dperms; /*!< Directory perms (0755) if not mapped. */
mode_t fperms; /*!< File perms (0644) if not mapped. */
/*@owned@*/ const char ** apath;
int mapflags;
/*@owned@*/ int * fmapflags;
uid_t uid;
/*@owned@*/ /*@null@*/ uid_t * fuids; /*!< File uid(s) */
gid_t gid;
/*@owned@*/ /*@null@*/ gid_t * fgids; /*!< File gid(s) */
int magic;
#define TFIMAGIC 0x09697923
/*@owned@*/ FSM_t fsm; /*!< File state machine data. */
/* these are for TR_ADDED packages */
/*@dependent@*/ struct availablePackage * ap;
/*@owned@*/ struct sharedFileInfo * replaced;
/*@owned@*/ uint_32 * replacedSizes;
/* for TR_REMOVED packages */
unsigned int record;
};
#ifdef __cplusplus
extern "C" {
#endif
/**
* Load data from header into transaction file element info.
* @param h header
* @param fi transaction element file info
*/
void loadFi(Header h, TFI_t fi)
/*@modifies h, fi @*/;
/**
* Destroy transaction element file info.
* @param fi transaction element file info
*/
void freeFi(TFI_t fi)
/*@modifies fi @*/;
/**
* Return formatted string representation of package disposition.
* @param a package dispostion
* @return formatted string
*/
/*@observer@*/ const char *const fiTypeString(TFI_t fi);
/**
* Return formatted string representation of file disposition.
* @param a file dispostion
* @return formatted string
*/
/*@observer@*/ const char *const fileActionString(fileAction a);
/**
* Install binary package (from transaction set).
* @param ts transaction set
* @param fi transaction element file info
* @return 0 on success, 1 on bad magic, 2 on error
*/
int installBinaryPackage(const rpmTransactionSet ts, TFI_t fi);
/**
* Erase binary package (from transaction set).
* @param ts transaction set
* @param fi transaction element file info
* @param pkgKey package private data
* @return 0 on success
*/
int removeBinaryPackage(const rpmTransactionSet ts, TFI_t fi);
#ifdef __cplusplus
}
#endif
#endif /* H_ROLLBACK */

View File

@ -1,335 +0,0 @@
/** \ingroup rpmtrans payload
* \file lib/rollback.c
*/
#include "system.h"
#include <rpmlib.h>
#include "rollback.h"
#include "debug.h"
/*@access Header @*/ /* compared with NULL */
/*@access rpmTransactionSet @*/ /* compared with NULL */
/*@access TFI_t @*/ /* compared with NULL */
static /*@null@*/ void * _free(/*@only@*/ /*@null@*/ const void * this) {
if (this) free((void *)this);
return NULL;
}
void loadFi(Header h, TFI_t fi)
{
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) */
hge = (fi->type == TR_ADDED)
? (HGE_t) headerGetEntryMinMemory : (HGE_t) headerGetEntry;
fi->hge = hge;
fi->hfd = hfd = headerFreeData;
if (h && fi->h == NULL) fi->h = headerLink(h);
/* Duplicate name-version-release so that headers can be free'd. */
hge(fi->h, RPMTAG_NAME, NULL, (void **) &fi->name, NULL);
fi->name = xstrdup(fi->name);
hge(fi->h, RPMTAG_VERSION, NULL, (void **) &fi->version, NULL);
fi->version = xstrdup(fi->version);
hge(fi->h, RPMTAG_RELEASE, NULL, (void **) &fi->release, NULL);
fi->release = xstrdup(fi->release);
/* -1 means not found */
rc = hge(fi->h, RPMTAG_EPOCH, NULL, (void **) &uip, NULL);
fi->epoch = (rc ? *uip : -1);
/* 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;
}
hge(fi->h, RPMTAG_DIRINDEXES, NULL, (void **) &fi->dil, NULL);
hge(fi->h, RPMTAG_DIRNAMES, NULL, (void **) &fi->dnl, &fi->dc);
hge(fi->h, RPMTAG_FILEMODES, NULL, (void **) &fi->fmodes, NULL);
hge(fi->h, RPMTAG_FILEFLAGS, NULL, (void **) &fi->fflags, NULL);
hge(fi->h, RPMTAG_FILESIZES, NULL, (void **) &fi->fsizes, NULL);
hge(fi->h, RPMTAG_FILESTATES, NULL, (void **) &fi->fstates, NULL);
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:
fi->mapflags = CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
hge(fi->h, RPMTAG_FILEMD5S, NULL, (void **) &fi->fmd5s, NULL);
hge(fi->h, RPMTAG_FILELINKTOS, NULL, (void **) &fi->flinks, NULL);
hge(fi->h, RPMTAG_FILELANGS, NULL, (void **) &fi->flangs, NULL);
hge(fi->h, RPMTAG_FILEMTIMES, NULL, (void **) &fi->fmtimes, NULL);
/* 0 makes for noops */
fi->replacedSizes = xcalloc(fi->fc, sizeof(*fi->replacedSizes));
break;
case TR_REMOVED:
fi->mapflags = CPIO_MAP_PATH;
hge(fi->h, RPMTAG_FILEMD5S, NULL, (void **) &fi->fmd5s, NULL);
hge(fi->h, RPMTAG_FILELINKTOS, NULL, (void **) &fi->flinks, NULL);
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));
headerFree(fi->h);
fi->h = NULL;
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:
break;
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;
}
if (fi->h) {
headerFree(fi->h); fi->h = NULL;
}
}
/*@observer@*/ const char *const fiTypeString(TFI_t fi) {
switch(fi->type) {
case TR_ADDED: return " install";
case TR_REMOVED: return " erase";
default: return "???";
}
/*@noteached@*/
}
/*@observer@*/ const char *const fileStageString(fileStage a) {
switch(a) {
case FSM_UNKNOWN: return "unknown";
case FSM_PKGINSTALL:return "pkginstall";
case FSM_PKGERASE: return "pkgerase";
case FSM_PKGBUILD: return "pkgbuild";
case FSM_PKGCOMMIT: return "pkgcommit";
case FSM_PKGUNDO: return "pkgundo";
case FSM_CREATE: return "create";
case FSM_INIT: return "init";
case FSM_MAP: return "map";
case FSM_MKDIRS: return "mkdirs";
case FSM_RMDIRS: return "rmdirs";
case FSM_PRE: return "pre";
case FSM_PROCESS: return "process";
case FSM_POST: return "post";
case FSM_MKLINKS: return "mklinks";
case FSM_NOTIFY: return "notify";
case FSM_UNDO: return "undo";
case FSM_FINI: return "fini";
case FSM_COMMIT: return "commit";
case FSM_DESTROY: return "destroy";
case FSM_VERIFY: return "verify";
case FSM_UNLINK: return "Unlink";
case FSM_RENAME: return "Rename";
case FSM_MKDIR: return "Mkdir";
case FSM_RMDIR: return "rmdir";
case FSM_CHOWN: return "chown";
case FSM_LCHOWN: return "lchown";
case FSM_CHMOD: return "chmod";
case FSM_UTIME: return "utime";
case FSM_SYMLINK: return "symlink";
case FSM_LINK: return "Link";
case FSM_MKFIFO: return "mkfifo";
case FSM_MKNOD: return "mknod";
case FSM_LSTAT: return "Lstat";
case FSM_STAT: return "Stat";
case FSM_READLINK: return "Readlink";
case FSM_CHROOT: return "chroot";
case FSM_NEXT: return "next";
case FSM_EAT: return "eat";
case FSM_POS: return "pos";
case FSM_PAD: return "pad";
case FSM_TRAILER: return "trailer";
case FSM_HREAD: return "hread";
case FSM_HWRITE: return "hwrite";
case FSM_DREAD: return "Fread";
case FSM_DWRITE: return "Fwrite";
case FSM_ROPEN: return "Fopen";
case FSM_READ: return "Fread";
case FSM_RCLOSE: return "Fclose";
case FSM_WOPEN: return "Fopen";
case FSM_WRITE: return "Fwrite";
case FSM_WCLOSE: return "Fclose";
default: return "???";
}
/*@noteached@*/
}
/*@obserever@*/ const char *const fileActionString(fileAction a)
{
switch (a) {
case FA_UNKNOWN: return "unknown";
case FA_CREATE: return "create";
case FA_BACKUP: return "backup";
case FA_SAVE: return "save";
case FA_SKIP: return "skip";
case FA_ALTNAME: return "altname";
case FA_ERASE: return "erase";
case FA_SKIPNSTATE: return "skipnstate";
case FA_SKIPNETSHARED: return "skipnetshared";
case FA_SKIPMULTILIB: return "skipmultilib";
default: return "???";
}
/*@notreached@*/
}
#ifdef DYING
/**
*/
struct pkgIterator {
/*@dependent@*/ /*@kept@*/ TFI_t fi;
int i;
};
/**
*/
static /*@null@*/ void * pkgFreeIterator(/*@only@*/ /*@null@*/ void * this) {
return _free(this);
}
/**
*/
static /*@only@*/ void * pkgInitIterator(/*@kept@*/ rpmTransactionSet ts,
/*@kept@*/ TFI_t fi)
{
struct pkgIterator * pi = NULL;
if (ts && fi) {
pi = xcalloc(sizeof(*pi), 1);
pi->fi = fi;
switch (fi->type) {
case TR_ADDED: pi->i = 0; break;
case TR_REMOVED: pi->i = fi->fc; break;
}
}
return pi;
}
/**
*/
static int pkgNextIterator(/*@null@*/ void * this) {
struct pkgIterator * pi = this;
int i = -1;
if (pi) {
TFI_t fi = pi->fi;
switch (fi->type) {
case TR_ADDED:
if (pi->i < fi->fc)
i = pi->i++;
break;
case TR_REMOVED:
if (pi->i >= 0)
i = --pi->i;
break;
}
}
return i;
}
int pkgActions(const rpmTransactionSet ts, TFI_t fi, fileStage a)
{
int rc = 0;
if (fi->actions) {
void * pi = pkgInitIterator(ts, fi);
int i;
while ((i = pkgNextIterator(pi)) != -1) {
if (pkgAction(ts, fi, i, a))
rc++;
}
pi = pkgFreeIterator(pi);
}
return rc;
}
#endif

View File

@ -1,336 +0,0 @@
#ifndef H_ROLLBACK
#define H_ROLLBACK
/** \file lib/rollback.h
*/
#include "depends.h"
#include "install.h"
/**
*/
typedef /*@abstract@*/ struct fsm_s * FSM_t;
#include "cpio.h"
/**
*/
#define FSM_VERBOSE 0x8000
#define FSM_INTERNAL 0x4000
#define FSM_SYSCALL 0x2000
#define FSM_DEAD 0x1000
#define _fv(_a) ((_a) | FSM_VERBOSE)
#define _fi(_a) ((_a) | FSM_INTERNAL)
#define _fs(_a) ((_a) | (FSM_INTERNAL | FSM_SYSCALL))
#define _fd(_a) ((_a) | (FSM_INTERNAL | FSM_DEAD))
typedef enum fileStage_e {
FSM_UNKNOWN = 0,
FSM_INIT = _fd(1),
FSM_PRE = _fd(2),
FSM_PROCESS = _fv(3),
FSM_POST = _fd(4),
FSM_UNDO = 5,
FSM_FINI = 6,
FSM_PKGINSTALL = _fd(7),
FSM_PKGERASE = _fd(8),
FSM_PKGBUILD = _fd(9),
FSM_PKGCOMMIT = _fd(10),
FSM_PKGUNDO = _fd(11),
FSM_CREATE = _fd(17),
FSM_MAP = _fd(18),
FSM_MKDIRS = _fi(19),
FSM_RMDIRS = _fi(20),
FSM_MKLINKS = _fi(21),
FSM_NOTIFY = _fd(22),
FSM_DESTROY = _fd(23),
FSM_VERIFY = _fd(24),
FSM_COMMIT = _fd(25),
FSM_UNLINK = _fs(33),
FSM_RENAME = _fs(34),
FSM_MKDIR = _fs(35),
FSM_RMDIR = _fs(36),
FSM_CHOWN = _fs(37),
FSM_LCHOWN = _fs(38),
FSM_CHMOD = _fs(39),
FSM_UTIME = _fs(40),
FSM_SYMLINK = _fs(41),
FSM_LINK = _fs(42),
FSM_MKFIFO = _fs(43),
FSM_MKNOD = _fs(44),
FSM_LSTAT = _fs(45),
FSM_STAT = _fs(46),
FSM_READLINK= _fs(47),
FSM_CHROOT = _fs(48),
FSM_NEXT = _fd(65),
FSM_EAT = _fd(66),
FSM_POS = _fd(67),
FSM_PAD = _fd(68),
FSM_TRAILER = _fd(69),
FSM_HREAD = _fd(70),
FSM_HWRITE = _fd(71),
FSM_DREAD = _fs(72),
FSM_DWRITE = _fs(73),
FSM_ROPEN = _fs(129),
FSM_READ = _fs(130),
FSM_RCLOSE = _fs(131),
FSM_WOPEN = _fs(132),
FSM_WRITE = _fs(133),
FSM_WCLOSE = _fs(134),
} fileStage;
#undef _fi
/**
* File disposition(s) during package install/erase transaction.
*/
typedef enum fileAction_e {
FA_UNKNOWN = 0, /*!< initial action (default action for source rpm) */
FA_CREATE, /*!< ... to be replaced. */
FA_BACKUP, /*!< ... renamed with ".rpmorig" extension. */
FA_SAVE, /*!< ... renamed with ".rpmsave" extension. */
FA_SKIP, /*!< ... already replaced, don't remove. */
FA_ALTNAME, /*!< ... create with ".rpmnew" extension. */
FA_ERASE, /*!< ... to be removed. */
FA_SKIPNSTATE, /*!< ... untouched, state "not installed". */
FA_SKIPNETSHARED, /*!< ... untouched, state "netshared". */
FA_SKIPMULTILIB, /*!< ... untouched. @todo state "multilib" ???. */
} fileAction;
#define XFA_SKIPPING(_a) \
((_a) == FA_SKIP || (_a) == FA_SKIPNSTATE || (_a) == FA_SKIPNETSHARED || (_a) == FA_SKIPMULTILIB)
/**
*/
typedef enum rollbackDir_e {
ROLLBACK_SAVE = 1, /*!< Save files. */
ROLLBACK_RESTORE = 2, /*!< Restore files. */
} rollbackDir;
/**
* File types.
* These are the types of files used internally by rpm. The file
* type is determined by applying stat(2) macros like S_ISDIR to
* the file mode tag from a header. The values are arbitrary,
* but are identical to the linux stat(2) file types.
*/
enum fileTypes {
PIPE = 1, /*!< pipe/fifo */
CDEV = 2, /*!< character device */
XDIR = 4, /*!< directory */
BDEV = 6, /*!< block device */
REG = 8, /*!< regular file */
LINK = 10, /*!< hard link */
SOCK = 12, /*!< socket */
};
/**
*/
struct transactionFileInfo_s {
/* for all packages */
enum rpmTransactionType type;
fileAction action; /*!< File disposition default. */
/*@owned@*/ fileAction * actions; /*!< File disposition(s) */
/*@owned@*/ struct fingerPrint_s * fps; /*!< File fingerprint(s) */
HGE_t hge; /*!< Vector to headerGetEntry() */
HFD_t hfd; /*!< Vector to headerFreeData() */
Header h; /*!< Package header */
/*@owned@*/ const char * name;
/*@owned@*/ const char * version;
/*@owned@*/ const char * release;
int_32 epoch;
uint_32 flags; /*!< File flag default. */
const uint_32 * fflags; /*!< File flag(s) (from header) */
const uint_32 * fsizes; /*!< File size(s) (from header) */
const uint_32 * fmtimes; /*!< File modification time(s) (from header) */
/*@owned@*/ const char ** bnl; /*!< Base name(s) (from header) */
/*@owned@*/ const char ** dnl; /*!< Directory name(s) (from header) */
int_32 * dil; /*!< Directory indice(s) (from header) */
/*@owned@*/ const char ** obnl; /*!< Original base name(s) (from header) */
/*@owned@*/ const char ** odnl; /*!< Original directory name(s) (from header) */
int_32 * odil; /*!< Original directory indice(s) (from header) */
/*@owned@*/ const char ** fmd5s;/*!< File MD5 sum(s) (from header) */
/*@owned@*/ const char ** flinks; /*!< File link(s) (from header) */
/* XXX setuid/setgid bits are turned off if fuser/fgroup doesn't map. */
uint_16 * fmodes; /*!< File mode(s) (from header) */
/*@owned@*/ char * fstates; /*!< File state(s) (from header) */
/*@owned@*/ const char ** fuser; /*!< File owner(s) */
/*@owned@*/ const char ** fgroup; /*!< File group(s) */
/*@owned@*/ const char ** flangs; /*!< File lang(s) */
int fc; /*!< No. of files. */
int dc; /*!< No. of directories. */
int bnlmax; /*!< Length (in bytes) of longest base name. */
int dnlmax; /*!< Length (in bytes) of longest dir name. */
int astriplen;
int striplen;
int scriptArg;
unsigned int archiveSize;
mode_t dperms; /*!< Directory perms (0755) if not mapped. */
mode_t fperms; /*!< File perms (0644) if not mapped. */
/*@owned@*/ const char ** apath;
int mapflags;
/*@owned@*/ int * fmapflags;
uid_t uid;
/*@owned@*/ /*@null@*/ uid_t * fuids; /*!< File uid(s) */
gid_t gid;
/*@owned@*/ /*@null@*/ gid_t * fgids; /*!< File gid(s) */
int magic;
#define TFIMAGIC 0x09697923
/*@owned@*/ FSM_t fsm; /*!< File state machine data. */
/* these are for TR_ADDED packages */
/*@dependent@*/ struct availablePackage * ap;
/*@owned@*/ struct sharedFileInfo * replaced;
/*@owned@*/ uint_32 * replacedSizes;
/* for TR_REMOVED packages */
unsigned int record;
};
#ifdef __cplusplus
extern "C" {
#endif
/**
* Create file state machine instance.
* @return file state machine data
*/
/*@only@*/ /*@null@*/ FSM_t newFSM(void);
/**
* Destroy file state machine instance.
* @param fsm file state machine data
* @return always NULL
*/
/*@null@*/ FSM_t freeFSM(/*@only@*/ /*@null@*/ FSM_t fsm);
/**
* Load data from header into transaction file element info.
* @param h header
* @param fi transaction element file info
*/
void loadFi(Header h, TFI_t fi)
/*@modifies h, fi @*/;
/**
* Destroy transaction element file info.
* @param fi transaction element file info
*/
void freeFi(TFI_t fi)
/*@modifies fi @*/;
/**
* Return formatted string representation of package disposition.
* @param a package dispostion
* @return formatted string
*/
/*@observer@*/ const char *const fiTypeString(TFI_t fi);
/**
* Return formatted string representation of file stages.
* @param a file stage
* @return formatted string
*/
/*@observer@*/ const char *const fileStageString(fileStage a);
/**
* Return formatted string representation of file disposition.
* @param a file dispostion
* @return formatted string
*/
/*@observer@*/ const char *const fileActionString(fileAction a);
#ifdef DYING
/**
* Perform package install/remove actions for s single file.
* @todo Eliminate.
* @param ts transaction set
* @param fi transaction element file info
* @param i file index
* @param a file stage
* @return 0 on success, 1 on failure
*/
int pkgAction(const rpmTransactionSet ts, TFI_t fi, int i, fileStage a);
/**
* Perform package pre-install and remove actions.
* @todo Eliminate.
* @param ts transaction set
* @param fi transaction element file info
* @param a file stage
* @return 0 on success, otherwise no. of failures
*/
int pkgActions(const rpmTransactionSet ts, TFI_t fi, fileStage a);
#endif
/**
* Load external data into file state machine.
* @param fsm file state machine data
* @param goal
* @param ts transaction set
* @param fi transaction element file info
* @param archiveSize pointer to archive size
* @param failedFile pointer to first file name that failed.
* @return 0 on success
*/
int fsmSetup(FSM_t fsm, fileStage goal,
/*@kept@*/ const rpmTransactionSet ts,
/*@kept@*/ const TFI_t fi,
FD_t cfd,
/*@out@*/ unsigned int * archiveSize,
/*@out@*/ const char ** failedFile)
/*@modifies fsm, *archiveSize, *failedFile @*/;
/**
* Clean file state machine.
* @param fsm file state machine data
* @return 0 on success
*/
int fsmTeardown(FSM_t fsm)
/*@modifies fsm @*/;
/**
* Retrieve transaction set from file state machine iterator.
* @param fsm file state machine data
* @return transaction set
*/
/*@kept@*/ rpmTransactionSet fsmGetTs(const FSM_t fsm) /*@*/;
/**
* Retrieve transaction element file info from file state machine iterator.
* @param fsm file state machine data
* @return transaction element file info
*/
/*@kept@*/ TFI_t fsmGetFi(const FSM_t fsm) /*@*/;
/**
* Map next file path and action.
* @param fsm file state machine data
*/
int fsmMapPath(FSM_t fsm)
/*@modifies fsm @*/;
/**
* Map file stat(2) info.
* @param fsm file state machine data
*/
int fsmMapAttrs(FSM_t fsm)
/*@modifies fsm @*/;
/**
* File state machine driver.
* @param fsm file state machine data
* @param stage next stage
* @return 0 on success
*/
int fsmStage(FSM_t fsm, fileStage stage)
/*@modifies fsm @*/;
#ifdef __cplusplus
}
#endif
#endif /* H_ROLLBACK */

View File

@ -868,6 +868,56 @@ int rpmInstallSourcePackage(const char * root, FD_t fd,
*/
int rpmVersionCompare(Header first, Header second);
/**
* File disposition(s) during package install/erase transaction.
*/
typedef enum fileAction_e {
FA_UNKNOWN = 0, /*!< initial action for file ... */
FA_CREATE, /*!< ... to be replaced. */
FA_BACKUP, /*!< ... renamed with ".rpmorig" extension. */
FA_SAVE, /*!< ... renamed with ".rpmsave" extension. */
FA_SKIP, /*!< ... already replaced, don't remove. */
FA_ALTNAME, /*!< ... create with ".rpmnew" extension. */
FA_ERASE, /*!< ... to be removed. */
FA_SKIPNSTATE, /*!< ... untouched, state "not installed". */
FA_SKIPNETSHARED, /*!< ... untouched, state "netshared". */
FA_SKIPMULTILIB, /*!< ... untouched. @todo state "multilib" ???. */
} fileAction;
#define XFA_SKIPPING(_a) \
((_a) == FA_SKIP || (_a) == FA_SKIPNSTATE || (_a) == FA_SKIPNETSHARED || (_a) == FA_SKIPMULTILIB)
/**
* File types.
* These are the types of files used internally by rpm. The file
* type is determined by applying stat(2) macros like S_ISDIR to
* the file mode tag from a header. The values are arbitrary,
* but are identical to the linux stat(2) file types.
*/
typedef enum fileTypes_e {
PIPE = 1, /*!< pipe/fifo */
CDEV = 2, /*!< character device */
XDIR = 4, /*!< directory */
BDEV = 6, /*!< block device */
REG = 8, /*!< regular file */
LINK = 10, /*!< hard link */
SOCK = 12, /*!< socket */
} fileTypes;
/** \ingroup payload
* Iterator across package file info, forward on install, backward on erase.
*/
typedef /*@abstract@*/ struct fsmIterator_s * FSMI_t;
/** \ingroup payload
* File state machine data.
*/
typedef /*@abstract@*/ struct fsm_s * FSM_t;
/** \ingroup rpmtrans
*/
typedef /*@abstract@*/ struct transactionFileInfo_s * TFI_t;
/** \ingroup rpmtrans
* The RPM Transaction Set.
* Transaction sets are inherently unordered! RPM may reorder transaction

453
lib/scriptlet.c Normal file
View File

@ -0,0 +1,453 @@
/** \ingroup rpmtrans payload
* \file lib/scriptlet.c
*/
#include "system.h"
#include <rpmlib.h>
#include <rpmurl.h>
#include <rpmmacro.h> /* XXX for rpmExpand */
#include "depends.h" /* XXX for headerMatchesDepFlags */
#include "scriptlet.h"
#include "misc.h" /* XXX for makeTempFile, doputenv */
#include "debug.h"
/*@access Header@*/ /* XXX compared with NULL */
static char * SCRIPT_PATH = "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin";
/**
* Return scriptlet name from tag.
* @param tag scriptlet tag
* @return name of scriptlet
*/
static /*@observer@*/ const char * const tag2sln(int tag)
{
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";
}
/**
* 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.
*
* @param ts transaction set
* @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
*/
static int runScript(const rpmTransactionSet ts, Header h,
const char * sln,
int progArgc, const char ** progArgv,
const char * script, int arg1, int arg2)
{
const char ** argv = NULL;
int argc = 0;
const char ** prefixes = NULL;
int numPrefixes;
const char * oldPrefix;
int maxPrefixLength;
int len;
char * prefixBuf = NULL;
pid_t child;
int status = 0;
const char * fn = NULL;
int i;
int freePrefixes = 0;
FD_t out;
int rc = 0;
const char *n, *v, *r;
if (!progArgv && !script)
return 0;
if (!progArgv) {
argv = alloca(5 * sizeof(char *));
argv[0] = "/bin/sh";
argc = 1;
} else {
argv = alloca((progArgc + 4) * sizeof(char *));
memcpy(argv, progArgv, progArgc * sizeof(char *));
argc = progArgc;
}
headerNVR(h, &n, &v, &r);
if (headerGetEntry(h, RPMTAG_INSTPREFIXES, NULL, (void **) &prefixes,
&numPrefixes)) {
freePrefixes = 1;
} else if (headerGetEntry(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;
if (makeTempFile((!ts->chrootDone ? ts->rootDir : "/"), &fn, &fd)) {
if (freePrefixes) free(prefixes);
return 1;
}
if (rpmIsDebug() &&
(!strcmp(argv[0], "/bin/sh") || !strcmp(argv[0], "/bin/bash")))
(void)Fwrite("set -x\n", sizeof(char), 7, fd);
(void)Fwrite(script, sizeof(script[0]), strlen(script), fd);
Fclose(fd);
{ 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);
out = fdLink(out, "runScript persist");
}
if (!(child = fork())) {
const char * rootDir;
int pipes[2];
pipes[0] = pipes[1] = 0;
/* make stdin inaccessible */
pipe(pipes);
close(pipes[1]);
dup2(pipes[0], STDIN_FILENO);
close(pipes[0]);
if (ts->scriptFd != NULL) {
if (Fileno(ts->scriptFd) != STDERR_FILENO)
dup2(Fileno(ts->scriptFd), STDERR_FILENO);
if (Fileno(out) != STDOUT_FILENO)
dup2(Fileno(out), STDOUT_FILENO);
/* make sure we don't close stdin/stderr/stdout by mistake! */
if (Fileno(out) > STDERR_FILENO && Fileno(out) != Fileno(ts->scriptFd)) {
Fclose (out);
}
if (Fileno(ts->scriptFd) > STDERR_FILENO) {
Fclose (ts->scriptFd);
}
}
{ const char *ipath = rpmExpand("PATH=%{_install_script_path}", NULL);
const char *path = SCRIPT_PATH;
if (ipath && ipath[5] != '%')
path = ipath;
doputenv(path);
if (ipath) free((void *)ipath);
}
for (i = 0; i < numPrefixes; i++) {
sprintf(prefixBuf, "RPM_INSTALL_PREFIX%d=%s", i, prefixes[i]);
doputenv(prefixBuf);
/* backwards compatibility */
if (i == 0) {
sprintf(prefixBuf, "RPM_INSTALL_PREFIX=%s", prefixes[i]);
doputenv(prefixBuf);
}
}
rootDir = ts->rootDir;
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')) {
/*@-unrecog@*/ chroot(rootDir); /*@=unrecog@*/
}
chdir("/");
execv(argv[0], (char *const *)argv);
break;
default:
break;
}
_exit(-1);
/*@notreached@*/
}
if (waitpid(child, &status, 0) < 0) {
rpmError(RPMERR_SCRIPT,
_("execution of %s scriptlet from %s-%s-%s failed, waitpid returned %s\n"),
sln, n, v, r, strerror (errno));
/* XXX what to do here? */
rc = 0;
} else {
if (!WIFEXITED(status) || WEXITSTATUS(status)) {
rpmError(RPMERR_SCRIPT,
_("execution of %s scriptlet from %s-%s-%s failed, exit status %d\n"),
sln, n, v, r, WEXITSTATUS(status));
rc = 1;
}
}
if (freePrefixes) free(prefixes);
Fclose(out); /* XXX dup'd STDOUT_FILENO */
if (script) {
if (!rpmIsDebug()) unlink(fn);
free((void *)fn);
}
return rc;
}
int runInstScript(const rpmTransactionSet ts, Header h,
int scriptTag, int progTag, int arg, int norunScripts)
{
void ** programArgv;
int programArgc;
const char ** argv;
int programType;
char * script;
int rc;
if (norunScripts) return 0;
/* headerGetEntry() sets the data pointer to NULL if the entry does
not exist */
headerGetEntry(h, progTag, &programType, (void **) &programArgv,
&programArgc);
headerGetEntry(h, scriptTag, NULL, (void **) &script, NULL);
if (programArgv && programType == RPM_STRING_TYPE) {
argv = alloca(sizeof(char *));
*argv = (const char *) programArgv;
} else {
argv = (const char **) programArgv;
}
rc = runScript(ts, h, tag2sln(scriptTag), programArgc, argv, script,
arg, -1);
programArgv = headerFreeData(programArgv, programType);
return rc;
}
/**
* @param ts transaction set
* @param sense
* @param sourceH
* @param triggeredH
* @param arg1correction
* @param arg2
* @param triggersAlreadyRun
* @return
*/
static int handleOneTrigger(const rpmTransactionSet ts, int sense,
Header sourceH, Header triggeredH,
int arg1correction, int arg2,
char * triggersAlreadyRun)
{
const char ** triggerNames;
const char ** triggerEVR;
const char ** triggerScripts;
const char ** triggerProgs;
int_32 * triggerFlags;
int_32 * triggerIndices;
const char * triggerPackageName;
const char * sourceName;
int numTriggers;
int rc = 0;
int i;
int skip;
if (!headerGetEntry(triggeredH, RPMTAG_TRIGGERNAME, NULL,
(void **) &triggerNames, &numTriggers)) {
return 0;
}
headerNVR(sourceH, &sourceName, NULL, NULL);
headerGetEntry(triggeredH, RPMTAG_TRIGGERFLAGS, NULL,
(void **) &triggerFlags, NULL);
headerGetEntry(triggeredH, RPMTAG_TRIGGERVERSION, NULL,
(void **) &triggerEVR, NULL);
for (i = 0; i < numTriggers; i++) {
if (!(triggerFlags[i] & 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;
headerGetEntry(triggeredH, RPMTAG_TRIGGERINDEX, NULL,
(void **) &triggerIndices, NULL);
headerGetEntry(triggeredH, RPMTAG_TRIGGERSCRIPTS, NULL,
(void **) &triggerScripts, NULL);
headerGetEntry(triggeredH, RPMTAG_TRIGGERSCRIPTPROG, NULL,
(void **) &triggerProgs, NULL);
headerNVR(triggeredH, &triggerPackageName, NULL, NULL);
{ int arg1;
int index;
if ((arg1 = rpmdbCountPackages(ts->rpmdb, triggerPackageName)) < 0) {
rc = 1; /* XXX W2DO? same as "execution of script failed" */
} else {
arg1 += arg1correction;
index = triggerIndices[i];
if (!triggersAlreadyRun || !triggersAlreadyRun[index]) {
rc = runScript(ts, triggeredH, "%trigger", 1,
triggerProgs + index, triggerScripts[index],
arg1, arg2);
if (triggersAlreadyRun) triggersAlreadyRun[index] = 1;
}
}
}
free(triggerScripts);
free(triggerProgs);
/* each target/source header pair can only result in a single
script being run */
break;
}
free(triggerNames);
return rc;
}
int runTriggers(const rpmTransactionSet ts, int sense, Header h,
int countCorrection)
{
const char * name;
int numPackage;
int rc = 0;
headerNVR(h, &name, NULL, NULL);
numPackage = rpmdbCountPackages(ts->rpmdb, name) + countCorrection;
if (numPackage < 0)
return 1;
{ Header triggeredH;
rpmdbMatchIterator mi;
mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_TRIGGERNAME, name, 0);
while((triggeredH = rpmdbNextIterator(mi)) != NULL) {
rc |= handleOneTrigger(ts, sense, h, triggeredH, 0, numPackage,
NULL);
}
rpmdbFreeIterator(mi);
}
return rc;
}
int runImmedTriggers(const rpmTransactionSet ts, int sense, Header h,
int countCorrection)
{
const char ** triggerNames;
int numTriggers;
int_32 * triggerIndices;
int numTriggerIndices;
char * triggersRun;
int rc = 0;
if (!headerGetEntry(h, RPMTAG_TRIGGERNAME, NULL, (void **) &triggerNames,
&numTriggers))
return 0;
headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &triggerIndices,
&numTriggerIndices);
triggersRun = alloca(sizeof(*triggersRun) * numTriggerIndices);
memset(triggersRun, 0, sizeof(*triggersRun) * numTriggerIndices);
{ Header sourceH = NULL;
int i;
for (i = 0; i < numTriggers; i++) {
rpmdbMatchIterator mi;
const char * name = triggerNames[i];
if (triggersRun[triggerIndices[i]]) continue;
mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, name, 0);
while((sourceH = rpmdbNextIterator(mi)) != NULL) {
rc |= handleOneTrigger(ts, sense, sourceH, h,
countCorrection, rpmdbGetIteratorCount(mi),
triggersRun);
}
rpmdbFreeIterator(mi);
}
}
return rc;
}

View File

@ -1,32 +1,11 @@
#ifndef H_INSTALL
#define H_INSTALL
#ifndef H_SCRIPTLET
#define H_SCRIPTLET
/** \file lib/install.h
/** \file lib/scriptlet.h
*/
#include <rpmlib.h>
/**
*/
struct sharedFile {
int mainFileNumber;
int secRecOffset;
int secFileNumber;
} ;
/**
*/
struct sharedFileInfo {
int pkgFileNum;
int otherFileNum;
int otherPkg;
int isRemoved;
};
/**
*/
typedef /*@abstract@*/ struct transactionFileInfo_s * TFI_t;
#ifdef __cplusplus
extern "C" {
#endif
@ -66,25 +45,8 @@ int runTriggers(const rpmTransactionSet ts, int sense, Header h,
int runImmedTriggers(const rpmTransactionSet ts, int sense, Header h,
int countCorrection);
/**
* Install binary package (from transaction set).
* @param ts transaction set
* @param fi transaction element file info
* @return 0 on success, 1 on bad magic, 2 on error
*/
int installBinaryPackage(const rpmTransactionSet ts, TFI_t fi);
/**
* Erase binary package (from transaction set).
* @param ts transaction set
* @param fi transaction element file info
* @param pkgKey package private data
* @return 0 on success
*/
int removeBinaryPackage(const rpmTransactionSet ts, TFI_t fi);
#ifdef __cplusplus
}
#endif
#endif /* H_INSTALL */
#endif /* H_SCRIPTLET */

View File

@ -7,7 +7,7 @@
#include <rpmlib.h>
#include <rpmmacro.h> /* XXX for rpmExpand */
#include "rollback.h"
#include "psm.h"
#include "fprint.h"
#include "hash.h"
#include "md5.h"
@ -242,7 +242,7 @@ void rpmProblemSetFree(rpmProblemSet probs)
free(probs);
}
static /*@observer@*/ const char *const ftstring (enum fileTypes ft)
static /*@observer@*/ const char *const ftstring (fileTypes ft)
{
switch (ft) {
case XDIR: return "directory";
@ -257,7 +257,7 @@ static /*@observer@*/ const char *const ftstring (enum fileTypes ft)
/*@notreached@*/
}
static enum fileTypes whatis(uint_16 mode)
static fileTypes whatis(uint_16 mode)
{
if (S_ISDIR(mode)) return XDIR;
if (S_ISCHR(mode)) return CDEV;
@ -502,7 +502,7 @@ static Header relocateFileList(const rpmTransactionSet ts,
/* On install, a relocate to NULL means skip the path. */
if (relocations[j].newPath == NULL) {
enum fileTypes ft = whatis(fModes[i]);
fileTypes ft = whatis(fModes[i]);
int k;
if (ft == XDIR) {
/* Start with the parent, looking for directory to exclude. */
@ -711,7 +711,7 @@ static fileAction decideFileFate(const char * dirName,
{
char buffer[1024];
const char * dbAttr, * newAttr;
enum fileTypes dbWhat, newWhat, diskWhat;
fileTypes dbWhat, newWhat, diskWhat;
struct stat sb;
int i, rc;
int save = (newFlags & RPMFILE_NOREPLACE) ? FA_ALTNAME : FA_SAVE;
@ -802,8 +802,8 @@ static fileAction decideFileFate(const char * dirName,
static int filecmp(short mode1, const char * md51, const char * link1,
short mode2, const char * md52, const char * link2)
{
enum fileTypes what1 = whatis(mode1);
enum fileTypes what2 = whatis(mode2);
fileTypes what1 = whatis(mode1);
fileTypes what2 = whatis(mode2);
if (what1 != what2) return 1;

View File

@ -1,115 +0,0 @@
/** \ingroup rpmtrans payload
* \file lib/uninstall.c
*/
#include "system.h"
#include <rpmlib.h>
#include <rpmurl.h>
#include <rpmmacro.h> /* XXX for rpmExpand */
#include "rollback.h"
#include "misc.h" /* XXX for makeTempFile, doputenv */
#include "debug.h"
/*@access Header@*/ /* XXX compared with NULL */
int removeBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
{
/*@observer@*/ static char * stepName = " erase";
Header h;
int chrootDone = 0;
const char * failedFile = NULL;
const void * pkgKey = NULL;
int rc = 0;
rpmMessage(RPMMESS_DEBUG, _("%s: %s-%s-%s has %d files, test = %d\n"),
stepName, fi->name, fi->version, fi->release,
fi->fc, (ts->transFlags & RPMTRANS_FLAG_TEST));
/*
* 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.
*/
fi->scriptArg = rpmdbCountPackages(ts->rpmdb, fi->name) - 1;
if (fi->scriptArg < 0)
return 1;
{ rpmdbMatchIterator mi = NULL;
mi = rpmdbInitIterator(ts->rpmdb, RPMDBI_PACKAGES,
&fi->record, sizeof(fi->record));
h = rpmdbNextIterator(mi);
if (h == NULL) {
rpmdbFreeIterator(mi);
return 2;
}
h = headerLink(h);
rpmdbFreeIterator(mi);
}
if (ts->rootDir && !ts->chrootDone) {
chdir("/");
/*@-unrecog@*/ chroot(ts->rootDir); /*@=unrecog@*/
chrootDone = ts->chrootDone = 1;
}
if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERS)) {
/* run triggers from this package which are keyed on installed
packages */
if (runImmedTriggers(ts, RPMSENSE_TRIGGERUN, h, -1))
return 2;
/* run triggers which are set off by the removal of this package */
if (runTriggers(ts, RPMSENSE_TRIGGERUN, h, -1))
return 1;
}
rpmMessage(RPMMESS_DEBUG, _("%s: running %s script(s) (if any)\n"),
stepName, "pre-erase");
rc = runInstScript(ts, h, RPMTAG_PREUN, RPMTAG_PREUNPROG, fi->scriptArg,
(ts->transFlags & RPMTRANS_FLAG_NOSCRIPTS));
if (rc)
return 1;
if (fi->fc > 0 && !(ts->transFlags & RPMTRANS_FLAG_JUSTDB)) {
if (ts->notify)
(void)ts->notify(h, RPMCALLBACK_UNINST_START, fi->fc, fi->fc,
pkgKey, ts->notifyData);
rc = fsmSetup(fi->fsm, FSM_PKGERASE, ts, fi, NULL, NULL, &failedFile);
(void) fsmTeardown(fi->fsm);
if (ts->notify)
(void)ts->notify(h, RPMCALLBACK_UNINST_STOP, 0, fi->fc,
pkgKey, ts->notifyData);
}
rpmMessage(RPMMESS_DEBUG, _("%s: running %s script(s) (if any)\n"),
stepName, "post-erase");
rc = runInstScript(ts, h, RPMTAG_POSTUN, RPMTAG_POSTUNPROG,
fi->scriptArg, (ts->transFlags & RPMTRANS_FLAG_NOSCRIPTS));
/* XXX postun failures are not cause for erasure failure. */
if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERS)) {
/* Run postun triggers which are set off by this package's removal. */
rc = runTriggers(ts, RPMSENSE_TRIGGERPOSTUN, h, -1);
if (rc)
return 2;
}
if (ts->rootDir && chrootDone) {
/*@-unrecog@*/ chroot("."); /*@=unrecog@*/
chrootDone = ts->chrootDone = 0;
chdir(ts->currDir);
}
if (!(ts->transFlags & RPMTRANS_FLAG_TEST))
rpmdbRemove(ts->rpmdb, ts->id, fi->record);
return 0;
}

View File

@ -5,11 +5,9 @@
#include "system.h"
#include <rpmlib.h>
#include <rpmbuild.h>
#include <rpmurl.h>
#include "depends.h"
#include "install.h"
#include "psm.h"
#include "md5.h"
#include "misc.h"
#include "debug.h"

View File

@ -33,9 +33,9 @@ lib/falloc.c
lib/formats.c
lib/fprint.c
lib/fs.c
lib/fsm.c
lib/hash.c
lib/header.c
lib/install.c
lib/md5.c
lib/md5sum.c
lib/misc.c
@ -43,8 +43,8 @@ lib/package.c
lib/poptBT.c
lib/poptQV.c
lib/problems.c
lib/psm.c
lib/query.c
lib/rollback.c
lib/rpmchecksig.c
lib/rpmdb.c
lib/rpminstall.c
@ -54,7 +54,6 @@ lib/scriptlet.c
lib/signature.c
lib/stringbuf.c
lib/transaction.c
lib/uninstall.c
lib/verify.c
rpmio/base64.c
rpmio/digest.c

File diff suppressed because it is too large Load Diff

1
rpm.c
View File

@ -4,7 +4,6 @@
#include <rpmurl.h>
#include "build.h"
#include "install.h"
#include "signature.h"
#include "debug.h"

View File

@ -25,7 +25,6 @@ static int initdb = 0;
#endif
#ifdef IAM_RPMEIU
#include "install.h"
#define GETOPT_INSTALL 1014
#define GETOPT_RELOCATE 1016
#define GETOPT_EXCLUDEPATH 1019