Kill FSM: Make FSM_PKGINSTALL a function

This commit is contained in:
Florian Festi 2012-03-29 15:44:40 +02:00
parent 800c60ea10
commit bd60c4285f
3 changed files with 143 additions and 118 deletions

254
lib/fsm.c
View File

@ -1801,122 +1801,6 @@ static int fsmStage(FSM_t fsm, fileStage stage)
switch (stage) {
case FSM_UNKNOWN:
break;
case FSM_PKGINSTALL:
while (1) {
/* Clean fsm, free'ing memory. Read next archive header. */
rc = fsmInit(fsm);
/* Exit on end-of-payload. */
if (rc == CPIOERR_HDR_TRAILER) {
rc = 0;
break;
}
/* Exit on error. */
if (rc) {
fsm->postpone = 1;
break;
}
if (!fsm->postpone) {
if (S_ISREG(st->st_mode)) {
char * path = fsm->path;
if (fsm->osuffix)
fsm->path = fsmFsPath(fsm, st, NULL, NULL);
rc = fsmVerify(fsm);
if (rc == 0 && fsm->osuffix) {
char * spath = fsmFsPath(fsm, st, NULL, fsm->osuffix);
rc = fsmRename(fsm->path, spath, fsm->mapFlags);
if (!rc)
rpmlog(RPMLOG_WARNING, _("%s saved as %s\n"),
fsm->path, spath);
free(spath);
}
if (fsm->osuffix)
free(fsm->path);
fsm->path = path;
if (!(rc == CPIOERR_ENOENT)) return rc;
rc = expandRegular(fsm);
} else if (S_ISDIR(st->st_mode)) {
rc = fsmVerify(fsm);
if (rc == CPIOERR_ENOENT) {
mode_t mode = st->st_mode;
mode &= ~07777;
mode |= 00700;
rc = fsmMkdir(fsm->path, mode);
}
} else if (S_ISLNK(st->st_mode)) {
if ((st->st_size + 1) > fsm->bufsize) {
rc = CPIOERR_HDR_SIZE;
} else if (rpmcpioRead(fsm->archive, fsm->buf, st->st_size) != st->st_size) {
rc = CPIOERR_READ_FAILED;
} else {
fsm->buf[st->st_size] = '\0';
/* fsmVerify() assumes link target in fsm->buf */
rc = fsmVerify(fsm);
if (rc == CPIOERR_ENOENT) {
rc = fsmSymlink(fsm->buf, fsm->path);
}
}
} else if (S_ISFIFO(st->st_mode)) {
/* This mimics cpio S_ISSOCK() behavior but probably isnt' right */
rc = fsmVerify(fsm);
if (rc == CPIOERR_ENOENT) {
rc = fsmMkfifo(fsm->path, 0000);
}
} else if (S_ISCHR(st->st_mode) ||
S_ISBLK(st->st_mode) ||
S_ISSOCK(st->st_mode))
{
rc = fsmVerify(fsm);
if (rc == CPIOERR_ENOENT) {
rc = fsmMknod(fsm->path, fsm->sb.st_mode, fsm->sb.st_rdev);
}
} else {
/* XXX Special case /dev/log, which shouldn't be packaged anyways */
if (!IS_DEV_LOG(fsm->path))
rc = CPIOERR_UNKNOWN_FILETYPE;
}
if (S_ISREG(st->st_mode) && st->st_nlink > 1) {
fsm->li->createdPath = fsm->li->linkIndex;
rc = fsmMakeLinks(fsm);
}
}
if (rc) {
if (!fsm->postpone) {
/* XXX only erase if temp fn w suffix is in use */
if (fsm->suffix) {
if (S_ISDIR(st->st_mode)) {
(void) fsmRmdir(fsm->path);
} else {
(void) fsmUnlink(fsm->path, fsm->mapFlags);
}
}
errno = saveerrno;
if (fsm->failedFile && *fsm->failedFile == NULL)
*fsm->failedFile = xstrdup(fsm->path);
}
break;
}
/* Notify on success. */
rpmpsmNotify(fsm->psm, RPMCALLBACK_INST_PROGRESS, rpmcpioTell(fsm->archive));
if (!fsm->postpone) {
rc = ((S_ISREG(st->st_mode) && st->st_nlink > 1)
? fsmCommitLinks(fsm) : fsmCommit(fsm));
}
if (rc) {
break;
}
}
break;
case FSM_PKGERASE:
while (1) {
/* Clean fsm, free'ing memory. */
@ -2137,3 +2021,141 @@ int rpmfsmRun(fileStage goal, rpmts ts, rpmte te, rpmfi fi, FD_t cfd,
/* Return the relevant code: if setup or the fsm failed, teardown doesn't matter */
return (rc ? rc : ec);
}
int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfi fi, FD_t cfd,
rpmpsm psm, char ** failedFile)
{
struct fsm_s fsm_;
FSM_t fsm = &fsm_;
struct stat * st = &fsm->sb;
int saveerrno = errno;
int rc = 0;
int ec = 0;
memset(fsm, 0, sizeof(*fsm));
rc = fsmSetup(fsm, FSM_PKGINSTALL, ts, te, fi, cfd, psm, NULL, failedFile);
while (!rc) {
/* Clean fsm, free'ing memory. Read next archive header. */
rc = fsmInit(fsm);
/* Exit on end-of-payload. */
if (rc == CPIOERR_HDR_TRAILER) {
rc = 0;
break;
}
/* Exit on error. */
if (rc) {
fsm->postpone = 1;
break;
}
if (!fsm->postpone) {
if (S_ISREG(st->st_mode)) {
char * path = fsm->path;
if (fsm->osuffix)
fsm->path = fsmFsPath(fsm, st, NULL, NULL);
rc = fsmVerify(fsm);
if (rc == 0 && fsm->osuffix) {
char * spath = fsmFsPath(fsm, st, NULL, fsm->osuffix);
rc = fsmRename(fsm->path, spath, fsm->mapFlags);
if (!rc)
rpmlog(RPMLOG_WARNING, _("%s saved as %s\n"),
fsm->path, spath);
free(spath);
}
if (fsm->osuffix)
free(fsm->path);
fsm->path = path;
if (!(rc == CPIOERR_ENOENT)) return rc;
rc = expandRegular(fsm);
} else if (S_ISDIR(st->st_mode)) {
rc = fsmVerify(fsm);
if (rc == CPIOERR_ENOENT) {
mode_t mode = st->st_mode;
mode &= ~07777;
mode |= 00700;
rc = fsmMkdir(fsm->path, mode);
}
} else if (S_ISLNK(st->st_mode)) {
if ((st->st_size + 1) > fsm->bufsize) {
rc = CPIOERR_HDR_SIZE;
} else if (rpmcpioRead(fsm->archive, fsm->buf, st->st_size) != st->st_size) {
rc = CPIOERR_READ_FAILED;
} else {
fsm->buf[st->st_size] = '\0';
/* fsmVerify() assumes link target in fsm->buf */
rc = fsmVerify(fsm);
if (rc == CPIOERR_ENOENT) {
rc = fsmSymlink(fsm->buf, fsm->path);
}
}
} else if (S_ISFIFO(st->st_mode)) {
/* This mimics cpio S_ISSOCK() behavior but probably isnt' right */
rc = fsmVerify(fsm);
if (rc == CPIOERR_ENOENT) {
rc = fsmMkfifo(fsm->path, 0000);
}
} else if (S_ISCHR(st->st_mode) ||
S_ISBLK(st->st_mode) ||
S_ISSOCK(st->st_mode))
{
rc = fsmVerify(fsm);
if (rc == CPIOERR_ENOENT) {
rc = fsmMknod(fsm->path, fsm->sb.st_mode, fsm->sb.st_rdev);
}
} else {
/* XXX Special case /dev/log, which shouldn't be packaged anyways */
if (!IS_DEV_LOG(fsm->path))
rc = CPIOERR_UNKNOWN_FILETYPE;
}
if (S_ISREG(st->st_mode) && st->st_nlink > 1) {
fsm->li->createdPath = fsm->li->linkIndex;
rc = fsmMakeLinks(fsm);
}
}
if (rc) {
if (!fsm->postpone) {
/* XXX only erase if temp fn w suffix is in use */
if (fsm->suffix) {
if (S_ISDIR(st->st_mode)) {
(void) fsmRmdir(fsm->path);
} else {
(void) fsmUnlink(fsm->path, fsm->mapFlags);
}
}
errno = saveerrno;
if (fsm->failedFile && *fsm->failedFile == NULL)
*fsm->failedFile = xstrdup(fsm->path);
}
break;
}
/* Notify on success. */
rpmpsmNotify(fsm->psm, RPMCALLBACK_INST_PROGRESS, rpmcpioTell(fsm->archive));
if (!fsm->postpone) {
rc = ((S_ISREG(st->st_mode) && st->st_nlink > 1)
? fsmCommitLinks(fsm) : fsmCommit(fsm));
}
if (rc) {
break;
}
}
ec = fsmTeardown(fsm);
/* Return the relevant code: if setup failed, teardown doesn't matter */
return (rc ? rc : ec);
}

View File

@ -119,6 +119,9 @@ extern "C" {
int rpmfsmRun(fileStage goal, rpmts ts, rpmte te, rpmfi fi, FD_t cfd,
rpmpsm psm, rpm_loff_t * archiveSize, char ** failedFile);
int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfi fi, FD_t cfd,
rpmpsm psm, char ** failedFile);
RPM_GNUC_INTERNAL
void rpmpsmNotify(rpmpsm psm, int what, rpm_loff_t amount);
#ifdef __cplusplus

View File

@ -816,8 +816,8 @@ static rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
break;
}
fsmrc = rpmfsmRun(FSM_PKGINSTALL, psm->ts, psm->te, psm->fi,
payload, psm, NULL, &psm->failedFile);
fsmrc = rpmPackageFilesInstall(psm->ts, psm->te, psm->fi,
payload, psm, &psm->failedFile);
rpmswAdd(rpmtsOp(psm->ts, RPMTS_OP_UNCOMPRESS),
fdOp(payload, FDSTAT_READ));