(katzj@linuxpower.org) (#17672).
- handle possible db3 dependency on -lpthread more gracefully.
- fix: more (possible) xstrdup side effects.
- - detect rdonly linux file systems.
+ - detect (still need to test) rdonly linux file systems.
- check available inodes as well as blocks on mounted file systems.
+ - pass rpmTransactionSet, not elements, to installBinaryPackage et al.
3.0.6 -> 4.0
- use DIRNAMES/BASENAMES/DIRINDICES not FILENAMES in packages and db.
CPIOERR_INTERNAL = (23 )
};
-#define CPIO_MAP_PATH (1 << 0)
-#define CPIO_MAP_MODE (1 << 1)
-#define CPIO_MAP_UID (1 << 2)
-#define CPIO_MAP_GID (1 << 3)
-#define CPIO_FOLLOW_SYMLINKS (1 << 4) /* only for building */
-#define CPIO_MULTILIB (1 << 31) /* internal, only for building */
+/** \ingroup payload
+ */
+enum cpioMapFlags {
+ CPIO_MAP_PATH = (1 << 0),
+ CPIO_MAP_MODE = (1 << 1),
+ CPIO_MAP_UID = (1 << 2),
+ CPIO_MAP_GID = (1 << 3),
+ CPIO_FOLLOW_SYMLINKS = (1 << 4), /* only for building */
+ CPIO_MULTILIB = (1 << 31) /* internal, only for building */
+};
/** \ingroup payload
* Defines a single file to be included in a cpio payload.
/** \ingroup payload
* The RPM internal equivalent of the command line "cpio -i".
+ *
* If no mappings are passed, this installs everything! If one is passed
* it should be sorted according to cpioFileMapCmp() and only files included
* in the map are installed. Files are installed relative to the current
* This is designed to be qsort/bsearch compatible.
* @param a 1st map
* @param b 2nd map
- * return result of comparison
+ * @return result of comparison
*/
int cpioFileMapCmp(const void * a, const void * b) /*@*/;
/** \ingroup payload
* Return fornmatted error message on payload handling failure.
+ * @param error code
+ * @return formatted error string
*/
/*@observer@*/ const char *cpioStrerror(int rc) /*@*/;
struct availableIndex index; /*!< Set of available items. */
int size;
int alloced;
- int numDirs; /*! No. of directories. */
+ int numDirs; /*!< No. of directories. */
/*@owned@*/ struct dirInfo * dirs; /*!< Set of directories. */
};
* The set of packages to be installed/removed atomically.
*/
struct rpmTransactionSet_s {
+ rpmtransFlags transFlags; /*!< Bit(s) to control operation. */
+ rpmCallbackFunction notify; /*!< Callback function. */
+ rpmCallbackData notifyData; /*!< Callback data. */
+ rpmProblemSet probs; /*!< Current problems in transaction. */
+ rpmprobFilterFlags ignoreSet; /*!< Bits to filter current problems. */
/*@owned@*/ /*@null@*/ rpmdb rpmdb; /*!< Database handle. */
/*@only@*/ int * removedPackages; /*!< Set of packages being removed. */
int numRemovedPackages; /*!< No. removed rpmdb instances. */
#include "cpio.h"
#include "install.h"
+#include "depends.h"
#include "misc.h"
#include <assert.h>
* @param h header
* @return 0 on success, 1 on bad magic, 2 on error
*/
-static int installSources(Header h, const char * rootdir, FD_t fd,
+static int installSources(Header h, const char * rootDir, FD_t fd,
const char ** specFilePtr,
rpmCallbackFunction notify, rpmCallbackData notifyData)
{
rpmMessage(RPMMESS_DEBUG, _("installing a source package\n"));
- realSourceDir = rpmGenPath(rootdir, "%{_sourcedir}", "");
+ realSourceDir = rpmGenPath(rootDir, "%{_sourcedir}", "");
if ((rc = Stat(realSourceDir, &st)) < 0) {
int ut = urlPath(realSourceDir, NULL);
switch (ut) {
}
rpmMessage(RPMMESS_DEBUG, _("sources in: %s\n"), realSourceDir);
- realSpecDir = rpmGenPath(rootdir, "%{_specdir}", "");
+ realSpecDir = rpmGenPath(rootDir, "%{_specdir}", "");
if ((rc = Stat(realSpecDir, &st)) < 0) {
int ut = urlPath(realSpecDir, NULL);
switch (ut) {
return "???";
}
-int rpmInstallSourcePackage(const char * rootdir, FD_t fd,
+int rpmInstallSourcePackage(const char * rootDir, FD_t fd,
const char ** specFile,
rpmCallbackFunction notify, rpmCallbackData notifyData,
char ** cookie)
rpmInstallLoadMacros(h);
- rc = installSources(h, rootdir, fd, specFile, notify, notifyData);
+ rc = installSources(h, rootDir, fd, specFile, notify, notifyData);
if (h)
headerFree(h);
return rc;
}
-int installBinaryPackage(const char * rootdir, rpmdb db, FD_t fd, Header h,
- rpmtransFlags transFlags,
- rpmCallbackFunction notify, rpmCallbackData notifyData,
+int installBinaryPackage(const rpmTransactionSet ts, FD_t fd, Header h,
const void * pkgKey, enum fileActions * actions,
- struct sharedFileInfo * sharedList, FD_t scriptFd)
+ struct sharedFileInfo * sharedList)
{
+ rpmtransFlags transFlags = ts->transFlags;
int rc;
const char * name, * version, * release;
int fileCount = 0;
rpmMessage(RPMMESS_DEBUG, _("package: %s-%s-%s files test = %d\n"),
name, version, release, transFlags & RPMTRANS_FLAG_TEST);
- if ((scriptArg = rpmdbCountPackages(db, name)) < 0) {
+ if ((scriptArg = rpmdbCountPackages(ts->rpmdb, name)) < 0) {
rc = 2;
goto exit;
}
scriptArg += 1;
{ rpmdbMatchIterator mi;
- mi = rpmdbInitIterator(db, RPMTAG_NAME, name, 0);
+ mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, name, 0);
rpmdbSetIteratorVersion(mi, version);
rpmdbSetIteratorRelease(mi, release);
while ((oldH = rpmdbNextIterator(mi))) {
rpmdbFreeIterator(mi);
}
- if (rootdir) {
+ if (ts->rootDir) {
/* this loads all of the name services libraries, in case we
don't have access to them in the chroot() */
(void)getpwnam("root");
}
chdir("/");
- /*@-unrecog@*/ chroot(rootdir); /*@=unrecog@*/
+ /*@-unrecog@*/ chroot(ts->rootDir); /*@=unrecog@*/
}
if (!(transFlags & RPMTRANS_FLAG_JUSTDB) && headerIsEntry(h, RPMTAG_BASENAMES)) {
}
rpmMessage(RPMMESS_DEBUG, _("running preinstall script (if any)\n"));
- if (runInstScript("/", h, RPMTAG_PREIN, RPMTAG_PREINPROG, scriptArg,
- transFlags & RPMTRANS_FLAG_NOSCRIPTS, scriptFd)) {
+
+ /* XXX Save chroot around runInstScript() call. */
+ { const char * rootDir = ts->rootDir;
+ ts->rootDir = "/";
+ rc = runInstScript(ts, h, RPMTAG_PREIN, RPMTAG_PREINPROG, scriptArg,
+ transFlags & RPMTRANS_FLAG_NOSCRIPTS);
+ ts->rootDir = rootDir;
+ }
+
+ if (rc) {
rc = 2;
goto exit;
}
(void **) &archiveSizePtr, &count))
archiveSizePtr = NULL;
- if (notify) {
- (void)notify(h, RPMCALLBACK_INST_START, 0, 0,
- pkgKey, notifyData);
+ if (ts->notify) {
+ (void)ts->notify(h, RPMCALLBACK_INST_START, 0, 0,
+ pkgKey, ts->notifyData);
}
/* the file pointer for fd is pointing at the cpio archive */
- if (installArchive(fd, files, fileCount, notify, notifyData, pkgKey,
+ if (installArchive(fd, files, fileCount, ts->notify, ts->notifyData, pkgKey,
h, NULL, archiveSizePtr ? *archiveSizePtr : 0)) {
rc = 2;
goto exit;
headerAddEntry(h, RPMTAG_INSTALLTIME, RPM_INT32_TYPE, &installTime, 1);
}
- if (rootdir) {
+ if (ts->rootDir) {
/*@-unrecog@*/ chroot("."); /*@=unrecog@*/
chdir(currDir);
currDir = NULL;
/* if this package has already been installed, remove it from the database
before adding the new one */
if (otherOffset)
- rpmdbRemove(db, otherOffset);
+ rpmdbRemove(ts->rpmdb, otherOffset);
if (transFlags & RPMTRANS_FLAG_MULTILIB) {
uint_32 multiLib, * newMultiLib, * p;
mergeFiles(oldH, h, actions);
}
- if (rpmdbAdd(db, h)) {
+ if (rpmdbAdd(ts->rpmdb, h)) {
rc = 2;
goto exit;
}
rpmMessage(RPMMESS_DEBUG, _("running postinstall scripts (if any)\n"));
- if (runInstScript(rootdir, h, RPMTAG_POSTIN, RPMTAG_POSTINPROG, scriptArg,
- (transFlags & RPMTRANS_FLAG_NOSCRIPTS), scriptFd)) {
+ if (runInstScript(ts, h, RPMTAG_POSTIN, RPMTAG_POSTINPROG, scriptArg,
+ (transFlags & RPMTRANS_FLAG_NOSCRIPTS))) {
rc = 2;
goto exit;
}
if (!(transFlags & RPMTRANS_FLAG_NOTRIGGERS)) {
/* Run triggers this package sets off */
- if (runTriggers(rootdir, db, RPMSENSE_TRIGGERIN, h, 0, scriptFd)) {
+ if (runTriggers(ts, RPMSENSE_TRIGGERIN, h, 0)) {
rc = 2;
goto exit;
}
- /* Run triggers in this package which are set off by other things in
- the database. */
- if (runImmedTriggers(rootdir, db, RPMSENSE_TRIGGERIN, h, 0, scriptFd)) {
+ /*
+ * Run triggers in this package which are set off by other packages in
+ * the database.
+ */
+ if (runImmedTriggers(ts, RPMSENSE_TRIGGERIN, h, 0)) {
rc = 2;
goto exit;
}
}
if (sharedList)
- markReplacedFiles(db, sharedList);
+ markReplacedFiles(ts->rpmdb, sharedList);
rc = 0;
exit:
- if (rootdir && currDir) {
+ if (ts->rootDir && currDir) {
/*@-unrecog@*/ chroot("."); /*@=unrecog@*/
chdir(currDir);
}
/**
*/
-enum fileActions { FA_UNKNOWN = 0, FA_CREATE, FA_BACKUP, FA_SAVE, FA_SKIP,
- FA_ALTNAME, FA_REMOVE, FA_SKIPNSTATE, FA_SKIPNETSHARED,
- FA_SKIPMULTILIB };
+enum fileActions {
+ FA_UNKNOWN = 0,
+ FA_CREATE,
+ FA_BACKUP,
+ FA_SAVE,
+ FA_SKIP,
+ FA_ALTNAME,
+ FA_REMOVE,
+ FA_SKIPNSTATE,
+ FA_SKIPNETSHARED,
+ FA_SKIPMULTILIB
+};
/**
*/
-enum fileTypes { XDIR, BDEV, CDEV, SOCK, PIPE, REG, LINK } ;
+enum fileTypes {
+ XDIR,
+ BDEV,
+ CDEV,
+ SOCK,
+ PIPE,
+ REG,
+ LINK
+};
#ifdef __cplusplus
extern "C" {
#endif
/**
- * @param prefix path to top of install tree
+ * @param ts transaction set
* @param h header
* @param scriptTag
* @param progTag
* @param arg
* @param norunScripts
- * @param err stderr file handle
*/
-int runInstScript(const char * prefix, Header h, int scriptTag, int progTag,
- int arg, int norunScripts, FD_t err);
+int runInstScript(const rpmTransactionSet ts, Header h,
+ int scriptTag, int progTag, int arg, int norunScripts);
/**
* Run trigger scripts in the database that are fired by header.
- * @param root path to top of install tree
- * @param rpmdb rpm database
- * @param sense
+ * @param ts transaction set
+ * @param sense @todo Document.
* @param h header
- * @param countCorrection
- * @param scriptFd
+ * @param countCorrection @todo Document.
+ * @return 0 on success, 1 on error
*/
-int runTriggers(const char * root, rpmdb rpmdb, int sense, Header h,
- int countCorrection, FD_t scriptFd);
+int runTriggers(const rpmTransactionSet ts, int sense, Header h,
+ int countCorrection);
/**
* Run triggers from header that are fired by the database.
- * @param root path to top of install tree
- * @param rpmdb rpm database
+ * @param ts transaction set
* @param sense @todo Document.
* @param h header
* @param countCorrection @todo Document.
- * @param scriptFd @todo Document.
- * @return @todo Document.
+ * @return 0 on success, 1 on error
*/
-int runImmedTriggers(const char * root, rpmdb rpmdb, int sense, Header h,
- int countCorrection, FD_t scriptFd);
+int runImmedTriggers(const rpmTransactionSet ts, int sense, Header h,
+ int countCorrection);
/**
* Return formatted string representation of file disposition.
/**
* Install binary package (from transaction set).
- * @param rootdir path to top of install tree
- * @param rpmdb rpm database
+ * @param ts transaction set
* @param fd package file handle
* @param h package header
- * @param transFlags transaction flags
- * @param notify progress callback
- * @param notifyData progress callback private data
* @param pkgKey package private data
* @param actions array of file dispositions
* @param sharedList header instances of packages that share files
- * @param scriptFd @todo Document.
* @return 0 on success, 1 on bad magic, 2 on error
*/
-int installBinaryPackage(const char * rootdir, rpmdb rpmdb, FD_t fd, Header h,
- rpmtransFlags transFlags,
- rpmCallbackFunction notify, rpmCallbackData notifyData,
+int installBinaryPackage(const rpmTransactionSet ts, FD_t fd, Header h,
const void * pkgKey, enum fileActions * actions,
- struct sharedFileInfo * sharedList, FD_t scriptFd);
+ struct sharedFileInfo * sharedList);
/**
* Erase binary package (from transaction set).
- * @param rootdir path to top of install tree
- * @param rpmdb rpm database
- * @param fd package file handle
+ * @param ts transaction set
* @param offset header instance in rpm database
* @param h package header
- * @param transFlags transaction flags
- * @param notify progress callback
- * @param notifyData progress callback private data
* @param pkgKey package private data
* @param actions array of file dispositions
- * @param scriptFd @todo Document.
* @return
*/
-int removeBinaryPackage(const char * rootdir, rpmdb rpmdb, unsigned int offset,
- Header h, rpmtransFlags flags,
- rpmCallbackFunction notify, rpmCallbackData notifyData,
- const void * pkgKey, enum fileActions * actions,
- FD_t scriptFd);
+int removeBinaryPackage(const rpmTransactionSet ts, unsigned int offset,
+ Header h, const void * pkgKey, enum fileActions * actions);
#ifdef __cplusplus
}
int numConflicts);
/** \ingroup rpmtrans
- * Bit(s) to control rpmCheckSig() operation.
+ * Bit(s) to control rpmRunTransaction() operation.
*/
typedef enum rpmtransFlags_e {
RPMTRANS_FLAG_TEST = (1 << 0), /*!< from --test */
/** \ingroup rpmcli
* Verify file attributes and MD5 sum.
+ * @todo python bindings prevent this from being static.
* @param root path to top of install tree
* @param h header
* @param filenum index of file in header file info arrays
/*@out@*/ int * result, int omitMask);
/** \ingroup rpmcli
- * Return exit code from running verify script in header.
- * @param root path to top of install tree
- * @param h header
- * @param err file handle to use for stderr
- * @return 0 on success
- */
-int rpmVerifyScript(const char * root, Header h, FD_t err);
-
-/** \ingroup rpmcli
* The command line argument will be used to retrieve header(s) ...
*/
typedef enum rpmQVSources_e {
if (languages) freeSplitString((char **)languages);
}
-#define NOTIFY(_x) if (notify) (void) notify _x
+#define NOTIFY(_ts, _al) if ((_ts)->notify) (void) (_ts)->notify _al
int rpmRunTransactions( rpmTransactionSet ts,
rpmCallbackFunction notify, rpmCallbackData notifyData,
int i, j;
int rc, ourrc = 0;
struct availablePackage * alp;
- rpmProblemSet probs;
Header * hdrs;
int totalFileCount = 0;
hashTable ht;
/* FIXME: what if the same package is included in ts twice? */
+ ts->transFlags = transFlags;
+ ts->notify = notify;
+ ts->notifyData = notifyData;
+ ts->ignoreSet = ignoreSet;
if (ts->currDir)
xfree(ts->currDir);
ts->currDir = currentDirectory();
/* Get available space on mounted file systems. */
- if (!(ignoreSet & RPMPROB_FILTER_DISKSPACE) &&
+ if (!(ts->ignoreSet & RPMPROB_FILTER_DISKSPACE) &&
!rpmGetFilesystemList(&filesystems, &filesystemCount)) {
struct stat sb;
if (di) di[i].bsize = 0;
}
- probs = *newProbs = psCreate();
+ *newProbs = ts->probs = psCreate();
hdrs = alloca(sizeof(*hdrs) * ts->addedPackages.size);
/* ===============================================
(alp - ts->addedPackages.list) < ts->addedPackages.size;
alp++)
{
- if (!archOkay(alp->h) && !(ignoreSet & RPMPROB_FILTER_IGNOREARCH))
- psAppend(probs, RPMPROB_BADARCH, alp->key, alp->h, NULL, NULL, 0);
+ if (!archOkay(alp->h) && !(ts->ignoreSet & RPMPROB_FILTER_IGNOREARCH))
+ psAppend(ts->probs, RPMPROB_BADARCH, alp->key, alp->h, NULL, NULL, 0);
- if (!osOkay(alp->h) && !(ignoreSet & RPMPROB_FILTER_IGNOREOS))
- psAppend(probs, RPMPROB_BADOS, alp->key, alp->h, NULL, NULL, 0);
+ if (!osOkay(alp->h) && !(ts->ignoreSet & RPMPROB_FILTER_IGNOREOS))
+ psAppend(ts->probs, RPMPROB_BADOS, alp->key, alp->h, NULL, NULL, 0);
- if (!(ignoreSet & RPMPROB_FILTER_OLDPACKAGE)) {
+ if (!(ts->ignoreSet & RPMPROB_FILTER_OLDPACKAGE)) {
rpmdbMatchIterator mi;
Header oldH;
mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, alp->name, 0);
while ((oldH = rpmdbNextIterator(mi)) != NULL)
- ensureOlder(ts->rpmdb, alp->h, oldH, probs, alp->key);
+ ensureOlder(ts->rpmdb, alp->h, oldH, ts->probs, alp->key);
rpmdbFreeIterator(mi);
}
/* XXX multilib should not display "already installed" problems */
- if (!(ignoreSet & RPMPROB_FILTER_REPLACEPKG) && !alp->multiLib) {
+ if (!(ts->ignoreSet & RPMPROB_FILTER_REPLACEPKG) && !alp->multiLib) {
rpmdbMatchIterator mi;
mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, alp->name, 0);
rpmdbSetIteratorVersion(mi, alp->version);
rpmdbSetIteratorRelease(mi, alp->release);
while (rpmdbNextIterator(mi) != NULL) {
- psAppend(probs, RPMPROB_PKG_INSTALLED, alp->key, alp->h,
+ psAppend(ts->probs, RPMPROB_PKG_INSTALLED, alp->key, alp->h,
NULL, NULL, 0);
break;
}
/* Allocate file actions (and initialize to RPMFILE_STATE_NORMAL) */
fi->actions = xcalloc(fi->fc, sizeof(*fi->actions));
- hdrs[i] = relocateFileList(alp, probs, alp->h, fi->actions,
- ignoreSet & RPMPROB_FILTER_FORCERELOCATE);
+ hdrs[i] = relocateFileList(alp, ts->probs, alp->h, fi->actions,
+ ts->ignoreSet & RPMPROB_FILTER_FORCERELOCATE);
fi->h = headerLink(hdrs[i]);
fi->type = TR_ADDED;
fi->ap = alp;
fi->replacedSizes = xcalloc(fi->fc, sizeof(*fi->replacedSizes));
/* Skip netshared paths, not our i18n files, and excluded docs */
- skipFiles(fi, transFlags & RPMTRANS_FLAG_NODOCS);
+ skipFiles(fi, ts->transFlags & RPMTRANS_FLAG_NODOCS);
break;
}
}
}
- NOTIFY((NULL, RPMCALLBACK_TRANS_START, 6, flEntries, NULL, notifyData));
+ NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_START, 6, flEntries,
+ NULL, ts->notifyData));
/* ===============================================
* Compute file disposition for each package in transaction set.
dbiIndexSet * matches;
int knownBad;
- NOTIFY((NULL, RPMCALLBACK_TRANS_PROGRESS, (fi - flList), flEntries,
- NULL, notifyData));
+ NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_PROGRESS, (fi - flList), flEntries,
+ NULL, ts->notifyData));
/* Extract file info for all files in this package from the database. */
matches = xcalloc(sizeof(*matches), fi->fc);
switch (fi->type) {
case TR_ADDED:
handleInstInstalledFiles(fi, ts->rpmdb, shared, nexti - i,
- !(beingRemoved || (ignoreSet & RPMPROB_FILTER_REPLACEOLDFILES)),
- probs, transFlags);
+ !(beingRemoved || (ts->ignoreSet & RPMPROB_FILTER_REPLACEOLDFILES)),
+ ts->probs, ts->transFlags);
break;
case TR_REMOVED:
if (!beingRemoved)
/* Update disk space needs on each partition for this package. */
handleOverlappedFiles(fi, ht,
- (ignoreSet & RPMPROB_FILTER_REPLACENEWFILES) ? NULL : probs, di);
+ (ts->ignoreSet & RPMPROB_FILTER_REPLACENEWFILES) ? NULL : ts->probs, di);
/* Check added package has sufficient space on each partition used. */
switch (fi->type) {
break;
for (i = 0; i < filesystemCount; i++) {
if (adj_fs_blocks(di[i].bneeded) > di[i].bavail)
- psAppend(probs, RPMPROB_DISKSPACE, fi->ap->key, fi->ap->h,
+ psAppend(ts->probs, RPMPROB_DISKSPACE, fi->ap->key, fi->ap->h,
filesystems[i], NULL,
(adj_fs_blocks(di[i].bneeded) - di[i].bavail) * di[i].bsize);
if (adj_fs_blocks(di[i].ineeded) > di[i].iavail)
- psAppend(probs, RPMPROB_DISKNODES, fi->ap->key, fi->ap->h,
+ psAppend(ts->probs, RPMPROB_DISKNODES, fi->ap->key, fi->ap->h,
filesystems[i], NULL,
(adj_fs_blocks(di[i].ineeded) - di[i].iavail));
}
}
}
- NOTIFY((NULL, RPMCALLBACK_TRANS_STOP, 6, flEntries, NULL, notifyData));
+ NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_STOP, 6, flEntries,
+ NULL, ts->notifyData));
chroot(".");
chdir(ts->currDir);
/* ===============================================
* If unfiltered problems exist, free memory and return.
*/
- if ((transFlags & RPMTRANS_FLAG_BUILD_PROBS) ||
- (probs->numProblems && (!okProbs || psTrim(okProbs, probs)))) {
- *newProbs = probs;
+ if ((ts->transFlags & RPMTRANS_FLAG_BUILD_PROBS) ||
+ (ts->probs->numProblems && (!okProbs || psTrim(okProbs, ts->probs)))) {
+ *newProbs = ts->probs;
for (alp = ts->addedPackages.list, fi = flList;
(alp - ts->addedPackages.list) < ts->addedPackages.size;
i = ts->order[oc].u.addedIndex;
if ((fd = alp->fd) == 0) {
- fd = notify(fi->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
- alp->key, notifyData);
+ fd = ts->notify(fi->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
+ alp->key, ts->notifyData);
if (fd) {
Header h;
headerFree(hdrs[i]);
rc = rpmReadPackageHeader(fd, &h, NULL, NULL, NULL);
if (rc) {
- (void)notify(fi->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
- alp->key, notifyData);
+ (void)ts->notify(fi->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
+ alp->key, ts->notifyData);
ourrc++;
fd = NULL;
} else {
- hdrs[i] = relocateFileList(alp, probs, h, NULL, 1);
+ hdrs[i] = relocateFileList(alp, ts->probs, h, NULL, 1);
headerFree(h);
}
}
if (fd) {
if (alp->multiLib)
- transFlags |= RPMTRANS_FLAG_MULTILIB;
+ ts->transFlags |= RPMTRANS_FLAG_MULTILIB;
- if (installBinaryPackage(ts->rootDir, ts->rpmdb, fd,
- hdrs[i], transFlags, notify,
- notifyData, alp->key, fi->actions,
- fi->fc ? fi->replaced : NULL,
- ts->scriptFd)) {
+ if (installBinaryPackage(ts, fd, hdrs[i],
+ alp->key, fi->actions,
+ fi->fc ? fi->replaced : NULL)) {
ourrc++;
lastFailed = i;
}
headerFree(hdrs[i]);
if (alp->fd == NULL && fd)
- (void)notify(fi->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0, alp->key,
- notifyData);
+ (void)ts->notify(fi->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
+ alp->key, ts->notifyData);
break;
case TR_REMOVED:
{ unsigned int offset = fi->record;
rpmdbFreeIterator(mi);
}
- if (removeBinaryPackage(ts->rootDir, ts->rpmdb, offset, dbh,
- transFlags,
- notify, notifyData, dbh, fi->actions,
- ts->scriptFd))
+ if (removeBinaryPackage(ts, offset, dbh, dbh, fi->actions))
ourrc++;
headerFree(dbh);
return 0;
}
-int removeBinaryPackage(const char * rootdir, rpmdb rpmdb, unsigned int offset,
- Header h, rpmtransFlags transFlags,
- rpmCallbackFunction notify, rpmCallbackData notifyData,
- const void * pkgKey, enum fileActions * actions,
- FD_t scriptFd)
+int removeBinaryPackage(const rpmTransactionSet ts, unsigned int offset,
+ Header h, const void * pkgKey, enum fileActions * actions)
{
+ rpmtransFlags transFlags = ts->transFlags;
const char * name, * version, * release;
const char ** baseNames;
int scriptArg;
* 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.
*/
- if ((scriptArg = rpmdbCountPackages(rpmdb, name)) < 0)
+ if ((scriptArg = rpmdbCountPackages(ts->rpmdb, name)) < 0)
return 1;
scriptArg -= 1;
if (!(transFlags & RPMTRANS_FLAG_NOTRIGGERS)) {
/* run triggers from this package which are keyed on installed
packages */
- if (runImmedTriggers(rootdir, rpmdb, RPMSENSE_TRIGGERUN, h, -1, scriptFd))
+ if (runImmedTriggers(ts, RPMSENSE_TRIGGERUN, h, -1))
return 2;
/* run triggers which are set off by the removal of this package */
- if (runTriggers(rootdir, rpmdb, RPMSENSE_TRIGGERUN, h, -1, scriptFd))
+ if (runTriggers(ts, RPMSENSE_TRIGGERUN, h, -1))
return 1;
}
if (!(transFlags & RPMTRANS_FLAG_TEST)) {
- rc = runInstScript(rootdir, h, RPMTAG_PREUN, RPMTAG_PREUNPROG, scriptArg,
- (transFlags & RPMTRANS_FLAG_NOSCRIPTS), scriptFd);
+ rc = runInstScript(ts, h, RPMTAG_PREUN, RPMTAG_PREUNPROG, scriptArg,
+ (transFlags & RPMTRANS_FLAG_NOSCRIPTS));
if (rc)
return 1;
}
int type;
char * fileName;
int fnmaxlen;
- int rdlen = (rootdir && !(rootdir[0] == '/' && rootdir[1] == '\0'))
- ? strlen(rootdir) : 0;
+ int rdlen = (ts->rootDir && !(ts->rootDir[0] == '/' && ts->rootDir[1] == '\0'))
+ ? strlen(ts->rootDir) : 0;
headerGetEntry(h, RPMTAG_DIRINDEXES, NULL, (void **) &dirIndexes,
NULL);
headerGetEntry(h, RPMTAG_DIRNAMES, NULL, (void **) &dirNames,
NULL);
- /* Get buffer for largest possible rootdir + dirname + filename. */
+ /* Get buffer for largest possible rootDir + dirname + filename. */
fnmaxlen = 0;
for (i = 0; i < fileCount; i++) {
size_t fnlen;
fileName = alloca(fnmaxlen);
if (rdlen) {
- strcpy(fileName, rootdir);
+ strcpy(fileName, ts->rootDir);
(void)rpmCleanPath(fileName);
rdlen = strlen(fileName);
} else
headerGetEntry(h, RPMTAG_FILEMODES, &type, (void **) &fileModesList,
&fileCount);
- if (notify) {
- (void)notify(h, RPMCALLBACK_UNINST_START, fileCount, fileCount,
- pkgKey, notifyData);
+ if (ts->notify) {
+ (void)ts->notify(h, RPMCALLBACK_UNINST_START, fileCount, fileCount,
+ pkgKey, ts->notifyData);
}
/* Traverse filelist backwards to help insure that rmdir() will work. */
fileName, fileActionString(actions[i]));
if (!(transFlags & RPMTRANS_FLAG_TEST)) {
- if (notify) {
- (void)notify(h, RPMCALLBACK_UNINST_PROGRESS,
- i, actions[i], fileName, notifyData);
+ if (ts->notify) {
+ (void)ts->notify(h, RPMCALLBACK_UNINST_PROGRESS,
+ i, actions[i], fileName, ts->notifyData);
}
removeFile(fileName, fileFlagsList[i], fileModesList[i],
actions[i]);
}
}
- if (notify) {
- (void)notify(h, RPMCALLBACK_UNINST_STOP, 0, fileCount,
- pkgKey, notifyData);
+ if (ts->notify) {
+ (void)ts->notify(h, RPMCALLBACK_UNINST_STOP, 0, fileCount,
+ pkgKey, ts->notifyData);
}
free(baseNames);
if (!(transFlags & RPMTRANS_FLAG_TEST)) {
rpmMessage(RPMMESS_DEBUG, _("running postuninstall script (if any)\n"));
- rc = runInstScript(rootdir, h, RPMTAG_POSTUN, RPMTAG_POSTUNPROG,
- scriptArg, (transFlags & RPMTRANS_FLAG_NOSCRIPTS), scriptFd);
+ rc = runInstScript(ts, h, RPMTAG_POSTUN, RPMTAG_POSTUNPROG,
+ scriptArg, (transFlags & RPMTRANS_FLAG_NOSCRIPTS));
/* XXX postun failures are not cause for erasure failure. */
}
if (!(transFlags & RPMTRANS_FLAG_NOTRIGGERS)) {
/* Run postun triggers which are set off by this package's removal. */
- rc = runTriggers(rootdir, rpmdb, RPMSENSE_TRIGGERPOSTUN, h,
- -1, scriptFd);
+ rc = runTriggers(ts, RPMSENSE_TRIGGERPOSTUN, h, -1);
if (rc)
return 2;
}
if (!(transFlags & RPMTRANS_FLAG_TEST))
- rpmdbRemove(rpmdb, offset);
+ rpmdbRemove(ts->rpmdb, offset);
return 0;
}
/**
+ * @param ts transaction set
* @param h header
- * @param root path to top of install tree
* @param progArgc
* @param progArgv
* @param script
* @param arg1
* @param arg2
- * @param errfd
* @return
*/
-static int runScript(Header h, const char * root, int progArgc, const char ** progArgv,
- const char * script, int arg1, int arg2, FD_t errfd)
+static int runScript(const rpmTransactionSet ts, Header h,
+ int progArgc, const char ** progArgv,
+ const char * script, int arg1, int arg2)
{
const char ** argv = NULL;
int argc = 0;
if (script) {
FD_t fd;
- if (makeTempFile(root, &fn, &fd)) {
+ if (makeTempFile(ts->rootDir, &fn, &fd)) {
if (freePrefixes) free(prefixes);
return 1;
}
(void)Fwrite(script, sizeof(script[0]), strlen(script), fd);
Fclose(fd);
- argv[argc++] = fn + strlen(root);
+ argv[argc++] = fn + strlen(ts->rootDir);
if (arg1 >= 0) {
char *av = alloca(20);
sprintf(av, "%d", arg1);
argv[argc] = NULL;
- if (errfd != NULL) {
+ if (ts->scriptFd != NULL) {
if (rpmIsVerbose()) {
- out = fdDup(Fileno(errfd));
+ out = fdDup(Fileno(ts->scriptFd));
} else {
out = Fopen("/dev/null", "w.fdio");
if (Ferror(out)) {
- out = fdDup(Fileno(errfd));
+ out = fdDup(Fileno(ts->scriptFd));
}
}
} else {
dup2(pipes[0], STDIN_FILENO);
close(pipes[0]);
- if (errfd != NULL) {
- if (Fileno(errfd) != STDERR_FILENO)
- dup2(Fileno(errfd), STDERR_FILENO);
+ 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(errfd)) {
+ if (Fileno(out) > STDERR_FILENO && Fileno(out) != Fileno(ts->scriptFd)) {
Fclose (out);
}
- if (Fileno(errfd) > STDERR_FILENO) {
- Fclose (errfd);
+ if (Fileno(ts->scriptFd) > STDERR_FILENO) {
+ Fclose (ts->scriptFd);
}
}
}
}
- switch(urlIsURL(root)) {
+ switch(urlIsURL(ts->rootDir)) {
case URL_IS_PATH:
- root += sizeof("file://") - 1;
- root = strchr(root, '/');
+ ts->rootDir += sizeof("file://") - 1;
+ ts->rootDir = strchr(ts->rootDir, '/');
/*@fallthrough@*/
case URL_IS_UNKNOWN:
- if (strcmp(root, "/"))
- /*@-unrecog@*/ chroot(root); /*@=unrecog@*/
+ if (strcmp(ts->rootDir, "/"))
+ /*@-unrecog@*/ chroot(ts->rootDir); /*@=unrecog@*/
chdir("/");
execv(argv[0], (char *const *)argv);
break;
return 0;
}
-int runInstScript(const char * root, Header h, int scriptTag, int progTag,
- int arg, int norunScripts, FD_t err)
+int runInstScript(const rpmTransactionSet ts, Header h,
+ int scriptTag, int progTag, int arg, int norunScripts)
{
void ** programArgv;
int programArgc;
argv = (const char **) programArgv;
}
- rc = runScript(h, root, programArgc, argv, script, arg, -1, err);
+ rc = runScript(ts, h, programArgc, argv, script, arg, -1);
if (programArgv && programType == RPM_STRING_ARRAY_TYPE) free(programArgv);
return rc;
}
/**
- * @param root path to top of install tree
- * @param db rpm database
+ * @param ts transaction set
* @param sense
* @param sourceH
* @param triggeredH
* @param arg1correction
* @param arg2
* @param triggersAlreadyRun
- * @param scriptFd
* @return
*/
-static int handleOneTrigger(const char * root, rpmdb db, int sense,
+static int handleOneTrigger(const rpmTransactionSet ts, int sense,
Header sourceH, Header triggeredH,
int arg1correction, int arg2,
- char * triggersAlreadyRun, FD_t scriptFd)
+ char * triggersAlreadyRun)
{
const char ** triggerNames;
const char ** triggerEVR;
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
+ /* 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]);
{ int arg1;
int index;
- if ((arg1 = rpmdbCountPackages(db, triggerPackageName)) < 0) {
+ 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(triggeredH, root, 1, triggerProgs + index,
+ rc = runScript(ts, triggeredH, 1, triggerProgs + index,
triggerScripts[index],
- arg1, arg2, scriptFd);
+ arg1, arg2);
if (triggersAlreadyRun) triggersAlreadyRun[index] = 1;
}
}
return rc;
}
-int runTriggers(const char * root, rpmdb db, int sense, Header h,
- int countCorrection, FD_t scriptFd)
+int runTriggers(const rpmTransactionSet ts, int sense, Header h,
+ int countCorrection)
{
const char * name;
int numPackage;
headerNVR(h, &name, NULL, NULL);
- numPackage = rpmdbCountPackages(db, name);
+ numPackage = rpmdbCountPackages(ts->rpmdb, name);
if (numPackage < 0)
return 1;
{ Header triggeredH;
rpmdbMatchIterator mi;
- mi = rpmdbInitIterator(db, RPMTAG_TRIGGERNAME, name, 0);
+ mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_TRIGGERNAME, name, 0);
while((triggeredH = rpmdbNextIterator(mi)) != NULL) {
- rc |= handleOneTrigger(root, db, sense, h, triggeredH, 0, numPackage,
- NULL, scriptFd);
+ rc |= handleOneTrigger(ts, sense, h, triggeredH, 0, numPackage,
+ NULL);
}
rpmdbFreeIterator(mi);
return rc;
}
-int runImmedTriggers(const char * root, rpmdb db, int sense, Header h,
- int countCorrection, FD_t scriptFd)
+int runImmedTriggers(const rpmTransactionSet ts, int sense, Header h,
+ int countCorrection)
{
const char ** triggerNames;
int numTriggers;
if (triggersRun[triggerIndices[i]]) continue;
- mi = rpmdbInitIterator(db, RPMTAG_NAME, name, 0);
+ mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, name, 0);
while((sourceH = rpmdbNextIterator(mi)) != NULL) {
- rc |= handleOneTrigger(root, db, sense, sourceH, h,
+ rc |= handleOneTrigger(ts, sense, sourceH, h,
countCorrection, rpmdbGetIteratorCount(mi),
- triggersRun, scriptFd);
+ triggersRun);
}
rpmdbFreeIterator(mi);
#include "md5.h"
#include "misc.h"
+#include "depends.h"
#include "install.h"
#include "build/rpmbuild.h"
};
/* ======================================================================== */
-/* XXX static */
-/** */
int rpmVerifyFile(const char * prefix, Header h, int filenum, int * result,
int omitMask)
{
return 0;
}
-/* XXX static */
-/** */
-int rpmVerifyScript(const char * root, Header h, FD_t err)
+/**
+ * Return exit code from running verify script in header.
+ * @param rootDir path to top of install tree
+ * @param rpmdb rpm database
+ * @param h header
+ * @param scriptFd file handle to use for stderr
+ * @return 0 on success
+ */
+static int rpmVerifyScript(const char * rootDir, rpmdb rpmdb, Header h, FD_t scriptFd)
{
- return runInstScript(root, h, RPMTAG_VERIFYSCRIPT, RPMTAG_VERIFYSCRIPTPROG,
- 0, 0, err);
+ rpmTransactionSet ts = rpmtransCreateSet(rpmdb, rootDir);
+ int rc;
+
+ ts->scriptFd = scriptFd;
+ rc = runInstScript(ts, h, RPMTAG_VERIFYSCRIPT, RPMTAG_VERIFYSCRIPTPROG,
+ 0, 0);
+ rpmtransFree(ts);
+ return rc;
}
/* ======================================================================== */
int showVerifyPackage(QVA_t *qva, rpmdb rpmdb, Header h)
{
- int ec, rc;
FD_t fdo;
- ec = 0;
+ int ec = 0;
+ int rc;
+
if ((qva->qva_flags & VERIFY_DEPS) &&
(rc = verifyDependencies(rpmdb, h)) != 0)
ec = rc;
ec = rc;;
fdo = fdDup(STDOUT_FILENO);
if ((qva->qva_flags & VERIFY_SCRIPT) &&
- (rc = rpmVerifyScript(qva->qva_prefix, h, fdo)) != 0)
+ (rc = rpmVerifyScript(qva->qva_prefix, rpmdb, h, fdo)) != 0)
ec = rc;
Fclose(fdo);
return ec;
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2000-10-20 12:42-0400\n"
+"POT-Creation-Date: 2000-10-20 15:49-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgid "grabData() RPM_STRING_TYPE count must be 1.\n"
msgstr ""
-#: lib/header.c:275 lib/header.c:745 lib/install.c:351
+#: lib/header.c:275 lib/header.c:745 lib/install.c:352
#, c-format
msgid "Data type %d not supported\n"
msgstr ""
msgid "(unknown type)"
msgstr ""
-#: lib/install.c:168 lib/uninstall.c:193
+#: lib/install.c:169 lib/uninstall.c:191
#, c-format
msgid " file: %s action: %s\n"
msgstr ""
-#: lib/install.c:189
+#: lib/install.c:190
#, c-format
msgid "user %s does not exist - using root"
msgstr ""
-#: lib/install.c:197
+#: lib/install.c:198
#, c-format
msgid "group %s does not exist - using root"
msgstr ""
-#: lib/install.c:230
+#: lib/install.c:231
msgid "%%instchangelog value in macro file should be a number, but isn't"
msgstr ""
#. this would probably be a good place to check if disk space
#. was used up - if so, we should return a different error
#. XXX FIXME: Fclose with libio destroys errno
-#: lib/install.c:612
+#: lib/install.c:613
#, c-format
msgid "unpacking of archive failed%s%s: %s"
msgstr ""
-#: lib/install.c:613
+#: lib/install.c:614
msgid " on file "
msgstr ""
-#: lib/install.c:657
+#: lib/install.c:658
msgid "installing a source package\n"
msgstr ""
-#: lib/install.c:677
+#: lib/install.c:678
#, c-format
msgid "cannot create sourcedir %s"
msgstr ""
-#: lib/install.c:683 lib/install.c:713
+#: lib/install.c:684 lib/install.c:714
#, c-format
msgid "cannot write to %s"
msgstr ""
-#: lib/install.c:687
+#: lib/install.c:688
#, c-format
msgid "sources in: %s\n"
msgstr ""
-#: lib/install.c:707
+#: lib/install.c:708
#, c-format
msgid "cannot create specdir %s"
msgstr ""
-#: lib/install.c:717
+#: lib/install.c:718
#, c-format
msgid "spec file in: %s\n"
msgstr ""
-#: lib/install.c:749 lib/install.c:777
+#: lib/install.c:750 lib/install.c:778
msgid "source package contains no .spec file"
msgstr ""
-#: lib/install.c:795
+#: lib/install.c:796
#, c-format
msgid "renaming %s to %s\n"
msgstr ""
-#: lib/install.c:797 lib/install.c:1062 lib/uninstall.c:40
+#: lib/install.c:798 lib/install.c:1070 lib/uninstall.c:40
#, c-format
msgid "rename of %s to %s failed: %s"
msgstr ""
-#: lib/install.c:887
+#: lib/install.c:888
msgid "source package expected, binary found"
msgstr ""
msgid "running preinstall script (if any)\n"
msgstr ""
-#: lib/install.c:1022
+#: lib/install.c:1030
#, c-format
msgid "warning: %s created as %s"
msgstr ""
-#: lib/install.c:1058
+#: lib/install.c:1066
#, c-format
msgid "warning: %s saved as %s"
msgstr ""
-#: lib/install.c:1147
+#: lib/install.c:1155
msgid "running postinstall scripts (if any)\n"
msgstr ""
msgid "removal of %s failed: %s"
msgstr ""
-#: lib/uninstall.c:133
+#: lib/uninstall.c:131
#, c-format
msgid "will remove files test = %d\n"
msgstr ""
-#: lib/uninstall.c:217
+#: lib/uninstall.c:215
msgid "running postuninstall script (if any)\n"
msgstr ""
-#: lib/uninstall.c:419
+#: lib/uninstall.c:416
#, c-format
msgid "execution of %s-%s-%s script failed, exit status %d"
msgstr ""
-#: lib/verify.c:43
+#: lib/verify.c:44
msgid "don't verify files in package"
msgstr ""
-#: lib/verify.c:219
+#: lib/verify.c:218
msgid "package lacks both user name and id lists (this should never happen)"
msgstr ""
-#: lib/verify.c:237
+#: lib/verify.c:236
msgid "package lacks both group name and id lists (this should never happen)"
msgstr ""
-#: lib/verify.c:273
+#: lib/verify.c:284
#, c-format
msgid "missing %s\n"
msgstr ""
-#: lib/verify.c:335
+#: lib/verify.c:346
#, c-format
msgid "Unsatisfied dependencies for %s-%s-%s: "
msgstr ""