- Similar in spirit to PSM blackbox treatment in
commit
df9cdb1321ada8e3b120771f91a2eefab4ac2ad5, except that
technically fsm guts are still wide-open in fsm.h due to cpio
"needing" them (yuck).
- Allows getting rid of dumb a**-backwards things like rpmfiFSM()
which is just not needed, fsm is a relatively short-lived entity
inside psm and build, nobody else needs to bother with it except
for the returned results.
- Figure out the cpio map flags in fsmSetup() where it logically belongs,
we have all the necessary info available there.
- Get rid of newFSM() and freeFSM(), we can just as well place the
fsm on stack, merge the necessary cleanup bits from freeFSM()
into fsmTeardown()
- Supposedly no functional changes, knock wood.
rpmfs fs = NULL;
char *failedFile = NULL;
FD_t cfd;
- rpmRC rc = RPMRC_OK;
- int i;
+ int i, fsmrc;
(void) Fflush(fdo);
cfd = Fdopen(fdDup(Fileno(fdo)), fmodeMacro);
rpmfsSetAction(fs, i, FA_COPYOUT);
}
- if (fsmSetup(rpmfiFSM(fi), FSM_PKGBUILD, ts, te, fi, cfd, NULL,
- &csa->cpioArchiveSize, &failedFile))
- rc = RPMRC_FAIL;
-
- (void) Fclose(cfd);
+ fsmrc = rpmfsmRun(FSM_PKGBUILD, ts, te, fi, cfd, NULL,
+ &csa->cpioArchiveSize, &failedFile);
- if (fsmTeardown(rpmfiFSM(fi)) || rc == RPMRC_FAIL) {
+ if (fsmrc) {
if (failedFile)
rpmlog(RPMLOG_ERR, _("create archive failed on file %s\n"), failedFile);
else
rpmlog(RPMLOG_ERR, _("create archive failed\n"));
- rc = RPMRC_FAIL;
}
free(failedFile);
+ Fclose(cfd);
rpmtsFree(ts);
- return rc;
+ return (fsmrc == 0) ? RPMRC_OK : RPMRC_FAIL;
}
static rpmRC addFileToTag(rpmSpec spec, const char * file,
return NULL;
}
-FSM_t newFSM(cpioMapFlags mapflags)
-{
- FSM_t fsm = xcalloc(1, sizeof(*fsm));
- fsm->mapFlags = mapflags;
- return fsm;
-}
-
-FSM_t freeFSM(FSM_t fsm)
-{
- if (fsm) {
- fsm->path = _free(fsm->path);
- while ((fsm->li = fsm->links) != NULL) {
- fsm->links = fsm->li->next;
- fsm->li->next = NULL;
- fsm->li = freeHardLink(fsm->li);
- }
- fsm->dnlx = _free(fsm->dnlx);
- fsm->ldn = _free(fsm->ldn);
- fsm->iter = mapFreeIterator(fsm->iter);
- _free(fsm);
- }
- return NULL;
-}
-
/* forward declaration*/
static int fsmMkdirs(FSM_t fsm);
return rc;
}
-int fsmSetup(FSM_t fsm, fileStage goal,
+static int fsmSetup(FSM_t fsm, fileStage goal,
rpmts ts, rpmte te, rpmfi fi, FD_t cfd, rpmpsm psm,
rpm_loff_t * archiveSize, char ** failedFile)
{
int rc, ec = 0;
+ int isSrc = rpmteIsSource(te);
fsm->goal = goal;
if (cfd != NULL) {
fsm->digestalgo = rpmfiDigestAlgo(fi);
fsm->psm = psm;
+ fsm->mapFlags = CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
+ if (goal == FSM_PKGBUILD) {
+ fsm->mapFlags |= CPIO_MAP_TYPE;
+ if (isSrc) {
+ fsm->mapFlags |= CPIO_FOLLOW_SYMLINKS;
+ }
+ } else {
+ if (!isSrc) {
+ fsm->mapFlags |= CPIO_SBIT_CHECK;
+ }
+ }
+
fsm->archiveSize = archiveSize;
if (fsm->archiveSize)
*fsm->archiveSize = 0;
return ec;
}
-int fsmTeardown(FSM_t fsm)
+static int fsmTeardown(FSM_t fsm)
{
int rc = fsm->rc;
fsm->cfd = NULL;
}
fsm->failedFile = NULL;
+
+ fsm->path = _free(fsm->path);
+ while ((fsm->li = fsm->links) != NULL) {
+ fsm->links = fsm->li->next;
+ fsm->li->next = NULL;
+ fsm->li = freeHardLink(fsm->li);
+ }
+ fsm->dnlx = _free(fsm->dnlx);
+ fsm->ldn = _free(fsm->ldn);
return rc;
}
default: return "???";
}
}
+
+int rpmfsmRun(fileStage goal, rpmts ts, rpmte te, rpmfi fi, FD_t cfd,
+ rpmpsm psm, rpm_loff_t * archiveSize, char ** failedFile)
+{
+ struct fsm_s fsm;
+ int sc = 0;
+ int ec = 0;
+
+ memset(&fsm, 0, sizeof(fsm));
+ sc = fsmSetup(&fsm, goal, ts, te, fi, cfd, psm, archiveSize, failedFile);
+ ec = fsmTeardown(&fsm);
+
+ /* Return the relevant code: if setup failed, teardown doesn't matter */
+ return (sc ? sc : ec);
+}
#endif
/**
- * Create file state machine instance.
- * @param mapflags CPIO map flags to use
- * @return file state machine
- */
-RPM_GNUC_INTERNAL
-FSM_t newFSM(cpioMapFlags mapflags);
-
-/**
- * Destroy file state machine instance.
- * @param fsm file state machine
- * @return always NULL
- */
-RPM_GNUC_INTERNAL
-FSM_t freeFSM(FSM_t fsm);
-
-/**
- * Load external data into file state machine.
- * @param fsm file state machine
+ * Execute a file state machine goal
* @param goal
* @param ts transaction set
* @param fi transaction element file info
* @retval failedFile pointer to first file name that failed (malloced)
* @return 0 on success
*/
-int fsmSetup(FSM_t fsm, fileStage goal,
- rpmts ts,
- rpmte te,
- rpmfi fi,
- FD_t cfd,
- rpmpsm psm,
- rpm_loff_t * archiveSize,
- char ** failedFile);
-
-/**
- * Clean file state machine.
- * @param fsm file state machine
- * @return 0 on success
- */
-int fsmTeardown(FSM_t fsm);
+int rpmfsmRun(fileStage goal, rpmts ts, rpmte te, rpmfi fi, FD_t cfd,
+ rpmpsm psm, rpm_loff_t * archiveSize, char ** failedFile);
/**
* File state machine driver.
static int runFsm(rpmpsm psm, FD_t payload)
{
- int sc, ec;
+ int rc;
- sc = fsmSetup(rpmfiFSM(psm->fi),
- (psm->goal == PKG_INSTALL) ? FSM_PKGINSTALL : FSM_PKGERASE,
+ rc = rpmfsmRun((psm->goal == PKG_INSTALL) ? FSM_PKGINSTALL : FSM_PKGERASE,
psm->ts, psm->te, psm->fi, payload, psm,
NULL, &psm->failedFile);
if (psm->goal == PKG_INSTALL) {
rpmswAdd(rpmtsOp(psm->ts, RPMTS_OP_DIGEST),
fdOp(payload, FDSTAT_DIGEST));
}
- ec = fsmTeardown(rpmfiFSM(psm->fi));
- /* Return the relevant code: if setup failed, teardown doesn't matter */
- return (sc ? sc : ec);
+ return rc;
}
/*
#include "lib/rpmfi_internal.h"
#include "lib/rpmte_internal.h" /* relocations */
#include "lib/cpio.h" /* XXX CPIO_FOO */
-#include "lib/fsm.h" /* XXX newFSM() */
#include "debug.h"
}
}
- fi->fsm = freeFSM(fi->fsm);
-
fi->fn = _free(fi->fn);
fi->apath = _free(fi->apath);
fpLookupList(fpc, fi->dnl, fi->bnl, fi->dil, fi->fc, fi->fps);
}
-FSM_t rpmfiFSM(rpmfi fi)
-{
- if (fi != NULL && fi->fsm == NULL) {
- cpioMapFlags mapflags;
- /* Figure out mapflags:
- * - path, mode, uid and gid are used by everything
- * - all binary packages get SBIT_CHECK set
- * - if archive size is not known, we're only building this package,
- * different rules apply
- */
- mapflags = CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
- if (fi->fiflags & RPMFI_ISBUILD) {
- mapflags |= CPIO_MAP_TYPE;
- if (fi->fiflags & RPMFI_ISSOURCE) mapflags |= CPIO_FOLLOW_SYMLINKS;
- } else {
- if (!(fi->fiflags & RPMFI_ISSOURCE)) mapflags |= CPIO_SBIT_CHECK;
- }
- fi->fsm = newFSM(mapflags);
- }
- return (fi != NULL) ? fi->fsm : NULL;
-}
-
/*
* Generate iterator accessors function wrappers, these do nothing but
* call the corresponding rpmfiFooIndex(fi, fi->[ij])
#include <rpm/header.h>
#include <rpm/rpmfi.h>
-#include "lib/fsm.h" /* for FSM_t */
#include "lib/fprint.h"
/*
char * fn; /*!< File name buffer. */
char ** apath;
- FSM_t fsm; /*!< File state machine data. */
rpm_off_t * replacedSizes; /*!< (TR_ADDED) */
int magic;
int nrefs; /*!< Reference count. */
RPM_GNUC_INTERNAL
void rpmfiFpLookup(rpmfi fi, fingerPrintCache fpc);
-/* XXX can't be internal as build code needs this */
-FSM_t rpmfiFSM(rpmfi fi);
-
#ifdef __cplusplus
}
#endif