Commit to install file state machine.
CVS patchset: 4509 CVS date: 2001/01/29 22:53:48
This commit is contained in:
parent
f684f63a72
commit
d8b44a5d65
1341
lib/cpio.c
1341
lib/cpio.c
File diff suppressed because it is too large
Load Diff
19
lib/cpio.h
19
lib/cpio.h
|
@ -47,10 +47,11 @@ enum cpioErrorReturns {
|
|||
CPIOERR_READ_FAILED = (20 | CPIOERR_CHECK_ERRNO),
|
||||
CPIOERR_COPY_FAILED = (21 | CPIOERR_CHECK_ERRNO),
|
||||
CPIOERR_HDR_SIZE = (22 ),
|
||||
CPIOERR_UNKNOWN_FILETYPE= (23 ),
|
||||
CPIOERR_MISSING_HARDLINK= (24 ),
|
||||
CPIOERR_MD5SUM_MISMATCH = (25 ),
|
||||
CPIOERR_INTERNAL = (26 )
|
||||
CPIOERR_HDR_TRAILER = (23 ),
|
||||
CPIOERR_UNKNOWN_FILETYPE= (24 ),
|
||||
CPIOERR_MISSING_HARDLINK= (25 ),
|
||||
CPIOERR_MD5SUM_MISMATCH = (26 ),
|
||||
CPIOERR_INTERNAL = (27 )
|
||||
};
|
||||
|
||||
/** \ingroup payload
|
||||
|
@ -78,15 +79,11 @@ extern "C" {
|
|||
* used for the permission bits, not for the file type. The owner/group
|
||||
* mappings are ignored for the non-root user.
|
||||
*
|
||||
* @param ts transaction set
|
||||
* @param fi transaction element file info
|
||||
* @param cfd file handle
|
||||
* @retval failedFile (malloc'd) file name that caused failure (if any)
|
||||
* @param fsm file state machine data
|
||||
* @return 0 on success
|
||||
*/
|
||||
int cpioInstallArchive(const rpmTransactionSet ts, const TFI_t fi, FD_t cfd,
|
||||
/*@out@*/const char ** failedFile)
|
||||
/*@modifies fileSystem, cfd, *failedFile @*/;
|
||||
int cpioInstallArchive(FSM_t fsm)
|
||||
/*@modifies fileSystem, fsm @*/;
|
||||
|
||||
/** \ingroup payload
|
||||
* The RPM internal equivalent of the command line "cpio -o".
|
||||
|
|
|
@ -531,10 +531,12 @@ typedef enum rpmTagType_e {
|
|||
/*@unused@*/ static inline /*@null@*/ void * headerFreeData(
|
||||
/*@only@*/ const void * data, rpmTagType type)
|
||||
{
|
||||
if (type == RPM_STRING_ARRAY_TYPE ||
|
||||
if (data) {
|
||||
if (type < 0 ||
|
||||
type == RPM_STRING_ARRAY_TYPE ||
|
||||
type == RPM_I18NSTRING_TYPE ||
|
||||
type == RPM_BIN_TYPE) {
|
||||
if (data) free((void *)data);
|
||||
type == RPM_BIN_TYPE)
|
||||
free((void *)data);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -416,12 +416,6 @@ static int installArchive(const rpmTransactionSet ts, TFI_t fi, int allFiles)
|
|||
return 0;
|
||||
}
|
||||
|
||||
{ uint_32 * asp;
|
||||
rc = headerGetEntry(fi->h, RPMTAG_ARCHIVESIZE, NULL,
|
||||
(void **) &asp, NULL);
|
||||
fi->archiveSize = (rc ? *asp : 0);
|
||||
}
|
||||
|
||||
/* Retrieve type of payload compression. */
|
||||
{ const char * payload_compressor = NULL;
|
||||
char * t;
|
||||
|
@ -437,12 +431,18 @@ static int installArchive(const rpmTransactionSet ts, TFI_t fi, int allFiles)
|
|||
t = stpcpy(t, ".bzdio");
|
||||
}
|
||||
|
||||
{ FD_t cfd;
|
||||
{
|
||||
FD_t cfd;
|
||||
(void) Fflush(alp->fd);
|
||||
|
||||
cfd = Fdopen(fdDup(Fileno(alp->fd)), rpmio_flags);
|
||||
rc = cpioInstallArchive(ts, fi, cfd, &failedFile);
|
||||
cfd = fdLink(cfd, "persist (installArchive");
|
||||
|
||||
rc = fsmSetup(fi->fsm, ts, fi, cfd, &failedFile);
|
||||
rc = cpioInstallArchive(fi->fsm);
|
||||
saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */
|
||||
Fclose(cfd);
|
||||
(void) fsmTeardown(fi->fsm);
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
|
@ -456,6 +456,13 @@ static int installArchive(const rpmTransactionSet ts, TFI_t fi, int allFiles)
|
|||
(failedFile != NULL ? failedFile : ""),
|
||||
cpioStrerror(rc));
|
||||
rc = 1;
|
||||
} else {
|
||||
if (ts && ts->notify) {
|
||||
unsigned int archiveSize = (fi->archiveSize ? fi->archiveSize : 100);
|
||||
(void)ts->notify(fi->h, RPMCALLBACK_INST_PROGRESS,
|
||||
archiveSize, archiveSize,
|
||||
(fi->ap ? fi->ap->key : NULL), ts->notifyData);
|
||||
}
|
||||
}
|
||||
|
||||
if (failedFile)
|
||||
|
@ -809,7 +816,7 @@ int installBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
|
|||
|
||||
setFileOwners(fi);
|
||||
|
||||
rc = pkgActions(ts, fi);
|
||||
rc = pkgActions(ts, fi, FSM_COMMIT);
|
||||
if (rc)
|
||||
goto exit;
|
||||
|
||||
|
|
368
lib/rollback.c
368
lib/rollback.c
|
@ -12,86 +12,16 @@
|
|||
|
||||
/*@access h@*/ /* compared with NULL */
|
||||
|
||||
#define SUFFIX_RPMORIG ".rpmorig"
|
||||
#define SUFFIX_RPMSAVE ".rpmsave"
|
||||
#define SUFFIX_RPMNEW ".rpmnew"
|
||||
|
||||
static char * ridsub = ".rid/";
|
||||
static char * ridsep = ";";
|
||||
static mode_t riddmode = 0700;
|
||||
static mode_t ridfmode = 0000;
|
||||
|
||||
int dirstashPackage(const rpmTransactionSet ts, const TFI_t fi, rollbackDir dir)
|
||||
{
|
||||
unsigned int offset = fi->record;
|
||||
char tsid[20], ofn[BUFSIZ], nfn[BUFSIZ];
|
||||
const char * s, * t;
|
||||
char * se, * te;
|
||||
Header h;
|
||||
int i;
|
||||
|
||||
assert(fi->type == TR_REMOVED);
|
||||
|
||||
{ rpmdbMatchIterator mi = NULL;
|
||||
|
||||
mi = rpmdbInitIterator(ts->rpmdb, RPMDBI_PACKAGES,
|
||||
&offset, sizeof(offset));
|
||||
|
||||
h = rpmdbNextIterator(mi);
|
||||
if (h == NULL) {
|
||||
rpmdbFreeIterator(mi);
|
||||
return 1;
|
||||
}
|
||||
h = headerLink(h);
|
||||
rpmdbFreeIterator(mi);
|
||||
}
|
||||
|
||||
sprintf(tsid, "%08x", ts->id);
|
||||
|
||||
/* Create rid sub-directories if necessary. */
|
||||
if (strchr(ridsub, '/')) {
|
||||
for (i = 0; i < fi->dc; i++) {
|
||||
|
||||
t = te = nfn;
|
||||
*te = '\0';
|
||||
te = stpcpy(te, fi->dnl[i]);
|
||||
te = stpcpy(te, ridsub);
|
||||
if (te[-1] == '/')
|
||||
*(--te) = '\0';
|
||||
fprintf(stderr, "*** mkdir(%s,%o)\n", t, (int)riddmode);
|
||||
}
|
||||
}
|
||||
|
||||
/* Rename files about to be removed. */
|
||||
for (i = 0; i < fi->fc; i++) {
|
||||
|
||||
if (S_ISDIR(fi->fmodes[i]))
|
||||
continue;
|
||||
|
||||
s = se = ofn;
|
||||
*se = '\0';
|
||||
se = stpcpy( stpcpy(se, fi->dnl[fi->dil[i]]), fi->bnl[i]);
|
||||
|
||||
t = te = nfn;
|
||||
*te = '\0';
|
||||
te = stpcpy(te, fi->dnl[fi->dil[i]]);
|
||||
if (ridsub)
|
||||
te = stpcpy(te, ridsub);
|
||||
te = stpcpy( stpcpy( stpcpy(te, fi->bnl[i]), ridsep), tsid);
|
||||
|
||||
s = strrchr(s, '/') + 1;
|
||||
t = strrchr(t, '/') + 1;
|
||||
fprintf(stderr, "*** rename(%s,%s%s)\n", s, (ridsub ? ridsub : ""), t);
|
||||
fprintf(stderr, "*** chmod(%s%s,%o)\n", (ridsub ? ridsub : ""), t, ridfmode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void loadFi(Header h, TFI_t fi)
|
||||
{
|
||||
HGE_t hge;
|
||||
int len, i;
|
||||
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)
|
||||
|
@ -108,19 +38,16 @@ void loadFi(Header h, TFI_t fi)
|
|||
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;
|
||||
fi->dnl = NULL;
|
||||
fi->bnl = NULL;
|
||||
fi->dil = NULL;
|
||||
fi->fmodes = NULL;
|
||||
fi->fflags = NULL;
|
||||
fi->fsizes = NULL;
|
||||
fi->fstates = NULL;
|
||||
fi->fmd5s = NULL;
|
||||
fi->flinks = NULL;
|
||||
fi->flangs = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -184,9 +111,6 @@ void loadFi(Header h, TFI_t fi)
|
|||
|
||||
void freeFi(TFI_t fi)
|
||||
{
|
||||
if (fi->h) {
|
||||
headerFree(fi->h); fi->h = NULL;
|
||||
}
|
||||
if (fi->name) {
|
||||
free((void *)fi->name); fi->name = NULL;
|
||||
}
|
||||
|
@ -205,33 +129,17 @@ void freeFi(TFI_t fi)
|
|||
if (fi->replaced) {
|
||||
free(fi->replaced); fi->replaced = NULL;
|
||||
}
|
||||
if (fi->bnl) {
|
||||
free(fi->bnl); fi->bnl = NULL;
|
||||
}
|
||||
if (fi->dnl) {
|
||||
free(fi->dnl); fi->dnl = NULL;
|
||||
}
|
||||
if (fi->obnl) {
|
||||
free(fi->obnl); fi->obnl = NULL;
|
||||
}
|
||||
if (fi->odnl) {
|
||||
free(fi->odnl); fi->odnl = NULL;
|
||||
}
|
||||
if (fi->flinks) {
|
||||
free(fi->flinks); fi->flinks = NULL;
|
||||
}
|
||||
if (fi->fmd5s) {
|
||||
free(fi->fmd5s); fi->fmd5s = NULL;
|
||||
}
|
||||
if (fi->fuser) {
|
||||
free(fi->fuser); fi->fuser = NULL;
|
||||
}
|
||||
if (fi->fgroup) {
|
||||
free(fi->fgroup); fi->fgroup = NULL;
|
||||
}
|
||||
if (fi->flangs) {
|
||||
free(fi->flangs); fi->flangs = NULL;
|
||||
}
|
||||
|
||||
fi->bnl = headerFreeData(fi->bnl, -1);
|
||||
fi->dnl = headerFreeData(fi->dnl, -1);
|
||||
fi->obnl = headerFreeData(fi->obnl, -1);
|
||||
fi->odnl = headerFreeData(fi->odnl, -1);
|
||||
fi->flinks = headerFreeData(fi->flinks, -1);
|
||||
fi->fmd5s = headerFreeData(fi->fmd5s, -1);
|
||||
fi->fuser = headerFreeData(fi->fuser, -1);
|
||||
fi->fgroup = headerFreeData(fi->fgroup, -1);
|
||||
fi->flangs = headerFreeData(fi->flangs, -1);
|
||||
|
||||
if (fi->apath) {
|
||||
free(fi->apath); fi->apath = NULL;
|
||||
}
|
||||
|
@ -245,27 +153,22 @@ void freeFi(TFI_t fi)
|
|||
free(fi->fmapflags); fi->fmapflags = NULL;
|
||||
}
|
||||
|
||||
fi->fsm = freeFSM(fi->fsm);
|
||||
|
||||
switch (fi->type) {
|
||||
case TR_ADDED:
|
||||
break;
|
||||
case TR_REMOVED:
|
||||
if (fi->fsizes) {
|
||||
free((void *)fi->fsizes); fi->fsizes = NULL;
|
||||
}
|
||||
if (fi->fflags) {
|
||||
free((void *)fi->fflags); fi->fflags = NULL;
|
||||
}
|
||||
if (fi->fmodes) {
|
||||
free((void *)fi->fmodes); fi->fmodes = NULL;
|
||||
}
|
||||
if (fi->fstates) {
|
||||
free((void *)fi->fstates); fi->fstates = NULL;
|
||||
}
|
||||
if (fi->dil) {
|
||||
free((void *)fi->dil); fi->dil = NULL;
|
||||
}
|
||||
fi->fsizes = headerFreeData(fi->fsizes, -1);
|
||||
fi->fflags = headerFreeData(fi->fflags, -1);
|
||||
fi->fmodes = headerFreeData(fi->fmodes, -1);
|
||||
fi->fstates = headerFreeData(fi->fstates, -1);
|
||||
fi->dil = headerFreeData(fi->dil, -1);
|
||||
break;
|
||||
}
|
||||
if (fi->h) {
|
||||
headerFree(fi->h); fi->h = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*@observer@*/ const char *const fiTypeString(TFI_t fi) {
|
||||
|
@ -279,30 +182,38 @@ void freeFi(TFI_t fi)
|
|||
|
||||
/*@observer@*/ const char *const fileStageString(fileStage a) {
|
||||
switch(a) {
|
||||
case FI_CREATE: return "create";
|
||||
case FI_INIT: return "init";
|
||||
case FI_MAP: return "map";
|
||||
case FI_SKIP: return "skip";
|
||||
case FI_PRE: return "pre-process";
|
||||
case FI_PROCESS: return "process";
|
||||
case FI_POST: return "post-process";
|
||||
case FI_NOTIFY: return "notify";
|
||||
case FI_UNDO: return "undo";
|
||||
case FI_COMMIT: return "commit";
|
||||
case FI_DESTROY: return "destroy";
|
||||
case FI_VERIFY: return "verify";
|
||||
case FI_UNLINK: return "unlink";
|
||||
case FI_RENAME: return "rename";
|
||||
case FI_MKDIR: return "mkdir";
|
||||
case FI_RMDIR: return "rmdir";
|
||||
case FI_CHOWN: return "chown";
|
||||
case FI_LCHOWN: return "lchown";
|
||||
case FI_CHMOD: return "chmod";
|
||||
case FI_UTIME: return "utime";
|
||||
case FI_SYMLINK: return "symlink";
|
||||
case FI_LINK: return "link";
|
||||
case FI_MKFIFO: return "mkfifo";
|
||||
case FI_MKNOD: return "mknod";
|
||||
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_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_NEXT: return "next";
|
||||
case FSM_EAT: return "eat ";
|
||||
case FSM_POS: return "pos ";
|
||||
case FSM_PAD: return "pad ";
|
||||
default: return "??? ";
|
||||
}
|
||||
/*@noteached@*/
|
||||
|
@ -326,16 +237,23 @@ void freeFi(TFI_t fi)
|
|||
/*@notreached@*/
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
struct pkgIterator {
|
||||
/*@kept@*/ TFI_t fi;
|
||||
/*@dependent@*/ /*@kept@*/ TFI_t fi;
|
||||
int i;
|
||||
};
|
||||
|
||||
static void pkgFreeIterator(void * this) {
|
||||
/**
|
||||
*/
|
||||
static /*@null@*/ void * pkgFreeIterator(/*@only@*/ /*@null@*/ void * this) {
|
||||
if (this) free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void * pkgInitIterator(TFI_t fi) {
|
||||
/**
|
||||
*/
|
||||
static /*@only@*/ void * pkgInitIterator(/*@kept@*/ TFI_t fi) {
|
||||
struct pkgIterator *pi = xcalloc(sizeof(*pi), 1);
|
||||
pi->fi = fi;
|
||||
switch (fi->type) {
|
||||
|
@ -345,10 +263,14 @@ static void * pkgInitIterator(TFI_t fi) {
|
|||
return pi;
|
||||
}
|
||||
|
||||
static int pkgNextIterator(void * this) {
|
||||
/**
|
||||
*/
|
||||
static int pkgNextIterator(/*@null@*/ void * this) {
|
||||
struct pkgIterator *pi = this;
|
||||
TFI_t fi = pi->fi;
|
||||
int i = -1;
|
||||
|
||||
if (pi) {
|
||||
TFI_t fi = pi->fi;
|
||||
switch (fi->type) {
|
||||
case TR_ADDED:
|
||||
if (pi->i < fi->fc)
|
||||
|
@ -359,17 +281,12 @@ static int pkgNextIterator(void * this) {
|
|||
i = --pi->i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
int pkgActions(const rpmTransactionSet ts, TFI_t fi)
|
||||
int pkgActions(const rpmTransactionSet ts, TFI_t fi, fileStage a)
|
||||
{
|
||||
int nb = (!ts->chrootDone ? strlen(ts->rootDir) : 0);
|
||||
char * opath = alloca(nb + fi->dnlmax + fi->bnlmax + 64);
|
||||
char * o = (!ts->chrootDone ? stpcpy(opath, ts->rootDir) : opath);
|
||||
char * npath = alloca(nb + fi->dnlmax + fi->bnlmax + 64);
|
||||
char * n = (!ts->chrootDone ? stpcpy(npath, ts->rootDir) : npath);
|
||||
int rc = 0;
|
||||
void * pi;
|
||||
int i;
|
||||
|
@ -379,120 +296,7 @@ int pkgActions(const rpmTransactionSet ts, TFI_t fi)
|
|||
|
||||
pi = pkgInitIterator(fi);
|
||||
while ((i = pkgNextIterator(pi)) != -1) {
|
||||
char * ext, * t;
|
||||
|
||||
if (fi->actions[i] & FA_DONE)
|
||||
continue;
|
||||
|
||||
rpmMessage(RPMMESS_DEBUG, _(" file: %s%s action: %s\n"),
|
||||
fi->dnl[fi->dil[i]], fi->bnl[i],
|
||||
fileActionString((fi->actions ? fi->actions[i] : FA_UNKNOWN)) );
|
||||
|
||||
ext = NULL;
|
||||
|
||||
switch (fi->actions[i] & ~FA_DONE) {
|
||||
case FA_DONE:
|
||||
case FA_SKIP:
|
||||
case FA_SKIPMULTILIB:
|
||||
case FA_UNKNOWN:
|
||||
continue;
|
||||
/*@notreached@*/ break;
|
||||
|
||||
case FA_CREATE:
|
||||
assert(fi->type == TR_ADDED);
|
||||
continue;
|
||||
/*@notreached@*/ break;
|
||||
|
||||
case FA_SKIPNSTATE:
|
||||
if (fi->type == TR_ADDED)
|
||||
fi->fstates[i] = RPMFILE_STATE_NOTINSTALLED;
|
||||
continue;
|
||||
/*@notreached@*/ break;
|
||||
|
||||
case FA_SKIPNETSHARED:
|
||||
if (fi->type == TR_ADDED)
|
||||
fi->fstates[i] = RPMFILE_STATE_NETSHARED;
|
||||
continue;
|
||||
/*@notreached@*/ break;
|
||||
case FA_BACKUP:
|
||||
ext = (fi->type == TR_ADDED ? SUFFIX_RPMORIG : SUFFIX_RPMSAVE);
|
||||
break;
|
||||
|
||||
case FA_ALTNAME:
|
||||
assert(fi->type == TR_ADDED);
|
||||
ext = SUFFIX_RPMNEW;
|
||||
t = xmalloc(strlen(fi->bnl[i]) + strlen(ext) + 1);
|
||||
(void)stpcpy(stpcpy(t, fi->bnl[i]), ext);
|
||||
rpmMessage(RPMMESS_WARNING, _("%s: %s%s created as %s\n"),
|
||||
fiTypeString(fi), fi->dnl[fi->dil[i]], fi->bnl[i], t);
|
||||
fi->bnl[i] = t; /* XXX memory leak iff i = 0 */
|
||||
ext = NULL;
|
||||
continue;
|
||||
/*@notreached@*/ break;
|
||||
|
||||
case FA_SAVE:
|
||||
assert(fi->type == TR_ADDED);
|
||||
ext = SUFFIX_RPMSAVE;
|
||||
break;
|
||||
|
||||
case FA_REMOVE:
|
||||
assert(fi->type == TR_REMOVED);
|
||||
/* Append file name to (possible) root dir. */
|
||||
(void) stpcpy( stpcpy(o, fi->dnl[fi->dil[i]]), fi->bnl[i]);
|
||||
if (S_ISDIR(fi->fmodes[i])) {
|
||||
if (!rmdir(opath))
|
||||
continue;
|
||||
switch (errno) {
|
||||
case ENOENT: /* XXX rmdir("/") linux 2.2.x kernel hack */
|
||||
case ENOTEMPTY:
|
||||
#ifdef NOTYET
|
||||
if (fi->fflags[i] & RPMFILE_MISSINGOK)
|
||||
continue;
|
||||
#endif
|
||||
rpmError(RPMERR_RMDIR,
|
||||
_("%s: cannot remove %s - directory not empty\n"),
|
||||
fiTypeString(fi), o);
|
||||
break;
|
||||
default:
|
||||
rpmError(RPMERR_RMDIR,
|
||||
_("%s rmdir of %s failed: %s\n"),
|
||||
fiTypeString(fi), o, strerror(errno));
|
||||
break;
|
||||
}
|
||||
rc++;
|
||||
continue;
|
||||
/*@notreached@*/ break;
|
||||
}
|
||||
if (!unlink(opath))
|
||||
continue;
|
||||
if (errno == ENOENT && (fi->fflags[i] & RPMFILE_MISSINGOK))
|
||||
continue;
|
||||
rpmError(RPMERR_UNLINK, _("%s removal of %s failed: %s\n"),
|
||||
fiTypeString(fi), o, strerror(errno));
|
||||
rc++;
|
||||
continue;
|
||||
/*@notreached@*/ break;
|
||||
}
|
||||
|
||||
if (ext == NULL)
|
||||
continue;
|
||||
|
||||
/* Append file name to (possible) root dir. */
|
||||
(void) stpcpy( stpcpy(o, fi->dnl[fi->dil[i]]), fi->bnl[i]);
|
||||
|
||||
/* XXX TR_REMOVED dinna do this. */
|
||||
if (access(opath, F_OK) != 0)
|
||||
continue;
|
||||
|
||||
(void) stpcpy( stpcpy(n, o), ext);
|
||||
rpmMessage(RPMMESS_WARNING, _("%s: %s saved as %s\n"),
|
||||
fiTypeString(fi), o, n);
|
||||
|
||||
if (!rename(opath, npath))
|
||||
continue;
|
||||
|
||||
rpmError(RPMERR_RENAME, _("%s rename of %s to %s failed: %s\n"),
|
||||
fiTypeString(fi), o, n, strerror(errno));
|
||||
if (pkgAction(ts, fi, i, a))
|
||||
rc++;
|
||||
}
|
||||
pkgFreeIterator(pi);
|
||||
|
|
118
lib/rollback.h
118
lib/rollback.h
|
@ -6,38 +6,56 @@
|
|||
|
||||
#include "depends.h"
|
||||
#include "install.h"
|
||||
|
||||
/**
|
||||
*/
|
||||
typedef /*@abstract@*/ struct cpioHeader * FSM_t;
|
||||
|
||||
#include "cpio.h"
|
||||
|
||||
/**
|
||||
*/
|
||||
#define FI_INTERNAL 0x8000
|
||||
#define _fi(_a) ((_a) | FI_INTERNAL)
|
||||
#define FSM_INTERNAL 0x8000
|
||||
#define FSM_QUIET 0x4000
|
||||
#define _fi(_a) ((_a) | FSM_INTERNAL)
|
||||
#define _fq(_a) ((_a) | FSM_INTERNAL)
|
||||
typedef enum fileStage_e {
|
||||
FI_CREATE = _fi(0),
|
||||
FI_INIT = 1,
|
||||
FI_MAP = 2,
|
||||
FI_SKIP = _fi(3),
|
||||
FI_PRE = 4,
|
||||
FI_PROCESS = 5,
|
||||
FI_POST = 6,
|
||||
FI_NOTIFY = _fi(7),
|
||||
FI_UNDO = 8,
|
||||
FI_COMMIT = 9,
|
||||
FI_DESTROY = 10,
|
||||
FI_VERIFY = _fi(11),
|
||||
FI_UNLINK = _fi(12),
|
||||
FI_RENAME = _fi(13),
|
||||
FI_MKDIR = _fi(14),
|
||||
FI_RMDIR = _fi(15),
|
||||
FI_CHOWN = _fi(16),
|
||||
FI_LCHOWN = _fi(17),
|
||||
FI_CHMOD = _fi(18),
|
||||
FI_UTIME = _fi(19),
|
||||
FI_SYMLINK = _fi(20),
|
||||
FI_LINK = _fi(21),
|
||||
FI_MKFIFO = _fi(22),
|
||||
FI_MKNOD = _fi(23),
|
||||
FSM_UNKNOWN = 0,
|
||||
FSM_INIT = _fq(1),
|
||||
FSM_PRE = _fq(2),
|
||||
FSM_PROCESS = _fq(3),
|
||||
FSM_POST = _fq(4),
|
||||
FSM_UNDO = 5,
|
||||
FSM_COMMIT = 6,
|
||||
|
||||
FSM_CREATE = _fi(17),
|
||||
FSM_MAP = _fi(18),
|
||||
FSM_MKDIRS = _fi(19),
|
||||
FSM_RMDIRS = _fi(20),
|
||||
FSM_MKLINKS = _fi(21),
|
||||
FSM_NOTIFY = _fi(22),
|
||||
FSM_DESTROY = _fi(23),
|
||||
FSM_VERIFY = _fi(24),
|
||||
|
||||
FSM_UNLINK = _fi(33),
|
||||
FSM_RENAME = _fi(34),
|
||||
FSM_MKDIR = _fi(35),
|
||||
FSM_RMDIR = _fi(36),
|
||||
FSM_CHOWN = _fi(37),
|
||||
FSM_LCHOWN = _fi(38),
|
||||
FSM_CHMOD = _fi(39),
|
||||
FSM_UTIME = _fi(40),
|
||||
FSM_SYMLINK = _fi(41),
|
||||
FSM_LINK = _fi(42),
|
||||
FSM_MKFIFO = _fi(43),
|
||||
FSM_MKNOD = _fi(44),
|
||||
|
||||
FSM_NEXT = _fi(65),
|
||||
FSM_EAT = _fi(66),
|
||||
FSM_POS = _fi(67),
|
||||
FSM_PAD = _fi(68),
|
||||
} fileStage;
|
||||
#undef _fi
|
||||
|
||||
/**
|
||||
* File disposition(s) during package install/erase transaction.
|
||||
|
@ -53,7 +71,6 @@ typedef enum fileAction_e {
|
|||
FA_SKIPNSTATE, /*!< ... untouched, state "not installed". */
|
||||
FA_SKIPNETSHARED, /*!< ... untouched, state "netshared". */
|
||||
FA_SKIPMULTILIB, /*!< ... untouched. @todo state "multilib" ???. */
|
||||
FA_DONE = (1 << 31)
|
||||
} fileAction;
|
||||
|
||||
|
||||
|
@ -102,6 +119,7 @@ struct transactionFileInfo_s {
|
|||
/*@owned@*/ const char * name;
|
||||
/*@owned@*/ const char * version;
|
||||
/*@owned@*/ const char * release;
|
||||
int_32 epoch;
|
||||
const uint_32 * fflags; /*!< File flags (from header) */
|
||||
const uint_32 * fsizes; /*!< File sizes (from header) */
|
||||
/*@owned@*/ const char ** bnl; /*!< Base names (from header) */
|
||||
|
@ -134,6 +152,8 @@ struct transactionFileInfo_s {
|
|||
/*@owned@*/ gid_t * fgids;
|
||||
int magic;
|
||||
#define TFIMAGIC 0x09697923
|
||||
/*@owned@*/ FSM_t fsm;
|
||||
|
||||
/* these are for TR_ADDED packages */
|
||||
/*@dependent@*/ struct availablePackage * ap;
|
||||
/*@owned@*/ struct sharedFileInfo * replaced;
|
||||
|
@ -147,14 +167,12 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/**
|
||||
* Save/restore files from transaction element by renaming on file system.
|
||||
* @param ts transaction set
|
||||
* @param fi transaction element file info
|
||||
* @param dir save or restore?
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dirstashPackage(const rpmTransactionSet ts, const TFI_t fi,
|
||||
rollbackDir dir);
|
||||
/*@only@*/ /*@null@*/ FSM_t newFSM(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
/*@null@*/ FSM_t freeFSM(/*@only@*/ /*@null@*/ FSM_t fsm);
|
||||
|
||||
/**
|
||||
* Load data from header into transaction file element info.
|
||||
|
@ -192,13 +210,43 @@ void freeFi(TFI_t fi)
|
|||
*/
|
||||
/*@observer@*/ const char *const fileActionString(fileAction a);
|
||||
|
||||
/**
|
||||
* Perform package install/remove actions for s single file.
|
||||
* @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 install/remove actions.
|
||||
* @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);
|
||||
int pkgActions(const rpmTransactionSet ts, TFI_t fi, fileStage a);
|
||||
|
||||
/**
|
||||
* @return 0 on success
|
||||
*/
|
||||
int fsmSetup(FSM_t fsm, const rpmTransactionSet ts, const TFI_t fi, FD_t cfd,
|
||||
const char ** failedFile);
|
||||
|
||||
/**
|
||||
* @return 0 on success
|
||||
*/
|
||||
int fsmTeardown(FSM_t fsm);
|
||||
|
||||
/**
|
||||
* Archive extraction state machine.
|
||||
* @param fsm file state machine data
|
||||
* @param stage next stage
|
||||
* @return 0 on success
|
||||
*/
|
||||
int fsmStage(FSM_t fsm, fileStage stage);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1687,26 +1687,6 @@ int rpmRunTransactions( rpmTransactionSet ts,
|
|||
return ts->orderCount;
|
||||
}
|
||||
|
||||
/* ===============================================
|
||||
* Save removed files before upgrading.
|
||||
*/
|
||||
if (ts->transFlags & (RPMTRANS_FLAG_DIRSTASH | RPMTRANS_FLAG_REPACKAGE)) {
|
||||
i = -2;
|
||||
for (oc = 0, fi = flList; oc < ts->orderCount; oc++, fi++) {
|
||||
switch (ts->order[oc].type) {
|
||||
case TR_ADDED:
|
||||
i = ts->order[oc].u.addedIndex;
|
||||
break;
|
||||
case TR_REMOVED:
|
||||
if (ts->order[oc].u.removed.dependsOnIndex != i)
|
||||
break;
|
||||
if (ts->transFlags & RPMTRANS_FLAG_DIRSTASH)
|
||||
dirstashPackage(ts, fi, ROLLBACK_SAVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ===============================================
|
||||
* Install and remove packages.
|
||||
*/
|
||||
|
|
|
@ -73,7 +73,7 @@ int removeBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
|
|||
(void)ts->notify(h, RPMCALLBACK_UNINST_START, fi->fc, fi->fc,
|
||||
pkgKey, ts->notifyData);
|
||||
|
||||
rc = pkgActions(ts, fi);
|
||||
rc = pkgActions(ts, fi, FSM_COMMIT);
|
||||
|
||||
if (ts->notify)
|
||||
(void)ts->notify(h, RPMCALLBACK_UNINST_STOP, 0, fi->fc,
|
||||
|
|
612
po/rpm.pot
612
po/rpm.pot
File diff suppressed because it is too large
Load Diff
2
rpm.c
2
rpm.c
|
@ -55,6 +55,7 @@ static int badReloc;
|
|||
static int dirStash;
|
||||
static int excldocs;
|
||||
static int force;
|
||||
extern int _fsm_debug;
|
||||
extern int _ftp_debug;
|
||||
static int showHash;
|
||||
static int help;
|
||||
|
@ -122,6 +123,7 @@ static struct poptOption optionsTable[] = {
|
|||
{ "excludepath", '\0', POPT_ARG_STRING, 0, GETOPT_EXCLUDEPATH, NULL, NULL},
|
||||
{ "force", '\0', 0, &force, 0, NULL, NULL},
|
||||
{ "freshen", 'F', 0, 0, 'F', NULL, NULL},
|
||||
{ "fsmdebug", '\0', POPT_ARG_VAL, &_fsm_debug, -1, NULL, NULL},
|
||||
{ "ftpdebug", '\0', POPT_ARG_VAL, &_ftp_debug, -1, NULL, NULL},
|
||||
{ "hash", 'h', 0, &showHash, 0, NULL, NULL},
|
||||
{ "help", '\0', 0, &help, 0, NULL, NULL},
|
||||
|
|
Loading…
Reference in New Issue