fixed problems in file relocation
authorewt <devnull@localhost>
Thu, 29 Jan 1998 19:39:12 +0000 (19:39 +0000)
committerewt <devnull@localhost>
Thu, 29 Jan 1998 19:39:12 +0000 (19:39 +0000)
CVS patchset: 1980
CVS date: 1998/01/29 19:39:12

CHANGES
lib/install.c
lib/rpmlib.h
lib/uninstall.c
rpm.c

diff --git a/CHANGES b/CHANGES
index f059f08..7ae46e9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
        - 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
index 481a563..4017326 100644 (file)
@@ -43,6 +43,7 @@ struct fileMemory {
     char ** md5s;
     char ** links;
     char ** names;
+    char ** cpioNames;
     struct fileInfo * files;
 };
 
@@ -140,6 +141,7 @@ static void freeFileMemory(struct fileMemory fileMem) {
     free(fileMem.md5s);
     free(fileMem.links);
     free(fileMem.names);
+    free(fileMem.cpioNames);
 }
 
 /* files should not be preallocated */
@@ -165,11 +167,11 @@ static int assembleFileList(Header h, struct fileMemory * mem,
 
     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);
 
@@ -232,6 +234,9 @@ static int assembleFileList(Header h, struct fileMemory * mem,
 
     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) {
@@ -285,7 +290,7 @@ static int assembleFileList(Header h, struct fileMemory * mem,
        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];
@@ -596,7 +601,7 @@ int rpmInstallPackage(char * rootdir, rpmdb db, int fd,
            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); 
@@ -606,8 +611,7 @@ int rpmInstallPackage(char * rootdir, rpmdb db, int fd,
        }
 
        if (assembleFileList(h, &fileMem, &fileCount, &files, stripSize,
-                            relocations, 1)) {
-                            /*relocations, flags & RPMINSTALL_FORCERELOCATE | 1)) {*/
+                            relocations, flags & RPMINSTALL_FORCERELOCATE)) {
            if (rootdir) {
                chroot(".");
                chdir(currDir);
index f416ab3..9153cd7 100644 (file)
@@ -66,8 +66,8 @@ extern const struct headerSprintfExtension rpmHeaderFormats[];
 #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
@@ -81,9 +81,9 @@ extern const struct headerSprintfExtension rpmHeaderFormats[];
 #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
@@ -115,6 +115,7 @@ extern const struct headerSprintfExtension rpmHeaderFormats[];
 #define RPMTAG_FILEINODES               1096
 #define RPMTAG_FILELANGS                1097
 #define RPMTAG_PREFIXES                 1098
+#define RPMTAG_INSTPREFIXES             1099
 
 #define RPMTAG_EXTERNAL_TAG            1000000
 
index 118eebf..44b668d 100644 (file)
@@ -330,8 +330,9 @@ int runScript(char * root, Header h, int scriptTag, int progTag,
     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;
@@ -339,6 +340,10 @@ int runScript(char * root, Header h, int scriptTag, int progTag,
     int programType = 0;
     int pipes[2];
     int out = 0;
+    int freePrefixes = 0;
+    int maxPrefixLength;
+    char * prefixBuf;
+    int i;
 
     if (norunScripts) return 0;
 
@@ -367,14 +372,25 @@ int runScript(char * root, Header h, int scriptTag, int progTag,
        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) {
@@ -390,9 +406,6 @@ int runScript(char * root, Header h, int scriptTag, int progTag,
             !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);
 
@@ -429,8 +442,16 @@ int runScript(char * root, Header h, int scriptTag, int progTag,
        }
 
        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, "/")) {
@@ -446,6 +467,8 @@ int runScript(char * root, Header h, int scriptTag, int progTag,
 
     waitpid(child, &status, 0);
 
+    if (freePrefixes) free(prefixes);
+
     if (err) {
        if (out > 2) close(out);
        if (err > 2) close(err);
diff --git a/rpm.c b/rpm.c
index ff5d32f..713f028 100755 (executable)
--- a/rpm.c
+++ b/rpm.c
@@ -90,14 +90,16 @@ static void printUsage(void) {
     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]"));
@@ -245,6 +247,10 @@ static void printHelp(void) {
     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>      ",
@@ -411,12 +417,13 @@ int main(int argc, char ** argv) {
     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 },
@@ -852,6 +859,9 @@ int main(int argc, char ** argv) {
     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"));
 
@@ -1154,6 +1164,7 @@ int main(int argc, char ** argv) {
        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;