summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Doxyfile.in1
-rw-r--r--lib/Makefile.am3
-rw-r--r--lib/cpio.c234
-rw-r--r--lib/install.c458
-rw-r--r--lib/install.h68
-rw-r--r--lib/transaction.c82
-rw-r--r--po/POTFILES.in1
-rw-r--r--po/rpm.pot76
8 files changed, 465 insertions, 458 deletions
diff --git a/Doxyfile.in b/Doxyfile.in
index 9a8c76962..c9ec29b49 100644
--- a/Doxyfile.in
+++ b/Doxyfile.in
@@ -302,6 +302,7 @@ INPUT = \
./lib/poptQV.c \
./lib/problems.c \
./lib/query.c \
+ ./lib/rollback.c \
./lib/rpmchecksig.c \
./lib/rpmdb.c \
./lib/rpmdb.h \
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 3f9729f8f..a20594c75 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -25,7 +25,8 @@ librpm_la_SOURCES = \
cpio.c $(DBLIBSRCS) depends.c \
formats.c fprint.c fs.c hash.c header.c install.c \
md5.c md5sum.c misc.c package.c problems.c \
- poptBT.c poptQV.c query.c rpmchecksig.c rpmdb.c rpminstall.c \
+ poptBT.c poptQV.c query.c rollback.c \
+ rpmchecksig.c rpmdb.c rpminstall.c \
rpmlead.c rpmlibprov.c rpmrc.c scriptlet.c signature.c stringbuf.c \
tagName.c tagtable.c transaction.c uninstall.c verify.c
librpm_la_LDFLAGS = @libdb3@ @libdb2@ @libdb1@
diff --git a/lib/cpio.c b/lib/cpio.c
index 000d0848c..03c7e978c 100644
--- a/lib/cpio.c
+++ b/lib/cpio.c
@@ -24,7 +24,7 @@
struct hardLink {
struct hardLink * next;
const char ** files; /* nlink of these, used by install */
- int * fileMaps; /* used by build */
+ const struct cpioFileMapping ** fileMaps;
dev_t dev;
ino_t inode;
int nlink;
@@ -79,6 +79,75 @@ static void prtli(const char *msg, struct hardLink * li)
}
#endif
+static int mapFlags(const void * this, cpioMapFlags mask) {
+ const struct cpioFileMapping * map = this;
+ return (map->mapFlags & mask);
+}
+
+static const char * mapArchivePath(const void * this) {
+ const struct cpioFileMapping * map = this;
+ return map->archivePath;
+}
+
+static /*@only@*/ const char * mapFsPath(const void * this) {
+ const struct cpioFileMapping * map = this;
+ char * t = xmalloc( strlen(map->dirName) + strlen(map->baseName) + 1);
+ (void) stpcpy( stpcpy(t, map->dirName), map->baseName);
+ return t;
+}
+
+static mode_t mapFinalMode(const void * this) {
+ const struct cpioFileMapping * map = this;
+ return map->finalMode;
+}
+
+static uid_t mapFinalUid(const void * this) {
+ const struct cpioFileMapping * map = this;
+ return map->finalUid;
+}
+
+static gid_t mapFinalGid(const void * this) {
+ const struct cpioFileMapping * map = this;
+ return map->finalGid;
+}
+
+static const char * mapMd5sum(const void * this) {
+ const struct cpioFileMapping * map = this;
+ return map->md5sum;
+}
+
+struct mapi {
+ const struct cpioFileMapping * mappings;
+ int numMappings;
+ int i;
+};
+
+static void mapFreeIterator(/*@only@*/ void * mi) {
+ free(mi);
+}
+
+static void * mapInitIterator(const struct cpioFileMapping * mappings,
+ int numMappings)
+{
+ struct mapi * mapi = xmalloc(sizeof(*mapi));
+ mapi->mappings = mappings;
+ mapi->numMappings = numMappings;
+ mapi->i = 0;
+ return mapi;
+}
+
+static const struct cpioFileMapping * mapNextIterator(void * mi)
+{
+ struct mapi * mapi = mi;
+ const struct cpioFileMapping * map;
+
+ if (!(mapi->i < mapi->numMappings))
+ return NULL;
+ map = mapi->mappings + mapi->i;
+ mapi->i++;
+ return map;
+}
+
/**
* Read data from payload.
* @param cfd payload file handle
@@ -298,29 +367,23 @@ int cpioFileMapCmp(const void * a, const void * b)
static int createDirectory(const char * path, mode_t perms)
/*@modifies fileSystem @*/
{
- struct stat sb;
+ struct stat st;
- if (!lstat(path, &sb)) {
- int dounlink = 0; /* XXX eliminate, dounlink==1 on all paths */
- if (S_ISDIR(sb.st_mode)) {
+ if (!lstat(path, &st)) {
+ if (S_ISDIR(st.st_mode))
return 0;
- } else if (S_ISLNK(sb.st_mode)) {
- if (stat(path, &sb)) {
+ if (S_ISLNK(st.st_mode)) {
+ if (stat(path, &st)) {
if (errno != ENOENT)
return CPIOERR_STAT_FAILED;
- dounlink = 1;
} else {
- if (S_ISDIR(sb.st_mode))
+ if (S_ISDIR(st.st_mode))
return 0;
- dounlink = 1;
}
- } else {
- dounlink = 1;
}
- if (dounlink && unlink(path)) {
+ if (unlink(path))
return CPIOERR_UNLINK_FAILED;
- }
}
if (mkdir(path, 000))
@@ -728,7 +791,6 @@ int cpioInstallArchive(FD_t cfd, const struct cpioFileMapping * mappings,
{
struct cpioHeader ch, *hdr = &ch;
struct cpioFileMapping * map = NULL;
- struct cpioFileMapping needle;
struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
struct hardLink * links = NULL;
struct hardLink * li = NULL;
@@ -766,6 +828,7 @@ int cpioInstallArchive(FD_t cfd, const struct cpioFileMapping * mappings,
break;
if (mappings) {
+ struct cpioFileMapping needle;
needle.archivePath = hdr->path;
map = bsearch(&needle, mappings, numMappings, sizeof(needle),
cpioFileMapCmp);
@@ -775,20 +838,17 @@ int cpioInstallArchive(FD_t cfd, const struct cpioFileMapping * mappings,
eatBytes(cfd, st->st_size);
} else {
if (map) {
- if (map->mapFlags & CPIO_MAP_PATH) {
- char * t = xmalloc( strlen(map->dirName) +
- strlen(map->baseName) + 1);
- (void) stpcpy( stpcpy(t, map->dirName), map->baseName);
+ if (mapFlags(map, CPIO_MAP_PATH)) {
if (hdr->path) free((void *)hdr->path);
- hdr->path = t;
+ hdr->path = mapFsPath(map);
}
- if (map->mapFlags & CPIO_MAP_MODE)
- st->st_mode = map->finalMode;
- if (map->mapFlags & CPIO_MAP_UID)
- st->st_uid = map->finalUid;
- if (map->mapFlags & CPIO_MAP_GID)
- st->st_gid = map->finalGid;
+ if (mapFlags(map, CPIO_MAP_MODE))
+ st->st_mode = mapFinalMode(map);
+ if (mapFlags(map, CPIO_MAP_UID))
+ st->st_uid = mapFinalUid(map);
+ if (mapFlags(map, CPIO_MAP_GID))
+ st->st_gid = mapFinalGid(map);
}
/* This won't get hard linked symlinks right, but I can't seem
@@ -826,7 +886,8 @@ int cpioInstallArchive(FD_t cfd, const struct cpioFileMapping * mappings,
if (!rc) {
if (S_ISREG(st->st_mode))
- rc = expandRegular(cfd, hdr, map->md5sum, cb, cbData);
+ rc = expandRegular(cfd, hdr, mapMd5sum(map),
+ cb, cbData);
else if (S_ISDIR(st->st_mode))
rc = createDirectory(hdr->path, 000);
else if (S_ISLNK(st->st_mode))
@@ -918,41 +979,38 @@ static int writeFile(FD_t cfd, const struct stat * st,
int writeData)
/*@modifies cfd, *sizep @*/
{
+ const char * fsPath = mapFsPath(map);
+ const char * archivePath = !mapFlags(map, CPIO_MAP_PATH)
+ ? fsPath : mapArchivePath(map);
struct cpioCrcPhysicalHeader hdr;
- char * fsPath = alloca(strlen(map->dirName) + strlen(map->baseName) + 1);
char buf[8192], symbuf[2048];
dev_t num;
FD_t datafd;
size_t st_size = st->st_size; /* XXX hard links need size preserved */
- const char * archivePath;
mode_t st_mode = st->st_mode;
uid_t st_uid = st->st_uid;
gid_t st_gid = st->st_gid;
size_t size, amount = 0;
int rc;
- *fsPath = '\0';
- (void) stpcpy( stpcpy(fsPath, map->dirName), map->baseName);
-
- archivePath = (!(map->mapFlags & CPIO_MAP_PATH))
- ? fsPath : map->archivePath;
-
- if (map->mapFlags & CPIO_MAP_MODE)
- st_mode = (st_mode & S_IFMT) | map->finalMode;
- if (map->mapFlags & CPIO_MAP_UID)
- st_uid = map->finalUid;
- if (map->mapFlags & CPIO_MAP_GID)
- st_gid = map->finalGid;
+ if (mapFlags(map, CPIO_MAP_MODE))
+ st_mode = (st_mode & S_IFMT) | mapFinalMode(map);
+ if (mapFlags(map, CPIO_MAP_UID))
+ st_uid = mapFinalUid(map);
+ if (mapFlags(map, CPIO_MAP_GID))
+ st_gid = mapFinalGid(map);
if (!writeData || S_ISDIR(st_mode)) {
st_size = 0;
} else if (S_ISLNK(st_mode)) {
- /* While linux puts the size of a symlink in the st_size field,
- I don't think that's a specified standard */
-
+ /*
+ * While linux puts the size of a symlink in the st_size field,
+ * I don't think that's a specified standard.
+ */
amount = Readlink(fsPath, symbuf, sizeof(symbuf));
if (amount <= 0) {
- return CPIOERR_READLINK_FAILED;
+ rc = CPIOERR_READLINK_FAILED;
+ goto exit;
}
st_size = amount;
@@ -976,12 +1034,12 @@ static int writeFile(FD_t cfd, const struct stat * st,
memcpy(hdr.checksum, "00000000", 8);
if ((rc = safewrite(cfd, &hdr, PHYS_HDR_SIZE)) != PHYS_HDR_SIZE)
- return rc;
+ goto exit;
if ((rc = safewrite(cfd, archivePath, num)) != num)
- return rc;
+ goto exit;
size = PHYS_HDR_SIZE + num;
if ((rc = padoutfd(cfd, &size, 4)))
- return rc;
+ goto exit;
if (writeData && S_ISREG(st_mode)) {
char *b;
@@ -992,8 +1050,10 @@ static int writeFile(FD_t cfd, const struct stat * st,
/* XXX unbuffered mmap generates *lots* of fdio debugging */
datafd = Fopen(fsPath, "r.ufdio");
- if (datafd == NULL || Ferror(datafd))
- return CPIOERR_OPEN_FAILED;
+ if (datafd == NULL || Ferror(datafd)) {
+ rc = CPIOERR_OPEN_FAILED;
+ goto exit;
+ }
#if HAVE_MMAP
nmapped = 0;
@@ -1023,7 +1083,8 @@ static int writeFile(FD_t cfd, const struct stat * st,
int olderrno = errno;
Fclose(datafd);
errno = olderrno;
- return CPIOERR_READ_FAILED;
+ rc = CPIOERR_READ_FAILED;
+ goto exit;
}
}
@@ -1031,7 +1092,7 @@ static int writeFile(FD_t cfd, const struct stat * st,
int olderrno = errno;
Fclose(datafd);
errno = olderrno;
- return rc;
+ goto exit;
}
st_size -= amount;
@@ -1046,25 +1107,27 @@ static int writeFile(FD_t cfd, const struct stat * st,
Fclose(datafd);
} else if (writeData && S_ISLNK(st_mode)) {
if ((rc = safewrite(cfd, symbuf, amount)) != amount)
- return rc;
+ goto exit;
size += amount;
}
/* this is a noop for most file types */
if ((rc = padoutfd(cfd, &size, 4)))
- return rc;
+ goto exit;
if (sizep)
*sizep = size;
+ rc = 0;
- return 0;
+exit:
+ if (fsPath) free((void *)fsPath);
+ return rc;
}
/**
* Write set of linked files to payload stream.
* @param cfd payload file handle
* @param hlink set of linked files
- * @param mappings mapping name and flags for linked files
* @param cb callback function
* @param cbData callback private data
* @retval sizep address of no. bytes written
@@ -1072,7 +1135,6 @@ static int writeFile(FD_t cfd, const struct stat * st,
* @return 0 on success
*/
static int writeLinkedFile(FD_t cfd, const struct hardLink * hlink,
- const struct cpioFileMapping * mappings,
cpioCallback cb, void * cbData,
/*@out@*/size_t * sizep,
/*@out@*/const char ** failedFile)
@@ -1081,39 +1143,32 @@ static int writeLinkedFile(FD_t cfd, const struct hardLink * hlink,
struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
size_t total = 0;
const struct cpioFileMapping * map;
- char * t;
size_t size;
int i, rc;
for (i = hlink->nlink - 1; i > hlink->linksLeft; i--) {
- map = mappings + hlink->fileMaps[i];
+ map = hlink->fileMaps[i];
if ((rc = writeFile(cfd, &hlink->sb, map, &size, 0)) != 0) {
- if (failedFile) {
- t = xmalloc(strlen(map->dirName) + strlen(map->baseName) + 1);
- (void) stpcpy( stpcpy(t, map->dirName), map->baseName);
- *failedFile = t;
- }
+ if (failedFile)
+ *failedFile = mapFsPath(map);;
return rc;
}
total += size;
if (cb) {
- cbInfo.file = mappings[i].archivePath;
+ cbInfo.file = mapArchivePath(map);
cb(&cbInfo, cbData);
}
}
i = hlink->linksLeft;
- map = mappings + hlink->fileMaps[i];
+ map = hlink->fileMaps[i];
if ((rc = writeFile(cfd, &hlink->sb, map, &size, 1))) {
if (sizep)
*sizep = total;
- if (failedFile) {
- t = xmalloc(strlen(map->dirName) + strlen(map->baseName) + 1);
- (void) stpcpy( stpcpy(t, map->dirName), map->baseName);
- *failedFile = t;
- }
+ if (failedFile)
+ *failedFile = mapFsPath(map);;
return rc;
}
total += size;
@@ -1122,7 +1177,7 @@ static int writeLinkedFile(FD_t cfd, const struct hardLink * hlink,
*sizep = total;
if (cb) {
- cbInfo.file = mappings[i].archivePath;
+ cbInfo.file = mapArchivePath(map);
cb(&cbInfo, cbData);
}
@@ -1135,7 +1190,6 @@ int cpioBuildArchive(FD_t cfd, const struct cpioFileMapping * mappings,
{
size_t size, totalsize = 0;
int rc;
- int i;
struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
struct cpioCrcPhysicalHeader hdr;
/*@-fullinitblock@*/
@@ -1143,25 +1197,25 @@ int cpioBuildArchive(FD_t cfd, const struct cpioFileMapping * mappings,
/*@=fullinitblock@*/
struct stat * st = (struct stat *) &hlinkList.sb;
struct hardLink * hlink;
+ void * mapi;
+ const struct cpioFileMapping * map;
hlinkList.next = NULL;
- for (i = 0; i < numMappings; i++) {
- const struct cpioFileMapping * map;
- char fsPath[8192];
+ mapi = mapInitIterator(mappings, numMappings);
+ while ((map = mapNextIterator(mapi)) != NULL) {
+ const char * fsPath;
- map = mappings + i;
- fsPath[0] = '\0';
- (void) stpcpy( stpcpy(fsPath, map->dirName), map->baseName);
+ fsPath = mapFsPath(map);
- if (map->mapFlags & CPIO_FOLLOW_SYMLINKS)
+ if (mapFlags(map, CPIO_FOLLOW_SYMLINKS))
rc = Stat(fsPath, st);
else
rc = Lstat(fsPath, st);
if (rc) {
if (failedFile)
- *failedFile = xstrdup(fsPath);
+ *failedFile = fsPath;
return CPIOERR_STAT_FAILED;
}
@@ -1176,13 +1230,15 @@ int cpioBuildArchive(FD_t cfd, const struct cpioFileMapping * mappings,
hlinkList.next = hlink;
}
- hlink->fileMaps[--hlink->linksLeft] = i;
+ hlink->fileMaps[--hlink->linksLeft] = map;
if (hlink->linksLeft == 0) {
struct hardLink * prev;
- if ((rc = writeLinkedFile(cfd, hlink, mappings, cb, cbData,
- &size, failedFile)))
+ rc = writeLinkedFile(cfd, hlink, cb, cbData, &size, failedFile);
+ if (rc) {
+ free((void *)fsPath);
return rc;
+ }
totalsize += size;
@@ -1200,18 +1256,21 @@ int cpioBuildArchive(FD_t cfd, const struct cpioFileMapping * mappings,
} else {
if ((rc = writeFile(cfd, st, map, &size, 1))) {
if (failedFile)
- *failedFile = xstrdup(fsPath);
+ *failedFile = fsPath;
return rc;
}
if (cb) {
- cbInfo.file = map->archivePath;
+ cbInfo.file = mapArchivePath(map);
cb(&cbInfo, cbData);
}
totalsize += size;
}
+ free((void *)fsPath);
+ fsPath = NULL;
}
+ mapFreeIterator(mapi);
rc = 0;
while ((hlink = hlinkList.next) != NULL) {
@@ -1219,8 +1278,7 @@ int cpioBuildArchive(FD_t cfd, const struct cpioFileMapping * mappings,
hlink->next = NULL;
if (rc == 0) {
- rc = writeLinkedFile(cfd, hlink, mappings, cb, cbData,
- &size, failedFile);
+ rc = writeLinkedFile(cfd, hlink, cb, cbData, &size, failedFile);
totalsize += size;
}
freeHardLink(hlink);
diff --git a/lib/install.c b/lib/install.c
index 07a3c1612..8ac628423 100644
--- a/lib/install.c
+++ b/lib/install.c
@@ -19,34 +19,24 @@
/**
* Private data for cpio callback.
*/
-struct callbackInfo {
+typedef struct callbackInfo_s {
unsigned long archiveSize;
rpmCallbackFunction notify;
const char ** specFilePtr;
Header h;
rpmCallbackData notifyData;
const void * pkgKey;
-};
-
-/**
- * Keeps track of memory allocated while accessing header tags.
- */
-typedef struct fileMemory_s {
-/*@owned@*/ const char ** dnl;
-/*@owned@*/ const char ** bnl;
-/*@owned@*/ const char ** cpioNames;
-/*@owned@*/ const char ** md5sums;
-/*@owned@*/ struct fileInfo * files;
-} * fileMemory;
+} * cbInfo;
/**
* Header file info, gathered per-file, rather than per-tag.
*/
-struct fileInfo {
+typedef struct fileInfo_s {
/*@dependent@*/ const char * cpioPath;
-/*@dependent@*/ const char * relativePath; /* relative to root */
/*@dependent@*/ const char * dn; /* relative to root */
/*@dependent@*/ const char * bn;
+/*@observer@*/ const char * bnsuffix;
+/*@observer@*/ const char * oext;
/*@dependent@*/ const char * md5sum;
uid_t uid;
gid_t gid;
@@ -56,7 +46,18 @@ struct fileInfo {
char state;
enum fileActions action;
int install;
-} ;
+} * XFI_t ;
+
+/**
+ * Keeps track of memory allocated while accessing header tags.
+ */
+typedef struct fileMemory_s {
+/*@owned@*/ const char ** dnl;
+/*@owned@*/ const char ** bnl;
+/*@owned@*/ const char ** cpioNames;
+/*@owned@*/ const char ** md5sums;
+/*@owned@*/ XFI_t files;
+} * fileMemory;
/* XXX add more tags */
/**
@@ -88,7 +89,7 @@ static int rpmInstallLoadMacros(Header h)
int_32 * i32p;
} body;
char numbuf[32];
- int type;
+ int_32 type;
for (tagm = tagMacros; tagm->macroname != NULL; tagm++) {
if (!headerGetEntry(h, tagm->tag, &type, (void **) &body, NULL))
@@ -150,7 +151,7 @@ static void freeFileMemory( /*@only@*/ fileMemory fileMem)
static int assembleFileList(TFI_t fi, Header h,
/*@out@*/ fileMemory * memPtr,
/*@out@*/ int * fileCountPtr,
- /*@out@*/ struct fileInfo ** filesPtr,
+ /*@out@*/ XFI_t * filesPtr,
int stripPrefixLength)
{
enum fileActions * actions;
@@ -160,8 +161,8 @@ static int assembleFileList(TFI_t fi, Header h,
uint_32 * fsizes;
uint_16 * fmodes;
fileMemory mem = newFileMemory();
- struct fileInfo * files;
- struct fileInfo * file;
+ XFI_t files;
+ XFI_t file;
int fileCount;
int i;
@@ -229,30 +230,29 @@ static int assembleFileList(TFI_t fi, Header h,
* @param files install file information
* @param fileCount install file count
*/
-static void setFileOwners(Header h, struct fileInfo * files, int fileCount)
+static void setFileOwners(Header h, XFI_t files, int fileCount)
{
- char ** fileOwners;
- char ** fileGroups;
+ const char ** fileOwners;
+ const char ** fileGroups;
+ XFI_t file;
int i;
headerGetEntry(h, RPMTAG_FILEUSERNAME, NULL, (void **) &fileOwners, NULL);
headerGetEntry(h, RPMTAG_FILEGROUPNAME, NULL, (void **) &fileGroups, NULL);
- for (i = 0; i < fileCount; i++) {
- if (unameToUid(fileOwners[i], &files[i].uid)) {
+ for (i = 0, file = files; i < fileCount; i++, file++) {
+ if (unameToUid(fileOwners[i], &file->uid)) {
rpmMessage(RPMMESS_WARNING,
_("user %s does not exist - using root\n"), fileOwners[i]);
- files[i].uid = 0;
- /* turn off the suid bit */
- files[i].mode &= ~S_ISUID;
+ file->uid = 0;
+ file->mode &= ~S_ISUID; /* turn off the suid bit */
}
- if (gnameToGid(fileGroups[i], &files[i].gid)) {
+ if (gnameToGid(fileGroups[i], &file->gid)) {
rpmMessage(RPMMESS_WARNING,
_("group %s does not exist - using root\n"), fileGroups[i]);
- files[i].gid = 0;
- /* turn off the sgid bit */
- files[i].mode &= ~S_ISGID;
+ file->gid = 0;
+ file->mode &= ~S_ISGID; /* turn off the sgid bit */
}
}
@@ -309,8 +309,9 @@ static void trimChangelog(Header h)
* @param actions array of file dispositions
* @return 0 on success, 1 on failure
*/
-static int mergeFiles(Header h, Header newH, enum fileActions * actions)
+static int mergeFiles(Header h, Header newH, TFI_t fi)
{
+ enum fileActions * actions = fi->actions;
int i, j, k, fileCount;
int_32 type, count, dirNamesCount, dirCount;
void * data, * newdata;
@@ -483,25 +484,30 @@ static int mergeFiles(Header h, Header newH, enum fileActions * actions)
}
/**
- * Mark files in database shared with current package as "replaced".
- * @param db rpm database
- * @param replist shared file list
+ * Mark files in database shared with this package as "replaced".
+ * @param ts transaction set
+ * @param fi transaction element file info
* @return 0 always
*/
-static int markReplacedFiles(rpmdb rpmdb, const struct sharedFileInfo * replList)
+static int markReplacedFiles(const rpmTransactionSet ts, const TFI_t fi)
{
- const struct sharedFileInfo * fileInfo;
+ rpmdb rpmdb = ts->rpmdb;
+ const struct sharedFileInfo * replaced = fi->replaced;
+ const struct sharedFileInfo * sfi;
rpmdbMatchIterator mi;
Header h;
unsigned int * offsets;
unsigned int prev;
int num;
+ if (!(fi->fc > 0 && fi->replaced))
+ return 0;
+
num = prev = 0;
- for (fileInfo = replList; fileInfo->otherPkg; fileInfo++) {
- if (prev && prev == fileInfo->otherPkg)
+ for (sfi = replaced; sfi->otherPkg; sfi++) {
+ if (prev && prev == sfi->otherPkg)
continue;
- prev = fileInfo->otherPkg;
+ prev = sfi->otherPkg;
num++;
}
if (num == 0)
@@ -509,17 +515,17 @@ static int markReplacedFiles(rpmdb rpmdb, const struct sharedFileInfo * replList
offsets = alloca(num * sizeof(*offsets));
num = prev = 0;
- for (fileInfo = replList; fileInfo->otherPkg; fileInfo++) {
- if (prev && prev == fileInfo->otherPkg)
+ for (sfi = replaced; sfi->otherPkg; sfi++) {
+ if (prev && prev == sfi->otherPkg)
continue;
- prev = fileInfo->otherPkg;
- offsets[num++] = fileInfo->otherPkg;
+ prev = sfi->otherPkg;
+ offsets[num++] = sfi->otherPkg;
}
mi = rpmdbInitIterator(rpmdb, RPMDBI_PACKAGES, NULL, 0);
rpmdbAppendIterator(mi, offsets, num);
- fileInfo = replList;
+ sfi = replaced;
while ((h = rpmdbNextIterator(mi)) != NULL) {
char * secStates;
int modified;
@@ -532,10 +538,10 @@ static int markReplacedFiles(rpmdb rpmdb, const struct sharedFileInfo * replList
prev = rpmdbGetIteratorOffset(mi);
num = 0;
- while (fileInfo->otherPkg && fileInfo->otherPkg == prev) {
- assert(fileInfo->otherFileNum < count);
- if (secStates[fileInfo->otherFileNum] != RPMFILE_STATE_REPLACED) {
- secStates[fileInfo->otherFileNum] = RPMFILE_STATE_REPLACED;
+ while (sfi->otherPkg && sfi->otherPkg == prev) {
+ assert(sfi->otherFileNum < count);
+ if (secStates[sfi->otherFileNum] != RPMFILE_STATE_REPLACED) {
+ secStates[sfi->otherFileNum] = RPMFILE_STATE_REPLACED;
if (modified == 0) {
/* Modified header will be rewritten. */
modified = 1;
@@ -543,7 +549,7 @@ static int markReplacedFiles(rpmdb rpmdb, const struct sharedFileInfo * replList
}
num++;
}
- fileInfo++;
+ sfi++;
}
}
rpmdbFreeIterator(mi);
@@ -555,19 +561,17 @@ static int markReplacedFiles(rpmdb rpmdb, const struct sharedFileInfo * replList
*/
static void callback(struct cpioCallbackInfo * cpioInfo, void * data)
{
- struct callbackInfo * ourInfo = data;
- const char * chptr;
+ cbInfo cbi = data;
- if (ourInfo->notify)
- (void)ourInfo->notify(ourInfo->h, RPMCALLBACK_INST_PROGRESS,
+ if (cbi->notify)
+ (void)cbi->notify(cbi->h, RPMCALLBACK_INST_PROGRESS,
cpioInfo->bytesProcessed,
- ourInfo->archiveSize, ourInfo->pkgKey,
- ourInfo->notifyData);
+ cbi->archiveSize, cbi->pkgKey, cbi->notifyData);
- if (ourInfo->specFilePtr) {
- chptr = cpioInfo->file + strlen(cpioInfo->file) - 5;
- if (!strcmp(chptr, ".spec"))
- *ourInfo->specFilePtr = xstrdup(cpioInfo->file);
+ if (cbi->specFilePtr) {
+ const char * t = cpioInfo->file + strlen(cpioInfo->file) - 5;
+ if (!strcmp(t, ".spec"))
+ *cbi->specFilePtr = xstrdup(cpioInfo->file);
}
}
@@ -587,19 +591,19 @@ static void callback(struct cpioCallbackInfo * cpioInfo, void * data)
* @param archiveSize @todo Document.
* @return 0 on success
*/
-static int installArchive(FD_t fd, struct fileInfo * files, int fileCount,
+static int installArchive(FD_t fd, XFI_t files, int fileCount,
rpmCallbackFunction notify, rpmCallbackData notifyData,
const void * pkgKey, Header h,
/*@out@*/ const char ** specFile, int archiveSize)
{
- int rc, i;
struct cpioFileMapping * map = NULL;
int mappedFiles = 0;
const char * failedFile = NULL;
- struct callbackInfo info;
+ cbInfo cbi = alloca(sizeof(*cbi));
char * rpmio_flags;
FD_t cfd;
int saveerrno;
+ int rc;
if (!files) {
/* install all files */
@@ -609,31 +613,34 @@ static int installArchive(FD_t fd, struct fileInfo * files, int fileCount,
return 0;
}
- info.archiveSize = archiveSize;
- info.notify = notify;
- info.notifyData = notifyData;
- info.specFilePtr = specFile;
- info.h = headerLink(h);
- info.pkgKey = pkgKey;
+ cbi->archiveSize = archiveSize; /* arg9 */
+ cbi->notify = notify; /* arg4 */
+ cbi->notifyData = notifyData; /* arg5 */
+ cbi->specFilePtr = specFile; /* arg8 */
+ cbi->h = headerLink(h); /* arg7 */
+ cbi->pkgKey = pkgKey; /* arg6 */
if (specFile) *specFile = NULL;
if (files) {
+ XFI_t file;
+ int i;
+
map = alloca(sizeof(*map) * fileCount);
- for (i = 0, mappedFiles = 0; i < fileCount; i++) {
- if (!files[i].install) continue;
+ for (i = 0, mappedFiles = 0, file = files; i < fileCount; i++, file++) {
+ if (!file->install) continue;
- map[mappedFiles].archivePath = files[i].cpioPath;
- (void) urlPath(files[i].dn, &map[mappedFiles].dirName);
- map[mappedFiles].baseName = files[i].bn;
+ map[mappedFiles].archivePath = file->cpioPath;
+ (void) urlPath(file->dn, &map[mappedFiles].dirName);
+ map[mappedFiles].baseName = file->bn;
/* XXX Can't do src rpm MD5 sum verification (yet). */
/* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */
map[mappedFiles].md5sum = headerIsEntry(h, RPMTAG_SOURCERPM)
- ? files[i].md5sum : NULL;
- map[mappedFiles].finalMode = files[i].mode;
- map[mappedFiles].finalUid = files[i].uid;
- map[mappedFiles].finalGid = files[i].gid;
+ ? file->md5sum : NULL;
+ map[mappedFiles].finalMode = file->mode;
+ map[mappedFiles].finalUid = file->uid;
+ map[mappedFiles].finalGid = file->gid;
map[mappedFiles].mapFlags = CPIO_MAP_PATH | CPIO_MAP_MODE |
CPIO_MAP_UID | CPIO_MAP_GID;
mappedFiles++;
@@ -665,10 +672,10 @@ static int installArchive(FD_t fd, struct fileInfo * files, int fileCount,
cfd = Fdopen(fdDup(Fileno(fd)), rpmio_flags);
rc = cpioInstallArchive(cfd, map, mappedFiles,
((notify && archiveSize) || specFile) ? callback : NULL,
- &info, &failedFile);
+ cbi, &failedFile);
saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */
Fclose(cfd);
- headerFree(info.h);
+ headerFree(cbi->h);
if (rc) {
/* this would probably be a good place to check if disk space
@@ -682,7 +689,7 @@ static int installArchive(FD_t fd, struct fileInfo * files, int fileCount,
} else if (notify) {
if (archiveSize)
(void)notify(h, RPMCALLBACK_INST_PROGRESS, archiveSize, archiveSize,
- pkgKey, notifyData);
+ pkgKey, notifyData);
else
(void)notify(h, RPMCALLBACK_INST_PROGRESS, 100, 100,
pkgKey, notifyData);
@@ -710,13 +717,12 @@ static int installSources(Header h, const char * rootDir, FD_t fd,
{
const char * specFile = NULL;
int specFileIndex = -1;
- const char * realSourceDir = NULL;
- const char * realSpecDir = NULL;
- char * instSpecFile, * correctSpecFile;
+ const char * _sourcedir = NULL;
+ const char * _specdir = NULL;
int fileCount = 0;
uint_32 * archiveSizePtr = NULL;
fileMemory fileMem = NULL;
- struct fileInfo * files = NULL;
+ XFI_t files = NULL;
int i;
const char * currDir = NULL;
uid_t currUid = getuid();
@@ -726,9 +732,9 @@ static int installSources(Header h, const char * rootDir, FD_t fd,
rpmMessage(RPMMESS_DEBUG, _("installing a source package\n"));
- realSourceDir = rpmGenPath(rootDir, "%{_sourcedir}", "");
- if ((rc = Stat(realSourceDir, &st)) < 0) {
- int ut = urlPath(realSourceDir, NULL);
+ _sourcedir = rpmGenPath(rootDir, "%{_sourcedir}", "");
+ if ((rc = Stat(_sourcedir, &st)) < 0) {
+ int ut = urlPath(_sourcedir, NULL);
switch (ut) {
case URL_IS_PATH:
case URL_IS_UNKNOWN:
@@ -738,28 +744,28 @@ static int installSources(Header h, const char * rootDir, FD_t fd,
case URL_IS_FTP:
case URL_IS_HTTP:
/* XXX this will only create last component of directory path */
- rc = Mkdir(realSourceDir, 0755);
+ rc = Mkdir(_sourcedir, 0755);
break;
case URL_IS_DASH:
break;
}
if (rc < 0) {
rpmError(RPMERR_CREATE, _("cannot create sourcedir %s\n"),
- realSourceDir);
+ _sourcedir);
rc = 2;
goto exit;
}
}
- if ((rc = Access(realSourceDir, W_OK))) {
- rpmError(RPMERR_CREATE, _("cannot write to %s\n"), realSourceDir);
+ if ((rc = Access(_sourcedir, W_OK))) {
+ rpmError(RPMERR_CREATE, _("cannot write to %s\n"), _sourcedir);
rc = 2;
goto exit;
}
- rpmMessage(RPMMESS_DEBUG, _("sources in: %s\n"), realSourceDir);
+ rpmMessage(RPMMESS_DEBUG, _("sources in: %s\n"), _sourcedir);
- realSpecDir = rpmGenPath(rootDir, "%{_specdir}", "");
- if ((rc = Stat(realSpecDir, &st)) < 0) {
- int ut = urlPath(realSpecDir, NULL);
+ _specdir = rpmGenPath(rootDir, "%{_specdir}", "");
+ if ((rc = Stat(_specdir, &st)) < 0) {
+ int ut = urlPath(_specdir, NULL);
switch (ut) {
case URL_IS_PATH:
case URL_IS_UNKNOWN:
@@ -769,24 +775,23 @@ static int installSources(Header h, const char * rootDir, FD_t fd,
case URL_IS_FTP:
case URL_IS_HTTP:
/* XXX this will only create last component of directory path */
- rc = Mkdir(realSpecDir, 0755);
+ rc = Mkdir(_specdir, 0755);
break;
case URL_IS_DASH:
break;
}
if (rc < 0) {
- rpmError(RPMERR_CREATE, _("cannot create specdir %s\n"),
- realSpecDir);
+ rpmError(RPMERR_CREATE, _("cannot create specdir %s\n"), _specdir);
rc = 2;
goto exit;
}
}
- if ((rc = Access(realSpecDir, W_OK))) {
- rpmError(RPMERR_CREATE, _("cannot write to %s\n"), realSpecDir);
+ if ((rc = Access(_specdir, W_OK))) {
+ rpmError(RPMERR_CREATE, _("cannot write to %s\n"), _specdir);
rc = 2;
goto exit;
}
- rpmMessage(RPMMESS_DEBUG, _("spec file in: %s\n"), realSpecDir);
+ rpmMessage(RPMMESS_DEBUG, _("spec file in: %s\n"), _specdir);
if (h != NULL && headerIsEntry(h, RPMTAG_BASENAMES)) {
/* we can't remap v1 packages */
@@ -804,17 +809,18 @@ static int installSources(Header h, const char * rootDir, FD_t fd,
if (i == fileCount) {
/* find the spec file by name */
for (i = 0; i < fileCount; i++) {
- const char *chptr;
- chptr = files[i].cpioPath + strlen(files[i].cpioPath) - 5;
- if (!strcmp(chptr, ".spec")) break;
+ const char * t = files[i].cpioPath;
+ t += strlen(files[i].cpioPath) - 5;
+ if (!strcmp(t, ".spec")) break;
}
}
if (i < fileCount) {
- char *t = alloca(strlen(realSpecDir) +
- strlen(files[i].cpioPath) + 5);
- (void)stpcpy(stpcpy(stpcpy(t,realSpecDir), "/"), files[i].cpioPath);
- files[i].relativePath = t;
+ char *t = alloca(strlen(_specdir) + strlen(files[i].cpioPath) + 5);
+ (void)stpcpy(stpcpy(t, _specdir), "/");
+ rpmCleanPath(t);
+ files[i].dn = t;
+ files[i].bn = files[i].cpioPath;
specFileIndex = i;
} else {
rpmError(RPMERR_NOSPEC,
@@ -824,17 +830,15 @@ static int installSources(Header h, const char * rootDir, FD_t fd,
}
}
- if (notify) {
+ if (notify)
(void)notify(h, RPMCALLBACK_INST_START, 0, 0, NULL, notifyData);
- }
-
- currDir = currentDirectory();
if (!headerGetEntry(h, RPMTAG_ARCHIVESIZE, NULL,
(void **) &archiveSizePtr, NULL))
archiveSizePtr = NULL;
- Chdir(realSourceDir);
+ currDir = currentDirectory();
+ Chdir(_sourcedir);
if (installArchive(fd, fileCount > 0 ? files : NULL,
fileCount, notify, notifyData, NULL, h,
specFileIndex >= 0 ? NULL : &specFile,
@@ -845,6 +849,9 @@ static int installSources(Header h, const char * rootDir, FD_t fd,
Chdir(currDir);
if (specFileIndex == -1) {
+ char * cSpecFile;
+ char * iSpecFile;
+
if (specFile == NULL) {
rpmError(RPMERR_NOSPEC,
_("source package contains no .spec file\n"));
@@ -852,41 +859,48 @@ static int installSources(Header h, const char * rootDir, FD_t fd,
goto exit;
}
- /* This logic doesn't work if realSpecDir and realSourceDir are on
- different filesystems, but we only do this on v1 source packages
- so I don't really care much. */
- instSpecFile = alloca(strlen(realSourceDir) + strlen(specFile) + 2);
- (void)stpcpy(stpcpy(stpcpy(instSpecFile,realSourceDir), "/"), specFile);
+ /*
+ * This logic doesn't work if _specdir and _sourcedir are on
+ * different filesystems, but we only do this on v1 source packages
+ * so I don't really care much.
+ */
+ iSpecFile = alloca(strlen(_sourcedir) + strlen(specFile) + 2);
+ (void)stpcpy(stpcpy(stpcpy(iSpecFile, _sourcedir), "/"), specFile);
- correctSpecFile = alloca(strlen(realSpecDir) + strlen(specFile) + 2);
- (void)stpcpy(stpcpy(stpcpy(correctSpecFile,realSpecDir), "/"), specFile);
+ cSpecFile = alloca(strlen(_specdir) + strlen(specFile) + 2);
+ (void)stpcpy(stpcpy(stpcpy(cSpecFile, _specdir), "/"), specFile);
free((void *)specFile);
- if (strcmp(instSpecFile, correctSpecFile)) {
+ if (strcmp(iSpecFile, cSpecFile)) {
rpmMessage(RPMMESS_DEBUG,
- _("renaming %s to %s\n"), instSpecFile, correctSpecFile);
- if ((rc = Rename(instSpecFile, correctSpecFile))) {
+ _("renaming %s to %s\n"), iSpecFile, cSpecFile);
+ if ((rc = Rename(iSpecFile, cSpecFile))) {
rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s\n"),
- instSpecFile, correctSpecFile, strerror(errno));
+ iSpecFile, cSpecFile, strerror(errno));
rc = 2;
goto exit;
}
}
if (specFilePtr)
- *specFilePtr = xstrdup(correctSpecFile);
+ *specFilePtr = xstrdup(cSpecFile);
} else {
- if (specFilePtr)
- *specFilePtr = xstrdup(files[specFileIndex].relativePath);
+ if (specFilePtr) {
+ const char * dn = files[specFileIndex].dn;
+ const char * bn = files[specFileIndex].bn;
+ char * t = xmalloc(strlen(dn) + strlen(bn) + 1);
+ (void)stpcpy( stpcpy(t, dn), bn);
+ *specFilePtr = t;
+ }
}
rc = 0;
exit:
if (fileMem) freeFileMemory(fileMem);
if (currDir) free((void *)currDir);
- if (realSpecDir) free((void *)realSpecDir);
- if (realSourceDir) free((void *)realSourceDir);
+ if (_specdir) free((void *)_specdir);
+ if (_sourcedir) free((void *)_sourcedir);
return rc;
}
@@ -983,22 +997,16 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi)
rpmtransFlags transFlags = ts->transFlags;
struct availablePackage * alp = fi->ap;
int fileCount = 0;
- int type, count;
- struct fileInfo * files;
- int i;
+ XFI_t files = NULL;
Header oldH = NULL;
int otherOffset = 0;
int scriptArg;
- int stripSize = 1; /* strip at least first / for cpio */
fileMemory fileMem = NULL;
+ int ec = 2; /* assume error return */
int rc;
+ int i;
-#ifdef DYING
- const char * name, * version, * release;
- headerNVR(h, &name, &version, &release);
-#endif
-
- /* XXX this looks broke, as libraries may need /sbin/ldconfig for example */
+ /* XXX MULTILIB is broken, as packages can and do execute /sbin/ldconfig. */
if (transFlags & (RPMTRANS_FLAG_JUSTDB | RPMTRANS_FLAG_MULTILIB))
transFlags |= RPMTRANS_FLAG_NOSCRIPTS;
@@ -1006,10 +1014,8 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi)
alp->name, alp->version, alp->release,
transFlags & RPMTRANS_FLAG_TEST);
- if ((scriptArg = rpmdbCountPackages(ts->rpmdb, alp->name)) < 0) {
- rc = 2;
+ if ((scriptArg = rpmdbCountPackages(ts->rpmdb, alp->name)) < 0)
goto exit;
- }
scriptArg += 1;
{ rpmdbMatchIterator mi;
@@ -1025,29 +1031,28 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi)
rpmdbFreeIterator(mi);
}
- if (!(transFlags & RPMTRANS_FLAG_JUSTDB) && headerIsEntry(h, RPMTAG_BASENAMES)) {
- const char * defaultPrefix;
- /* old format relocateable packages need the entire default
- prefix stripped to form the cpio list, while all other packages
- need the leading / stripped */
- if (headerGetEntry(h, RPMTAG_DEFAULTPREFIX, NULL, (void **)
- &defaultPrefix, NULL)) {
- stripSize = strlen(defaultPrefix) + 1;
- } else {
- stripSize = 1;
- }
+ if (!(transFlags & RPMTRANS_FLAG_JUSTDB) &&
+ headerIsEntry(h, RPMTAG_BASENAMES))
+ {
+ const char * p;
+ int stripSize;
- if (assembleFileList(fi, h, &fileMem, &fileCount, &files, stripSize)) {
- rc = 2;
+ /*
+ * Old format relocateable packages need the entire default
+ * prefix stripped to form the cpio list, while all other packages
+ * need the leading / stripped.
+ */
+ rc = headerGetEntry(h, RPMTAG_DEFAULTPREFIX, NULL, (void **) &p, NULL);
+ stripSize = (rc ? strlen(p) + 1 : 1);
+ if (assembleFileList(fi, h, &fileMem, &fileCount, &files, stripSize))
goto exit;
- }
} else {
files = NULL;
}
if (transFlags & RPMTRANS_FLAG_TEST) {
rpmMessage(RPMMESS_DEBUG, _("stopping install as we're running --test\n"));
- rc = 0;
+ ec = 0;
goto exit;
}
@@ -1060,7 +1065,6 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi)
rpmError(RPMERR_SCRIPT,
_("skipping %s-%s-%s install, %%pre scriptlet failed rc %d\n"),
alp->name, alp->version, alp->release, rc);
- rc = 2;
goto exit;
}
@@ -1076,29 +1080,33 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi)
}
if (files) {
+ XFI_t file;
+
setFileOwners(h, files, fileCount);
- for (i = 0; i < fileCount; i++) {
+ for (i = 0, file = files; i < fileCount; i++, file++) {
+ char opath[BUFSIZ];
+ char * npath;
char * ext;
- char * newpath;
- ext = NULL;
+ file->bnsuffix = file->oext = ext = NULL;
- switch (files[i].action) {
+ switch (file->action) {
case FA_BACKUP:
- ext = ".rpmorig";
+ file->oext = ext = ".rpmorig";
break;
case FA_ALTNAME:
- newpath = alloca(strlen(files[i].relativePath) + 20);
- (void)stpcpy(stpcpy(newpath, files[i].relativePath), ".rpmnew");
- rpmMessage(RPMMESS_WARNING, _("%s created as %s\n"),
- files[i].relativePath, newpath);
- files[i].relativePath = newpath;
+ file->bnsuffix = ".rpmnew";
+ npath = alloca(strlen(file->bn) + strlen(file->bnsuffix) + 1);
+ (void)stpcpy(stpcpy(npath, file->bn), file->bnsuffix);
+ rpmMessage(RPMMESS_WARNING, _("%s%s created as %s\n"),
+ file->dn, file->bn, npath);
+ file->bn = npath;
break;
case FA_SAVE:
- ext = ".rpmsave";
+ file->oext = ext = ".rpmsave";
break;
case FA_CREATE:
@@ -1106,45 +1114,48 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi)
case FA_SKIP:
case FA_SKIPMULTILIB:
- files[i].install = 0;
+ file->install = 0;
break;
case FA_SKIPNSTATE:
- files[i].state = RPMFILE_STATE_NOTINSTALLED;
- files[i].install = 0;
+ file->state = RPMFILE_STATE_NOTINSTALLED;
+ file->install = 0;
break;
case FA_SKIPNETSHARED:
- files[i].state = RPMFILE_STATE_NETSHARED;
- files[i].install = 0;
+ file->state = RPMFILE_STATE_NETSHARED;
+ file->install = 0;
break;
case FA_UNKNOWN:
case FA_REMOVE:
- files[i].install = 0;
+ file->install = 0;
break;
}
- if (ext && access(files[i].relativePath, F_OK) == 0) {
- newpath = alloca(strlen(files[i].relativePath) + 20);
- (void)stpcpy(stpcpy(newpath, files[i].relativePath), ext);
- rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"),
- files[i].relativePath, newpath);
-
- if (rename(files[i].relativePath, newpath)) {
- rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s\n"),
- files[i].relativePath, newpath, strerror(errno));
- rc = 2;
- goto exit;
- }
- }
+ if (ext == NULL)
+ continue;
+ (void)stpcpy(stpcpy(opath, file->dn), file->bn);
+ if (access(opath, F_OK) != 0)
+ continue;
+ npath = alloca(strlen(file->dn) + strlen(file->bn)
+ + strlen(ext) + 1);
+ (void)stpcpy(stpcpy(npath, opath), ext);
+ rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"), opath, npath);
+
+ if (!rename(opath, npath))
+ continue;
+
+ rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s\n"),
+ opath, npath, strerror(errno));
+ goto exit;
}
- { uint_32 * archiveSizePtr;
+ { uint_32 archiveSize, * asp;
- if (!headerGetEntry(h, RPMTAG_ARCHIVESIZE, &type,
- (void **) &archiveSizePtr, &count))
- archiveSizePtr = NULL;
+ rc = headerGetEntry(h, RPMTAG_ARCHIVESIZE, NULL,
+ (void **) &asp, NULL);
+ archiveSize = (rc ? *asp : 0);
if (ts->notify) {
(void)ts->notify(h, RPMCALLBACK_INST_START, 0, 0,
@@ -1152,33 +1163,28 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi)
}
/* the file pointer for fd is pointing at the cpio archive */
- if (installArchive(alp->fd, files, fileCount,
+ rc = installArchive(alp->fd, files, fileCount,
ts->notify, ts->notifyData, alp->key,
- h, NULL, archiveSizePtr ? *archiveSizePtr : 0))
- {
- rc = 2;
+ h, NULL, archiveSize);
+ if (rc)
goto exit;
- }
}
- { char *fileStates = xmalloc(sizeof(*fileStates) * fileCount);
- for (i = 0; i < fileCount; i++)
- fileStates[i] = files[i].state;
-
- headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fileStates,
+ { char *fstates = alloca(sizeof(*fstates) * fileCount);
+ for (i = 0, file = files; i < fileCount; i++, file++)
+ fstates[i] = file->state;
+ headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fstates,
fileCount);
-
- free(fileStates);
}
+
if (fileMem) freeFileMemory(fileMem);
fileMem = NULL;
} else if (transFlags & RPMTRANS_FLAG_JUSTDB) {
if (headerGetEntry(h, RPMTAG_BASENAMES, NULL, NULL, &fileCount)) {
- char * fileStates = xmalloc(sizeof(*fileStates) * fileCount);
- memset(fileStates, RPMFILE_STATE_NORMAL, fileCount);
- headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fileStates,
- fileCount);
- free(fileStates);
+ char * fstates = alloca(sizeof(*fstates) * fileCount);
+ memset(fstates, RPMFILE_STATE_NORMAL, fileCount);
+ headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fstates,
+ fileCount);
}
}
@@ -1213,46 +1219,36 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi)
headerModifyEntry(oldH, RPMTAG_MULTILIBS, RPM_INT32_TYPE,
&multiLib, 1);
}
- if (mergeFiles(oldH, h, fi->actions)) {
- rc = 2;
+ if (mergeFiles(oldH, h, fi))
goto exit;
- }
}
- if (rpmdbAdd(ts->rpmdb, ts->id, h)) {
- rc = 2;
+ if (rpmdbAdd(ts->rpmdb, ts->id, h))
goto exit;
- }
rpmMessage(RPMMESS_DEBUG, _("running postinstall scripts (if any)\n"));
- if (runInstScript(ts, h, RPMTAG_POSTIN, RPMTAG_POSTINPROG, scriptArg,
- (transFlags & RPMTRANS_FLAG_NOSCRIPTS))) {
- rc = 2;
+ rc = runInstScript(ts, h, RPMTAG_POSTIN, RPMTAG_POSTINPROG, scriptArg,
+ (transFlags & RPMTRANS_FLAG_NOSCRIPTS));
+ if (rc)
goto exit;
- }
if (!(transFlags & RPMTRANS_FLAG_NOTRIGGERS)) {
/* Run triggers this package sets off */
- if (runTriggers(ts, RPMSENSE_TRIGGERIN, h, 0)) {
- rc = 2;
+ if (runTriggers(ts, RPMSENSE_TRIGGERIN, h, 0))
goto exit;
- }
/*
* Run triggers in this package which are set off by other packages in
* the database.
*/
- if (runImmedTriggers(ts, RPMSENSE_TRIGGERIN, h, 0)) {
- rc = 2;
+ if (runImmedTriggers(ts, RPMSENSE_TRIGGERIN, h, 0))
goto exit;
- }
}
- if (fi->fc > 0 && fi->replaced)
- markReplacedFiles(ts->rpmdb, fi->replaced);
+ markReplacedFiles(ts, fi);
- rc = 0;
+ ec = 0;
exit:
if (ts->chrootDone) {
@@ -1264,5 +1260,5 @@ exit:
freeFileMemory(fileMem);
if (oldH)
headerFree(oldH);
- return rc;
+ return ec;
}
diff --git a/lib/install.h b/lib/install.h
index 8792f99ff..26c407e45 100644
--- a/lib/install.h
+++ b/lib/install.h
@@ -28,23 +28,31 @@ struct sharedFileInfo {
* File disposition(s) during package install/erase.
*/
enum fileActions {
- FA_UNKNOWN = 0,
- FA_CREATE,
- FA_BACKUP,
- FA_SAVE,
- FA_SKIP,
- FA_ALTNAME,
- FA_REMOVE,
- FA_SKIPNSTATE,
- FA_SKIPNETSHARED,
- FA_SKIPMULTILIB
+ FA_UNKNOWN = 0, /*!< initial action (default action for source rpm) */
+ FA_CREATE, /*!< ... to be replaced. */
+ FA_BACKUP, /*!< ... renamed with ".rpmorig" extension. */
+ FA_SAVE, /*!< ... renamed with ".rpmsave" extension. */
+ FA_SKIP, /*!< ... already replaced, don't remove. */
+ FA_ALTNAME, /*!< ... create with ".rpmnew" extension. */
+ FA_REMOVE, /*!< ... to be removed. */
+ FA_SKIPNSTATE, /*!< ... untouched, state "not installed". */
+ FA_SKIPNETSHARED, /*!< ... untouched, state "netshared". */
+ FA_SKIPMULTILIB, /*!< ... untouched. @todo state "multilib" ???. */
};
/**
+ */
+typedef enum rollbackDir_e {
+ ROLLBACK_SAVE = 1, /*!< Save files. */
+ ROLLBACK_RESTORE = 2, /*!< Restore files. */
+} rollbackDir;
+
+/**
* File types.
* These are the types of files used internally by rpm. The file
* type is determined by applying stat(2) macros like S_ISDIR to
- * the file mode tag from a header.
+ * the file mode tag from a header. The values are arbitrary,
+ * but are identical to the linux stat(2) file types.
*/
enum fileTypes {
PIPE = 1, /*!< pipe/fifo */
@@ -53,7 +61,7 @@ enum fileTypes {
BDEV = 6, /*!< block device */
REG = 8, /*!< regular file */
LINK = 10, /*!< hard link */
- SOCK = 12 /*!< socket */
+ SOCK = 12, /*!< socket */
};
/*@abstract@*/ typedef struct transactionFileInfo_s * TFI_t;
@@ -63,33 +71,35 @@ extern "C" {
#endif
/**
+ * Retrieve and run scriptlet from header.
* @param ts transaction set
* @param h header
- * @param scriptTag
- * @param progTag
- * @param arg
- * @param norunScripts
+ * @param scriptTag scriptlet tag
+ * @param progTag scriptlet interpreter tag
+ * @param arg no. instances of package installed after scriptlet exec
+ * @param norunScripts should scriptlet be executed?
+ * @return 0 on success
*/
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.
+ * Run trigger scripts in the database that are fired by this header.
* @param ts transaction set
- * @param sense @todo Document.
+ * @param sense one of RPMSENSE_TRIGGER{IN,UN,POSTUN}
* @param h header
- * @param countCorrection @todo Document.
+ * @param countCorrection 0 if installing, -1 if removing, package
* @return 0 on success, 1 on error
*/
int runTriggers(const rpmTransactionSet ts, int sense, Header h,
int countCorrection);
/**
- * Run triggers from header that are fired by the database.
+ * Run triggers from this header that are fired by headers in the database.
* @param ts transaction set
- * @param sense @todo Document.
+ * @param sense one of RPMSENSE_TRIGGER{IN,UN,POSTUN}
* @param h header
- * @param countCorrection @todo Document.
+ * @param countCorrection 0 if installing, -1 if removing, package
* @return 0 on success, 1 on error
*/
int runImmedTriggers(const rpmTransactionSet ts, int sense, Header h,
@@ -106,7 +116,7 @@ int runImmedTriggers(const rpmTransactionSet ts, int sense, Header h,
* Install binary package (from transaction set).
* @param ts transaction set
* @param h package header
- * @param fi transaction file info
+ * @param fi transaction element file info
* @return 0 on success, 1 on bad magic, 2 on error
*/
int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi);
@@ -118,11 +128,21 @@ int installBinaryPackage(const rpmTransactionSet ts, Header h, TFI_t fi);
* @param h package header
* @param pkgKey package private data
* @param actions array of file dispositions
- * @return
+ * @return 0 on success
*/
int removeBinaryPackage(const rpmTransactionSet ts, unsigned int offset,
Header h, const void * pkgKey, enum fileActions * actions);
+/**
+ * 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);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/transaction.c b/lib/transaction.c
index ddfacefb3..efa9edacc 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -1351,76 +1351,6 @@ static void skipFiles(TFI_t fi, int noDocs)
if (languages) freeSplitString((char **)languages);
}
-static char * ridsub = ".rid/";
-static char * ridsep = ";";
-static mode_t riddmode = 0700;
-static mode_t ridfmode = 0000;
-
-static int dirstashPackage(const rpmTransactionSet ts, const TFI_t fi)
-{
- unsigned int offset = fi->record;
- char tsid[20], ofn[BUFSIZ], nfn[BUFSIZ];
- const char * s, * t;
- char * se, * te;
- Header h;
- int i;
-
- { 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, 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;
-}
-
#define NOTIFY(_ts, _al) if ((_ts)->notify) (void) (_ts)->notify _al
int rpmRunTransactions( rpmTransactionSet ts,
@@ -1601,9 +1531,10 @@ int rpmRunTransactions( rpmTransactionSet ts,
switch (ts->order[oc].type) {
case TR_ADDED:
+ fi->type = TR_ADDED;
i = ts->order[oc].u.addedIndex;
alp = ts->addedPackages.list + i;
-
+ fi->ap = alp;
if (!headerGetEntryMinMemory(alp->h, RPMTAG_BASENAMES, NULL,
NULL, &fi->fc)) {
fi->h = headerLink(alp->h);
@@ -1615,10 +1546,10 @@ int rpmRunTransactions( rpmTransactionSet ts,
fi->actions = xcalloc(fi->fc, sizeof(*fi->actions));
hdrs[i] = relocateFileList(ts, alp, alp->h, fi->actions);
fi->h = headerLink(hdrs[i]);
- fi->ap = alp;
- fi->type = TR_ADDED;
break;
case TR_REMOVED:
+ fi->type = TR_REMOVED;
+ fi->ap = alp = NULL;
fi->record = ts->order[oc].u.removed.dboffset;
{ rpmdbMatchIterator mi;
@@ -1632,8 +1563,6 @@ int rpmRunTransactions( rpmTransactionSet ts,
/* ACK! */
continue;
}
- fi->ap = alp = NULL;
- fi->type = TR_REMOVED;
break;
}
@@ -1899,7 +1828,7 @@ int rpmRunTransactions( rpmTransactionSet ts,
if (ts->order[oc].u.removed.dependsOnIndex != i)
break;
if (ts->transFlags & RPMTRANS_FLAG_DIRSTASH)
- dirstashPackage(ts, fi);
+ dirstashPackage(ts, fi, ROLLBACK_SAVE);
break;
}
}
@@ -1945,6 +1874,7 @@ int rpmRunTransactions( rpmTransactionSet ts,
if (alp->multiLib)
ts->transFlags |= RPMTRANS_FLAG_MULTILIB;
+if (fi->ap == NULL) fi->ap = alp;
if (installBinaryPackage(ts, hdrs[i], fi)) {
ourrc++;
lastFailed = i;
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e33952ea2..e07092ca8 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -44,6 +44,7 @@ lib/poptBT.c
lib/poptQV.c
lib/problems.c
lib/query.c
+lib/rollback.c
lib/rpmchecksig.c
lib/rpmdb.c
lib/rpminstall.c
diff --git a/po/rpm.pot b/po/rpm.pot
index 31e80a8f4..384059b6f 100644
--- a/po/rpm.pot
+++ b/po/rpm.pot
@@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2001-01-21 10:28-0500\n"
+"POT-Creation-Date: 2001-01-21 18:24-0500\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"
@@ -2190,55 +2190,55 @@ msgstr ""
msgid "line %d: Bad %s number: %s\n"
msgstr ""
-#: lib/cpio.c:445
+#: lib/cpio.c:508
#, c-format
msgid "can't rename %s to %s: %s\n"
msgstr ""
-#: lib/cpio.c:451
+#: lib/cpio.c:514
#, c-format
msgid "can't unlink %s: %s\n"
msgstr ""
-#: lib/cpio.c:758
+#: lib/cpio.c:820
#, c-format
msgid "getNextHeader: %s\n"
msgstr ""
-#: lib/cpio.c:1262
+#: lib/cpio.c:1320
#, c-format
msgid "(error 0x%x)"
msgstr ""
-#: lib/cpio.c:1265
+#: lib/cpio.c:1323
msgid "Bad magic"
msgstr ""
-#: lib/cpio.c:1266
+#: lib/cpio.c:1324
msgid "Bad/unreadable header"
msgstr ""
-#: lib/cpio.c:1284
+#: lib/cpio.c:1342
msgid "Header size too big"
msgstr ""
-#: lib/cpio.c:1285
+#: lib/cpio.c:1343
msgid "Unknown file type"
msgstr ""
-#: lib/cpio.c:1286
+#: lib/cpio.c:1344
msgid "Missing hard link"
msgstr ""
-#: lib/cpio.c:1287
+#: lib/cpio.c:1345
msgid "MD5 sum mismatch"
msgstr ""
-#: lib/cpio.c:1288
+#: lib/cpio.c:1346
msgid "Internal error"
msgstr ""
-#: lib/cpio.c:1297
+#: lib/cpio.c:1355
msgid " failed - "
msgstr ""
@@ -2517,7 +2517,7 @@ msgstr ""
msgid "dataLength() RPM_STRING_TYPE count must be 1.\n"
msgstr ""
-#: lib/header.c:207 lib/header.c:1015 lib/install.c:394
+#: lib/header.c:207 lib/header.c:1015 lib/install.c:395
#, c-format
msgid "Data type %d not supported\n"
msgstr ""
@@ -2602,17 +2602,17 @@ msgstr ""
msgid "(unknown type)"
msgstr ""
-#: lib/install.c:219
+#: lib/install.c:220
#, c-format
msgid " file: %s%s action: %s\n"
msgstr ""
-#: lib/install.c:244
+#: lib/install.c:246
#, c-format
msgid "user %s does not exist - using root\n"
msgstr ""
-#: lib/install.c:252
+#: lib/install.c:253
#, c-format
msgid "group %s does not exist - using root\n"
msgstr ""
@@ -2620,90 +2620,90 @@ 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:677
+#: lib/install.c:684
#, c-format
msgid "unpacking of archive failed%s%s: %s\n"
msgstr ""
-#: lib/install.c:678
+#: lib/install.c:685
msgid " on file "
msgstr ""
-#: lib/install.c:727
+#: lib/install.c:733
msgid "installing a source package\n"
msgstr ""
-#: lib/install.c:747
+#: lib/install.c:753
#, c-format
msgid "cannot create sourcedir %s\n"
msgstr ""
-#: lib/install.c:754 lib/install.c:785
+#: lib/install.c:760 lib/install.c:790
#, c-format
msgid "cannot write to %s\n"
msgstr ""
-#: lib/install.c:758
+#: lib/install.c:764
#, c-format
msgid "sources in: %s\n"
msgstr ""
-#: lib/install.c:778
+#: lib/install.c:784
#, c-format
msgid "cannot create specdir %s\n"
msgstr ""
-#: lib/install.c:789
+#: lib/install.c:794
#, c-format
msgid "spec file in: %s\n"
msgstr ""
-#: lib/install.c:821 lib/install.c:850
+#: lib/install.c:827 lib/install.c:857
msgid "source package contains no .spec file\n"
msgstr ""
-#: lib/install.c:868
+#: lib/install.c:877
#, c-format
msgid "renaming %s to %s\n"
msgstr ""
-#: lib/install.c:870 lib/install.c:1135 lib/uninstall.c:43
+#: lib/install.c:879 lib/install.c:1149 lib/uninstall.c:43
#, c-format
msgid "rename of %s to %s failed: %s\n"
msgstr ""
-#: lib/install.c:960
+#: lib/install.c:974
msgid "source package expected, binary found\n"
msgstr ""
-#: lib/install.c:1005
+#: lib/install.c:1013
#, c-format
msgid "package: %s-%s-%s files test = %d\n"
msgstr ""
-#: lib/install.c:1049
+#: lib/install.c:1054
msgid "stopping install as we're running --test\n"
msgstr ""
-#: lib/install.c:1054
+#: lib/install.c:1059
msgid "running preinstall script (if any)\n"
msgstr ""
-#: lib/install.c:1061
+#: lib/install.c:1066
msgid "skipping %s-%s-%s install, %%pre scriptlet failed rc %d\n"
msgstr ""
-#: lib/install.c:1095
+#: lib/install.c:1103
#, c-format
-msgid "%s created as %s\n"
+msgid "%s%s created as %s\n"
msgstr ""
-#: lib/install.c:1131
+#: lib/install.c:1144
#, c-format
msgid "%s saved as %s\n"
msgstr ""
-#: lib/install.c:1227
+#: lib/install.c:1229
msgid "running postinstall scripts (if any)\n"
msgstr ""
@@ -3554,7 +3554,7 @@ msgstr ""
msgid "Please contact rpm-list@redhat.com\n"
msgstr ""
-#: lib/scriptlet.c:233
+#: lib/scriptlet.c:241
#, c-format
msgid "execution of %s scriptlet from %s-%s-%s failed, exit status %d\n"
msgstr ""