Reorganize sources before implementing --repackage.
CVS patchset: 4543 CVS date: 2001/02/10 16:47:40
This commit is contained in:
parent
d304bac9be
commit
eccb6f66fc
|
@ -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 \
|
||||
|
|
1
build.c
1
build.c
|
@ -4,7 +4,6 @@
|
|||
#include <rpmurl.h>
|
||||
|
||||
#include "build.h"
|
||||
#include "install.h"
|
||||
#include "debug.h"
|
||||
|
||||
static int checkSpec(Header h)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* XXX this information will move elsewhere eventually
|
||||
*/
|
||||
|
||||
#include "rollback.h"
|
||||
#include "psm.h"
|
||||
|
||||
/**
|
||||
*/
|
||||
|
|
|
@ -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
1895
lib/cpio.c
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
335
lib/rollback.c
335
lib/rollback.c
|
@ -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
|
336
lib/rollback.h
336
lib/rollback.h
|
@ -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 */
|
50
lib/rpmlib.h
50
lib/rpmlib.h
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
|
||||
|
|
115
lib/uninstall.c
115
lib/uninstall.c
|
@ -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;
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
928
po/rpm.pot
928
po/rpm.pot
File diff suppressed because it is too large
Load Diff
1
rpm.c
1
rpm.c
|
@ -4,7 +4,6 @@
|
|||
#include <rpmurl.h>
|
||||
|
||||
#include "build.h"
|
||||
#include "install.h"
|
||||
#include "signature.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue