supports relocateable packages
CVS patchset: 758 CVS date: 1996/07/10 02:33:38
This commit is contained in:
parent
abb42944a4
commit
5f0b82b4f5
146
lib/install.c
146
lib/install.c
|
@ -43,7 +43,7 @@ static int installArchive(char * prefix, int fd, struct fileToInstall * files,
|
|||
char ** installArchive);
|
||||
static int packageAlreadyInstalled(rpmdb db, char * name, char * version,
|
||||
char * release, int * recOffset, int flags);
|
||||
static int setFileOwnerships(char * prefix, char ** fileList,
|
||||
static int setFileOwnerships(char * rootdir, char ** fileList,
|
||||
char ** fileOwners, char ** fileGroups,
|
||||
int_16 * fileModes,
|
||||
enum instActions * instActions, int fileCount);
|
||||
|
@ -54,18 +54,20 @@ static int instHandleSharedFiles(rpmdb db, int ignoreOffset, char ** fileList,
|
|||
char ** fileMd5List, int_16 * fileModeList,
|
||||
char ** fileLinkList,
|
||||
int fileCount, enum instActions * instActions,
|
||||
char ** prefixedFileList, int * notErrors,
|
||||
char ** prootdirootdir, int * notErrors,
|
||||
struct replacedFile ** repListPtr, int flags);
|
||||
static int fileCompare(const void * one, const void * two);
|
||||
static int installSources(char * prefix, int fd, char ** specFilePtr);
|
||||
static int installSources(char * rootdir, int fd, char ** specFilePtr);
|
||||
static int markReplacedFiles(rpmdb db, struct replacedFile * replList);
|
||||
static int ensureOlder(rpmdb db, char * name, char * newVersion,
|
||||
char * newRelease, int dbOffset);
|
||||
static int relocateFilelist(Header * hp, char * defaultPrefix,
|
||||
char * newPrefix, int * relocationSize);
|
||||
|
||||
/* 0 success */
|
||||
/* 1 bad magic */
|
||||
/* 2 error */
|
||||
int rpmInstallSourcePackage(char * prefix, int fd, char ** specFile) {
|
||||
int rpmInstallSourcePackage(char * rootdir, int fd, char ** specFile) {
|
||||
int rc, isSource;
|
||||
Header h;
|
||||
|
||||
|
@ -79,14 +81,14 @@ int rpmInstallSourcePackage(char * prefix, int fd, char ** specFile) {
|
|||
|
||||
if (h) freeHeader(h);
|
||||
|
||||
return installSources(prefix, fd, specFile);
|
||||
return installSources(rootdir, fd, specFile);
|
||||
}
|
||||
|
||||
/* 0 success */
|
||||
/* 1 bad magic */
|
||||
/* 2 error */
|
||||
int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
|
||||
notifyFunction notify, char * labelFormat) {
|
||||
int rpmInstallPackage(char * rootdir, rpmdb db, int fd, char * location,
|
||||
int flags, notifyFunction notify, char * labelFormat) {
|
||||
int rc, isSource;
|
||||
char * name, * version, * release;
|
||||
Header h;
|
||||
|
@ -106,17 +108,19 @@ int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
|
|||
int normalState = 0;
|
||||
int otherOffset = 0;
|
||||
char * ext = NULL, * newpath;
|
||||
int prefixLength = strlen(prefix);
|
||||
int prefixLength = strlen(rootdir);
|
||||
char ** prefixedFileList = NULL;
|
||||
struct replacedFile * replacedList = NULL;
|
||||
char * sptr, * dptr;
|
||||
char * sptr, * dptr, * defaultPrefix;
|
||||
int length;
|
||||
dbIndexSet matches;
|
||||
int * oldVersions;
|
||||
int * intptr;
|
||||
int_8 * pkgArchNum;
|
||||
void * pkgArch;
|
||||
char * archivePrefix;
|
||||
int scriptArg;
|
||||
int relocationSize = 1; /* strip at least first / for cpio */
|
||||
|
||||
oldVersions = alloca(sizeof(int));
|
||||
*oldVersions = 0;
|
||||
|
@ -138,9 +142,26 @@ int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
|
|||
|
||||
if (h) freeHeader(h);
|
||||
|
||||
return installSources(prefix, fd, NULL);
|
||||
return installSources(rootdir, fd, NULL);
|
||||
}
|
||||
|
||||
if (location && !getEntry(h, RPMTAG_DEFAULTPREFIX, &type, (void *)
|
||||
&defaultPrefix, &fileCount)) {
|
||||
error(RPMERR_NORELOCATE, "package %s-%s-%s is not relocatable",
|
||||
name, version, release);
|
||||
freeHeader(h);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (location) {
|
||||
relocateFilelist(&h, defaultPrefix, location, &relocationSize);
|
||||
getEntry(h, RPMTAG_DEFAULTPREFIX, &type, (void *) &defaultPrefix,
|
||||
&fileCount);
|
||||
archivePrefix = alloca(strlen(rootdir) + strlen(location) + 2);
|
||||
sprintf(archivePrefix, "%s/%s", rootdir, location);
|
||||
} else
|
||||
archivePrefix = rootdir;
|
||||
|
||||
getEntry(h, RPMTAG_NAME, &type, (void **) &name, &fileCount);
|
||||
getEntry(h, RPMTAG_VERSION, &type, (void **) &version, &fileCount);
|
||||
getEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &fileCount);
|
||||
|
@ -239,7 +260,7 @@ int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
|
|||
if (prefixLength > 1) {
|
||||
prefixedFileList[i] = alloca(strlen(fileList[i]) +
|
||||
prefixLength + 3);
|
||||
strcpy(prefixedFileList[i], prefix);
|
||||
strcpy(prefixedFileList[i], rootdir);
|
||||
strcat(prefixedFileList[i], "/");
|
||||
strcat(prefixedFileList[i], fileList[i]);
|
||||
} else
|
||||
|
@ -281,7 +302,7 @@ int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
|
|||
}
|
||||
|
||||
message(MESS_DEBUG, "running preinstall script (if any)\n");
|
||||
if (runScript(prefix, h, RPMTAG_PREIN, scriptArg,
|
||||
if (runScript(rootdir, h, RPMTAG_PREIN, scriptArg,
|
||||
flags & INSTALL_NOSCRIPTS)) {
|
||||
free(fileList);
|
||||
if (replacedList) free(replacedList);
|
||||
|
@ -290,7 +311,7 @@ int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
|
|||
|
||||
if (fileList) {
|
||||
|
||||
if (createDirectories(prefix, fileList, fileCount)) {
|
||||
if (createDirectories(rootdir, fileList, fileCount)) {
|
||||
freeHeader(h);
|
||||
free(fileList);
|
||||
if (replacedList) free(replacedList);
|
||||
|
@ -358,10 +379,13 @@ int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
|
|||
/* 1) we skip over the leading /
|
||||
2) we have to escape globbing characters :-( */
|
||||
|
||||
/* if we are using a relocateable package, we need to strip
|
||||
off whatever part of the (already relocated!) filelist */
|
||||
|
||||
length = strlen(fileList[i]);
|
||||
files[archiveFileCount].fileName = alloca((length * 2) + 1);
|
||||
dptr = files[archiveFileCount].fileName;
|
||||
for (sptr = fileList[i] + 1; *sptr; sptr++) {
|
||||
for (sptr = fileList[i] + relocationSize; *sptr; sptr++) {
|
||||
switch (*sptr) {
|
||||
case '*': case '[': case ']': case '?': case '\\':
|
||||
*dptr++ = '\\';
|
||||
|
@ -384,7 +408,8 @@ int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
|
|||
}
|
||||
|
||||
/* the file pointer for fd is pointing at the cpio archive */
|
||||
if (installArchive(prefix, fd, files, archiveFileCount, notify, NULL)) {
|
||||
if (installArchive(archivePrefix, fd, files, archiveFileCount, notify,
|
||||
NULL)) {
|
||||
freeHeader(h);
|
||||
free(fileList);
|
||||
if (replacedList) free(replacedList);
|
||||
|
@ -395,7 +420,7 @@ int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
|
|||
&fileCount)) {
|
||||
if (getEntry(h, RPMTAG_FILEGROUPNAME, &type, (void **) &fileGroups,
|
||||
&fileCount)) {
|
||||
if (setFileOwnerships(prefix, fileList, fileOwners, fileGroups,
|
||||
if (setFileOwnerships(rootdir, fileList, fileOwners, fileGroups,
|
||||
fileModesList, instActions, fileCount)) {
|
||||
free(fileOwners);
|
||||
free(fileGroups);
|
||||
|
@ -438,7 +463,7 @@ int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
|
|||
|
||||
message(MESS_DEBUG, "running postinstall script (if any)\n");
|
||||
|
||||
if (runScript(prefix, h, RPMTAG_POSTIN, scriptArg,
|
||||
if (runScript(rootdir, h, RPMTAG_POSTIN, scriptArg,
|
||||
flags & INSTALL_NOSCRIPTS)) {
|
||||
return 2;
|
||||
}
|
||||
|
@ -447,7 +472,7 @@ int rpmInstallPackage(char * prefix, rpmdb db, int fd, int flags,
|
|||
message(MESS_DEBUG, "removing old versions of package\n");
|
||||
intptr = oldVersions;
|
||||
while (*intptr) {
|
||||
rpmRemovePackage(prefix, db, *intptr, 0);
|
||||
rpmRemovePackage(rootdir, db, *intptr, 0);
|
||||
intptr++;
|
||||
}
|
||||
}
|
||||
|
@ -706,7 +731,7 @@ static int packageAlreadyInstalled(rpmdb db, char * name, char * version,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int setFileOwnerships(char * prefix, char ** fileList,
|
||||
static int setFileOwnerships(char * rootdir, char ** fileList,
|
||||
char ** fileOwners, char ** fileGroups,
|
||||
int_16 * fileModesList,
|
||||
enum instActions * instActions, int fileCount) {
|
||||
|
@ -718,7 +743,7 @@ static int setFileOwnerships(char * prefix, char ** fileList,
|
|||
|
||||
message(MESS_DEBUG, "setting file owners and groups by name (not id)\n");
|
||||
|
||||
chptr = prefix;
|
||||
chptr = rootdir;
|
||||
while (*chptr && *chptr == '/')
|
||||
chptr++;
|
||||
|
||||
|
@ -731,7 +756,7 @@ static int setFileOwnerships(char * prefix, char ** fileList,
|
|||
waitpid(child, &status, 0);
|
||||
return 0;
|
||||
} else {
|
||||
chroot(prefix);
|
||||
chroot(rootdir);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1194,7 +1219,7 @@ static int fileCompare(const void * one, const void * two) {
|
|||
}
|
||||
|
||||
|
||||
static int installSources(char * prefix, int fd, char ** specFilePtr) {
|
||||
static int installSources(char * rootdir, int fd, char ** specFilePtr) {
|
||||
char * specFile;
|
||||
char * sourceDir, * specDir;
|
||||
char * realSourceDir, * realSpecDir;
|
||||
|
@ -1205,13 +1230,13 @@ static int installSources(char * prefix, int fd, char ** specFilePtr) {
|
|||
sourceDir = getVar(RPMVAR_SOURCEDIR);
|
||||
specDir = getVar(RPMVAR_SPECDIR);
|
||||
|
||||
realSourceDir = alloca(strlen(prefix) + strlen(sourceDir) + 2);
|
||||
strcpy(realSourceDir, prefix);
|
||||
realSourceDir = alloca(strlen(rootdir) + strlen(sourceDir) + 2);
|
||||
strcpy(realSourceDir, rootdir);
|
||||
strcat(realSourceDir, "/");
|
||||
strcat(realSourceDir, sourceDir);
|
||||
|
||||
realSpecDir = alloca(strlen(prefix) + strlen(specDir) + 2);
|
||||
strcpy(realSpecDir, prefix);
|
||||
realSpecDir = alloca(strlen(rootdir) + strlen(specDir) + 2);
|
||||
strcpy(realSpecDir, rootdir);
|
||||
strcat(realSpecDir, "/");
|
||||
strcat(realSpecDir, specDir);
|
||||
|
||||
|
@ -1353,3 +1378,72 @@ enum fileTypes whatis(short mode) {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* This is *much* more difficult then it should be. Rather then just
|
||||
modifying an entry with a single call to modifyEntry(), we have to
|
||||
clone most of the header. Once the internal data structures of
|
||||
header.c get cleaned up, this will be *much* easier */
|
||||
static int relocateFilelist(Header * hp, char * defaultPrefix,
|
||||
char * newPrefix, int * relocationLength) {
|
||||
Header newh, h = *hp;
|
||||
HeaderIterator it;
|
||||
char ** newFileList, ** fileList;
|
||||
int type, count, tag, fileCount, i;
|
||||
void * data;
|
||||
int defaultPrefixLength;
|
||||
int newPrefixLength;
|
||||
|
||||
/* a trailing '/' in the defaultPrefix or in the newPrefix would really
|
||||
confuse us */
|
||||
defaultPrefix = strcpy(alloca(strlen(defaultPrefix) + 1), defaultPrefix);
|
||||
stripTrailingSlashes(defaultPrefix);
|
||||
newPrefix = strcpy(alloca(strlen(newPrefix) + 1), newPrefix);
|
||||
stripTrailingSlashes(newPrefix);
|
||||
|
||||
if (!strcmp(newPrefix, defaultPrefix)) {
|
||||
*relocationLength = strlen(defaultPrefix);
|
||||
return 0; /* NOP */
|
||||
}
|
||||
|
||||
message(MESS_DEBUG, "relocating files from %s to %s\n", defaultPrefix,
|
||||
newPrefix);
|
||||
|
||||
defaultPrefixLength = strlen(defaultPrefix);
|
||||
newPrefixLength = strlen(newPrefix);
|
||||
|
||||
/* packages can have empty filelists */
|
||||
if (!getEntry(h, RPMTAG_FILENAMES, &type, (void *) &fileList, &fileCount))
|
||||
return 0;
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
newh = newHeader();
|
||||
it = initIterator(h);
|
||||
while (nextIterator(it, &tag, &type, &data, &count))
|
||||
if (tag != RPMTAG_FILENAMES)
|
||||
addEntry(newh, tag, type, data, count);
|
||||
|
||||
newFileList = alloca(sizeof(char *) * fileCount);
|
||||
for (i = 0; i < fileCount; i++) {
|
||||
if (!strncmp(fileList[i], defaultPrefix, defaultPrefixLength)) {
|
||||
newFileList[i] = alloca(strlen(fileList[i]) + newPrefixLength -
|
||||
defaultPrefixLength + 2);
|
||||
sprintf(newFileList[i], "%s/%s", newPrefix,
|
||||
fileList[i] + defaultPrefixLength + 1);
|
||||
} else {
|
||||
message(MESS_DEBUG, "BAD - unprefixed file in relocatable package");
|
||||
newFileList[i] = alloca(strlen(fileList[i]) -
|
||||
defaultPrefixLength + 2);
|
||||
sprintf(newFileList[i], "/%s", fileList[i] +
|
||||
defaultPrefixLength + 1);
|
||||
}
|
||||
}
|
||||
|
||||
addEntry(newh, RPMTAG_FILENAMES, STRING_ARRAY_TYPE, newFileList, fileCount);
|
||||
addEntry(newh, RPMTAG_INSTALLPREFIX, STRING_TYPE, newPrefix, 1);
|
||||
|
||||
*relocationLength = newPrefixLength + 1;
|
||||
*hp = newh;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue