summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/fsm.c148
-rw-r--r--lib/fsm.h3
-rw-r--r--lib/psm.c4
3 files changed, 88 insertions, 67 deletions
diff --git a/lib/fsm.c b/lib/fsm.c
index 16658dc3e..de1712f6b 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -1801,71 +1801,6 @@ static int fsmStage(FSM_t fsm, fileStage stage)
switch (stage) {
case FSM_UNKNOWN:
break;
- case FSM_PKGERASE:
- while (1) {
- /* Clean fsm, free'ing memory. */
- rc = fsmInit(fsm);
-
- /* Exit on end-of-payload. */
- if (rc == CPIOERR_HDR_TRAILER) {
- rc = 0;
- break;
- }
-
- /* Remove erased files. */
- if (!fsm->postpone && fsm->action == FA_ERASE) {
- rpmte te = fsmGetTe(fsm);
- if (S_ISDIR(st->st_mode)) {
- rc = fsmRmdir(fsm->path);
- if (!rc) break;
- switch (rc) {
- case CPIOERR_ENOENT: /* XXX rmdir("/") linux 2.2.x kernel hack */
- case CPIOERR_ENOTEMPTY:
- /* XXX make sure that build side permits %missingok on directories. */
- if (fsm->fflags & RPMFILE_MISSINGOK)
- break;
-
- /* XXX common error message. */
- rpmlog(
- (strict_erasures ? RPMLOG_ERR : RPMLOG_DEBUG),
- _("%s rmdir of %s failed: Directory not empty\n"),
- rpmteTypeString(te), fsm->path);
- break;
- default:
- rpmlog(
- (strict_erasures ? RPMLOG_ERR : RPMLOG_DEBUG),
- _("%s rmdir of %s failed: %s\n"),
- rpmteTypeString(te), fsm->path, strerror(errno));
- break;
- }
- } else {
- rc = fsmUnlink(fsm->path, fsm->mapFlags);
- if (!rc) break;
- switch (rc) {
- case CPIOERR_ENOENT:
- if (fsm->fflags & RPMFILE_MISSINGOK)
- break;
- default:
- rpmlog(
- (strict_erasures ? RPMLOG_ERR : RPMLOG_DEBUG),
- _("%s unlink of %s failed: %s\n"),
- rpmteTypeString(te), fsm->path, strerror(errno));
- break;
- }
- }
- }
- /* XXX Failure to remove is not (yet) cause for failure. */
- if (!strict_erasures) rc = 0;
-
- if (rc) break;
-
- /* Notify on success. */
- /* On erase we're iterating backwards, fixup for progress */
- rpm_loff_t amount = (fsm->ix >= 0) ?
- rpmfiFC(fsmGetFi(fsm)) - fsm->ix : 0;
- rpmpsmNotify(fsm->psm, RPMCALLBACK_UNINST_PROGRESS, amount);
- }
- break;
case FSM_PKGBUILD:
while (1) {
@@ -2159,3 +2094,86 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfi fi, FD_t cfd,
return (rc ? rc : ec);
}
+
+int rpmPackageFilesRemove(rpmts ts, rpmte te, rpmfi fi,
+ rpmpsm psm, char ** failedFile)
+{
+ struct fsm_s fsm_;
+ FSM_t fsm = &fsm_;
+ int rc = 0;
+ int ec = 0;
+
+ memset(fsm, 0, sizeof(*fsm));
+ rc = fsmSetup(fsm, FSM_PKGERASE, ts, te, fi, NULL, psm, NULL, failedFile);
+
+ while (!rc) {
+ /* Clean fsm, free'ing memory. */
+ rc = fsmInit(fsm);
+
+ /* Exit on end-of-payload. */
+ if (rc == CPIOERR_HDR_TRAILER) {
+ rc = 0;
+ break;
+ }
+
+ /* Remove erased files. */
+ if (!fsm->postpone && fsm->action == FA_ERASE) {
+ rpmte te = fsmGetTe(fsm);
+ if (S_ISDIR(fsm->sb.st_mode)) {
+ rc = fsmRmdir(fsm->path);
+ if (!rc) break;
+ switch (rc) {
+ case CPIOERR_ENOENT: /* XXX rmdir("/") linux 2.2.x kernel hack */
+ case CPIOERR_ENOTEMPTY:
+ /* XXX make sure that build side permits %missingok on directories. */
+ if (fsm->fflags & RPMFILE_MISSINGOK)
+ break;
+
+ /* XXX common error message. */
+ rpmlog(
+ (strict_erasures ? RPMLOG_ERR : RPMLOG_DEBUG),
+ _("%s rmdir of %s failed: Directory not empty\n"),
+ rpmteTypeString(te), fsm->path);
+ break;
+ default:
+ rpmlog(
+ (strict_erasures ? RPMLOG_ERR : RPMLOG_DEBUG),
+ _("%s rmdir of %s failed: %s\n"),
+ rpmteTypeString(te), fsm->path, strerror(errno));
+ break;
+ }
+ } else {
+ rc = fsmUnlink(fsm->path, fsm->mapFlags);
+ if (!rc) break;
+ switch (rc) {
+ case CPIOERR_ENOENT:
+ if (fsm->fflags & RPMFILE_MISSINGOK)
+ break;
+ default:
+ rpmlog(
+ (strict_erasures ? RPMLOG_ERR : RPMLOG_DEBUG),
+ _("%s unlink of %s failed: %s\n"),
+ rpmteTypeString(te), fsm->path, strerror(errno));
+ break;
+ }
+ }
+ }
+ /* XXX Failure to remove is not (yet) cause for failure. */
+ if (!strict_erasures) rc = 0;
+
+ if (rc) break;
+
+ /* Notify on success. */
+ /* On erase we're iterating backwards, fixup for progress */
+ rpm_loff_t amount = (fsm->ix >= 0) ?
+ rpmfiFC(fsmGetFi(fsm)) - fsm->ix : 0;
+ rpmpsmNotify(fsm->psm, RPMCALLBACK_UNINST_PROGRESS, amount);
+ }
+
+ ec = fsmTeardown(fsm);
+
+ /* Return the relevant code: if setup failed, teardown doesn't matter */
+ return (rc ? rc : ec);
+}
+
+
diff --git a/lib/fsm.h b/lib/fsm.h
index 0156523db..756835f60 100644
--- a/lib/fsm.h
+++ b/lib/fsm.h
@@ -122,6 +122,9 @@ int rpmfsmRun(fileStage goal, rpmts ts, rpmte te, rpmfi fi, FD_t cfd,
int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfi fi, FD_t cfd,
rpmpsm psm, char ** failedFile);
+int rpmPackageFilesRemove(rpmts ts, rpmte te, rpmfi fi,
+ rpmpsm psm, char ** failedFile);
+
RPM_GNUC_INTERNAL
void rpmpsmNotify(rpmpsm psm, int what, rpm_loff_t amount);
#ifdef __cplusplus
diff --git a/lib/psm.c b/lib/psm.c
index 161c77e13..8f5376d49 100644
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -853,8 +853,8 @@ static rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
/* XXX should't we log errors from here? */
if (rpmfiFC(fi) > 0 && !(rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB)) {
- rc = rpmfsmRun(FSM_PKGERASE, psm->ts, psm->te, psm->fi,
- NULL, psm, NULL, &psm->failedFile);
+ rc = rpmPackageFilesRemove(psm->ts, psm->te, psm->fi,
+ psm, &psm->failedFile);
}
/* XXX make sure progress reaches 100% */