- default instchangelog is set to 5
- headerRemoveEntry() didn't free the item's data -- this led to
a slight memory leak when installing packages
+ - implemented generic file relocations at install time
+ (use --relocate <oldpath>=<newpath>, i.e. --relocate /usr=/foo)
+ - added --badreloc flag to force RPM to relocate files which packages
+ haven't advertised as relocateable
2.4.99 -> 2.4.100:
- fixed handling of --rebuild and --recompile
char ** md5s;
char ** links;
char ** names;
+ char ** cpioNames;
struct fileInfo * files;
};
free(fileMem.md5s);
free(fileMem.links);
free(fileMem.names);
+ free(fileMem.cpioNames);
}
/* files should not be preallocated */
if (rawRelocations) {
if (!headerGetEntry(h, RPMTAG_PREFIXES, NULL,
- (void **) validRelocations, &numValid)) {
+ (void **) &validRelocations, &numValid)) {
numValid = 0;
}
- for (i = 0; rawRelocations[i].oldPath; i++) ;
+ for (i = 0; rawRelocations[i].newPath; i++) ;
numRelocations = i;
relocations = alloca(sizeof(*relocations) * numRelocations);
headerGetEntry(h, RPMTAG_FILENAMES, NULL, (void **) &mem->names,
fileCountPtr);
+ /* get this before we start mucking with this info */
+ headerGetEntry(h, RPMTAG_FILENAMES, NULL, (void **) &mem->cpioNames,
+ fileCountPtr);
fileCount = *fileCountPtr;
if (relocations) {
file->install = 1;
file->relativePath = mem->names[i];
- file->cpioPath = mem->names[i] + stripPrefixLength;
+ file->cpioPath = mem->cpioNames[i] + stripPrefixLength;
file->mode = fileModes[i];
file->md5 = mem->md5s[i];
file->link = mem->links[i];
defaultPrefix = strcpy(alloca(strlen(defaultPrefix) + 1),
defaultPrefix);
stripTrailingSlashes(defaultPrefix);
- stripSize = strlen(defaultPrefix);
+ stripSize = strlen(defaultPrefix) + 1;
headerAddEntry(h, RPMTAG_PREFIXES, RPM_STRING_ARRAY_TYPE,
&defaultPrefix, 1);
}
if (assembleFileList(h, &fileMem, &fileCount, &files, stripSize,
- relocations, 1)) {
- /*relocations, flags & RPMINSTALL_FORCERELOCATE | 1)) {*/
+ relocations, flags & RPMINSTALL_FORCERELOCATE)) {
if (rootdir) {
chroot(".");
chdir(currDir);
#define RPMTAG_ROOT 1038
#define RPMTAG_FILEUSERNAME 1039
#define RPMTAG_FILEGROUPNAME 1040
-#define RPMTAG_EXCLUDE 1041 /* not used - depricated */
-#define RPMTAG_EXCLUSIVE 1042 /* not used - depricated */
+#define RPMTAG_EXCLUDE 1041 /* internal - depricated */
+#define RPMTAG_EXCLUSIVE 1042 /* internal - depricated */
#define RPMTAG_ICON 1043
#define RPMTAG_SOURCERPM 1044
#define RPMTAG_FILEVERIFYFLAGS 1045
#define RPMTAG_CONFLICTFLAGS 1053
#define RPMTAG_CONFLICTNAME 1054
#define RPMTAG_CONFLICTVERSION 1055
-#define RPMTAG_DEFAULTPREFIX 1056 /* internal */
+#define RPMTAG_DEFAULTPREFIX 1056 /* internal - deprecated */
#define RPMTAG_BUILDROOT 1057
-#define RPMTAG_INSTALLPREFIX 1058
+#define RPMTAG_INSTALLPREFIX 1058 /* internal - deprecated */
#define RPMTAG_EXCLUDEARCH 1059
#define RPMTAG_EXCLUDEOS 1060
#define RPMTAG_EXCLUSIVEARCH 1061
#define RPMTAG_FILEINODES 1096
#define RPMTAG_FILELANGS 1097
#define RPMTAG_PREFIXES 1098
+#define RPMTAG_INSTPREFIXES 1099
#define RPMTAG_EXTERNAL_TAG 1000000
int child;
int status;
char upgradeArg[20];
- char * installPrefix = NULL;
- char * installPrefixEnv = NULL;
+ char ** prefixes = NULL;
+ int numPrefixes;
+ char * oldPrefix;
char * program;
char ** programArgv;
char ** argv = NULL;
int programType = 0;
int pipes[2];
int out = 0;
+ int freePrefixes = 0;
+ int maxPrefixLength;
+ char * prefixBuf;
+ int i;
if (norunScripts) return 0;
memcpy(programArgv, argv, programArgc * sizeof(char *));
}
- if (headerGetEntry(h, RPMTAG_INSTALLPREFIX, NULL, (void **) &installPrefix,
+ if (headerGetEntry(h, RPMTAG_INSTPREFIXES, NULL, (void **) prefixes,
+ &numPrefixes)) {
+ freePrefixes = 1;
+ } else if (headerGetEntry(h, RPMTAG_INSTALLPREFIX, NULL,
+ (void **) &oldPrefix,
NULL)) {
- installPrefixEnv = alloca(strlen(installPrefix) + 30);
- strcpy(installPrefixEnv, "RPM_INSTALL_PREFIX=");
- strcat(installPrefixEnv, installPrefix);
- strcat(installPrefixEnv, "\n");
+ prefixes = &oldPrefix;
+ numPrefixes = 1;
+ } else {
+ numPrefixes = 0;
}
+ maxPrefixLength = 0;
+ for (i = 0; i < numPrefixes; i++) {
+ child = strlen(prefixes[i]);
+ if (child > maxPrefixLength) maxPrefixLength = child;
+ }
+ prefixBuf = alloca(maxPrefixLength + 50);
+
rpmMessage(RPMMESS_DEBUG, "running inst helper %s\n", programArgv[0]);
if (script) {
!strcmp(programArgv[0], "/bin/bash")))
write(fd, "set -x\n", 7);
- if (installPrefixEnv)
- write(fd, installPrefixEnv, strlen(installPrefixEnv));
-
write(fd, script, strlen(script));
close(fd);
}
doputenv(SCRIPT_PATH);
- if (installPrefixEnv) {
- doputenv(installPrefixEnv);
+
+ for (i = 0; i < numPrefixes; i++) {
+ sprintf(prefixBuf, "RPM_INSTALL_PREFIX%d=%s", i, prefixes[i]);
+ doputenv(prefixBuf);
+
+ /* backwards compatibility */
+ if (!i) {
+ sprintf(prefixBuf, "RPM_INSTALL_PREFIX=%s", prefixes[i]);
+ doputenv(prefixBuf);
+ }
}
if (strcmp(root, "/")) {
waitpid(child, &status, 0);
+ if (freePrefixes) free(prefixes);
+
if (err) {
if (out > 2) close(out);
if (err > 2) close(err);
puts(_(" [--rcfile <file>] [--ignorearch] [--dbpath <dir>]"));
puts(_(" [--prefix <dir>] [--ignoreos] [--nodeps] [--allfiles]"));
puts(_(" [--ftpproxy <host>] [--ftpport <port>] [--justdb]"));
- puts(_(" [--noorder] file1.rpm ... fileN.rpm"));
+ puts(_(" [--noorder] [--relocate oldpath=newpath]"));
+ puts(_(" [--badreloc] file1.rpm ... fileN.rpm"));
puts(_(" rpm {--upgrade -U} [-v] [--hash -h] [--percent] [--force] [--test]"));
puts(_(" [--oldpackage] [--root <dir>] [--noscripts]"));
puts(_(" [--excludedocs] [--includedocs] [--rcfile <file>]"));
puts(_(" [--ignorearch] [--dbpath <dir>] [--prefix <dir>] "));
puts(_(" [--ftpproxy <host>] [--ftpport <port>]"));
puts(_(" [--ignoreos] [--nodeps] [--allfiles] [--justdb]"));
- puts(_(" [--noorder] file1.rpm ... fileN.rpm"));
+ puts(_(" [--noorder] [--relocate oldpath=newpath]"));
+ puts(_(" [--badreloc] file1.rpm ... fileN.rpm"));
puts(_(" rpm {--query -q} [-afpg] [-i] [-l] [-s] [-d] [-c] [-v] [-R]"));
puts(_(" [--scripts] [--root <dir>] [--rcfile <file>]"));
puts(_(" [--whatprovides] [--whatrequires] [--requires]"));
puts( " --install <packagefile>");
printHelpLine(" -i <packagefile> ",
_("install package"));
+ printHelpLine(" --relocate <oldpath>=<newpath>",
+ _("relocate files from <oldpath> to <newpath>"));
+ printHelpLine(" --badreloc",
+ _("relocate files even though the package doesn't allow it"));
printHelpLine(" --prefix <dir> ",
_("relocate the package to <dir>, if relocatable"));
printHelpLine(" --dbpath <dir> ",
int status;
int p[2];
struct rpmRelocation * relocations = NULL;
- int numRelocations = 0;
+ int numRelocations = 0, badReloc = 0;
struct poptOption optionsTable[] = {
{ "addsign", '\0', 0, 0, GETOPT_ADDSIGN },
{ "all", 'a', 0, 0, 'a' },
{ "allfiles", '\0', 0, &allFiles, 0 },
{ "allmatches", 'a', 0, &allMatches, 0 },
+ { "badreloc", '\0', 0, &badReloc, 0 },
{ "build", 'b', POPT_ARG_STRING, 0, 'b' },
{ "buildarch", '\0', POPT_ARG_STRING, 0, 0 },
{ "buildos", '\0', POPT_ARG_STRING, 0, 0 },
if (bigMode != MODE_INSTALL && force)
argerror(_("only installation and upgrading may be forced"));
+ if (bigMode != MODE_INSTALL && badReloc)
+ argerror(_("files may only be relocated during package installation"));
+
if (relocations && prefix)
argerror(_("only one of --prefix or --relocate may be used"));
if (force)
installFlags |= (RPMINSTALL_REPLACEPKG | RPMINSTALL_REPLACEFILES);
if (replaceFiles) installFlags |= RPMINSTALL_REPLACEFILES;
+ if (badReloc) installFlags |= RPMINSTALL_FORCERELOCATE;
if (replacePackages) installFlags |= RPMINSTALL_REPLACEPKG;
if (test) installFlags |= RPMINSTALL_TEST;
if (noScripts) installFlags |= RPMINSTALL_NOSCRIPTS;