Eliminate static prototypes.
authorjbj <devnull@localhost>
Tue, 13 Jul 1999 22:53:46 +0000 (22:53 +0000)
committerjbj <devnull@localhost>
Tue, 13 Jul 1999 22:53:46 +0000 (22:53 +0000)
CVS patchset: 3150
CVS date: 1999/07/13 22:53:46

lib/install.c

index 0f1883a..67fca55 100644 (file)
@@ -36,21 +36,6 @@ struct fileInfo {
     int install;
 } ;
 
-static int installArchive(FD_t fd, struct fileInfo * files,
-                         int fileCount, rpmCallbackFunction notify, 
-                         void * notifydb, const void * pkgKey, Header h,
-                         char ** specFile, int archiveSize);
-static int installSources(Header h, const char * rootdir, FD_t fd, 
-                         const char ** specFilePtr, rpmCallbackFunction notify,
-                         void * notifyData);
-static int assembleFileList(Header h, struct fileMemory * mem, 
-                            int * fileCountPtr, struct fileInfo ** filesPtr, 
-                            int stripPrefixLength, enum fileActions * actions);
-static void setFileOwners(Header h, struct fileInfo * files, int fileCount);
-static void freeFileMemory(struct fileMemory fileMem);
-static void trimChangelog(Header h);
-static int markReplacedFiles(rpmdb db, struct sharedFileInfo * replList);
-
 /* XXX add more tags */
 static struct tagMacro {
        const char *    macroname;
@@ -62,7 +47,8 @@ static struct tagMacro {
        { NULL, 0 }
 };
 
-static int rpmInstallLoadMacros(Header h) {
+static int rpmInstallLoadMacros(Header h)
+{
     struct tagMacro *tagm;
     const char *body;
     int type;
@@ -76,48 +62,8 @@ static int rpmInstallLoadMacros(Header h) {
     return 0;
 }
 
-/* 0 success */
-/* 1 bad magic */
-/* 2 error */
-int rpmInstallSourcePackage(const char * rootdir, FD_t fd, 
-                           const char ** specFile, rpmCallbackFunction notify, 
-                           void * notifyData, char ** cookie) {
-    int rc, isSource;
-    Header h;
-    int major, minor;
-
-    rc = rpmReadPackageHeader(fd, &h, &isSource, &major, &minor);
-    if (rc) return rc;
-
-    if (!isSource) {
-       rpmError(RPMERR_NOTSRPM, _("source package expected, binary found"));
-       return 2;
-    }
-
-#if defined(ENABLE_V1_PACKAGES)
-    if (major == 1) {
-       notify = NULL;
-       h = NULL;
-    }
-#endif /* ENABLE_V1_PACKAGES */
-
-    if (cookie) {
-       *cookie = NULL;
-       if (h && headerGetEntry(h, RPMTAG_COOKIE, NULL, (void **) cookie,
-                               NULL)) {
-           *cookie = strdup(*cookie);
-       }
-    }
-
-    rpmInstallLoadMacros(h);
-    
-    rc = installSources(h, rootdir, fd, specFile, notify, notifyData);
-    if (h != NULL) headerFree(h);
-    return rc;
-}
-
-static void freeFileMemory(struct fileMemory fileMem) {
+static void freeFileMemory(struct fileMemory fileMem)
+{
     free(fileMem.files);
     free(fileMem.names);
     free(fileMem.cpioNames);
@@ -127,7 +73,8 @@ static void freeFileMemory(struct fileMemory fileMem) {
 static int assembleFileList(Header h, struct fileMemory * mem, 
                             int * fileCountPtr, struct fileInfo ** filesPtr, 
                             int stripPrefixLength, 
-                            enum fileActions * actions) {
+                            enum fileActions * actions)
+{
     uint_32 * fileFlags;
     uint_32 * fileSizes;
     uint_16 * fileModes;
@@ -175,7 +122,8 @@ static int assembleFileList(Header h, struct fileMemory * mem,
     return 0;
 }
 
-static void setFileOwners(Header h, struct fileInfo * files, int fileCount) {
+static void setFileOwners(Header h, struct fileInfo * files, int fileCount)
+{
     char ** fileOwners;
     char ** fileGroups;
     int i;
@@ -205,7 +153,8 @@ static void setFileOwners(Header h, struct fileInfo * files, int fileCount) {
     free(fileGroups);
 }
 
-static void trimChangelog(Header h) {
+static void trimChangelog(Header h)
+{
     int * times;
     char ** names, ** texts;
     long numToKeep;
@@ -254,370 +203,141 @@ static void trimChangelog(Header h) {
     free(texts);
 }
 
-/* 0 success */
-/* 1 bad magic */
-/* 2 error */
-int installBinaryPackage(const char * rootdir, rpmdb db, FD_t fd, Header h,
-                        int flags, rpmCallbackFunction notify, 
-                        void * notifyData, const void * pkgKey, 
-                        enum fileActions * actions, 
-                        struct sharedFileInfo * sharedList, FD_t scriptFd) {
-    int rc;
-    char * name, * version, * release;
-    int fileCount, type, count;
-    struct fileInfo * files;
-    int_32 installTime;
-    char * fileStates;
-    int i;
-    int installFile = 0;
-    int otherOffset = 0;
-    char * ext = NULL, * newpath;
-    char * defaultPrefix;
-    dbiIndexSet matches;
-    int scriptArg;
-    int stripSize = 1;         /* strip at least first / for cpio */
-    uint_32 * archiveSizePtr;
-    struct fileMemory fileMem;
-    int freeFileMem = 0;
-    char * currDir = NULL, * tmpptr;
+static int markReplacedFiles(rpmdb db, struct sharedFileInfo * replList)
+{
+    struct sharedFileInfo * fileInfo;
+    Header secHeader = NULL, sh;
+    char * secStates;
+    int type, count;
+    
+    int secOffset = 0;
 
-    if (flags & RPMTRANS_FLAG_JUSTDB)
-       flags |= RPMTRANS_FLAG_NOSCRIPTS;
+    for (fileInfo = replList; fileInfo->otherPkg; fileInfo++) {
+       if (secOffset != fileInfo->otherPkg) {
+           if (secHeader != NULL) {
+               /* ignore errors here - just do the best we can */
 
-    headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &fileCount);
-    headerGetEntry(h, RPMTAG_VERSION, &type, (void **) &version, &fileCount);
-    headerGetEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &fileCount);
+               rpmdbUpdateRecord(db, secOffset, secHeader);
+               headerFree(secHeader);
+           }
 
-    rpmMessage(RPMMESS_DEBUG, _("package: %s-%s-%s files test = %d\n"), 
-               name, version, release, flags & RPMTRANS_FLAG_TEST);
+           secOffset = fileInfo->otherPkg;
+           sh = rpmdbGetRecord(db, secOffset);
+           if (sh == NULL) {
+               secOffset = 0;
+           } else {
+               secHeader = headerCopy(sh);     /* so we can modify it */
+               headerFree(sh);
+           }
 
-    rc = rpmdbFindPackage(db, name, &matches);
-    if (rc == -1) return 2;
-    if (rc) {
-       scriptArg = 1;
-    } else {
-       scriptArg = dbiIndexSetCount(matches) + 1;
-       dbiFreeIndexRecord(matches);
-    }
+           headerGetEntry(secHeader, RPMTAG_FILESTATES, &type, 
+                          (void **) &secStates, &count);
+       }
 
-    if (!rpmdbFindByHeader(db, h, &matches)) {
-       otherOffset = matches.recs[0].recOffset;
-       dbiFreeIndexRecord(matches);
+       /* by now, secHeader is the right header to modify, secStates is
+          the right states list to modify  */
+       
+       secStates[fileInfo->otherFileNum] = RPMFILE_STATE_REPLACED;
     }
 
-    if (rootdir) {
-       /* this loads all of the name services libraries, in case we
-          don't have access to them in the chroot() */
-       (void)getpwnam("root");
-       endpwent();
-
-       tmpptr = currentDirectory();
-       currDir = alloca(strlen(tmpptr) + 1);
-       strcpy(currDir, tmpptr);
-       free(tmpptr);
+    if (secHeader != NULL) {
+       /* ignore errors here - just do the best we can */
 
-       chdir("/");
-       chroot(rootdir);
+       rpmdbUpdateRecord(db, secOffset, secHeader);
+       headerFree(secHeader);
     }
 
-    if (!(flags & RPMTRANS_FLAG_JUSTDB) && headerIsEntry(h, RPMTAG_FILENAMES)) {
-       /* 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;
-       }
+    return 0;
+}
 
-       if (assembleFileList(h, &fileMem, &fileCount, &files, stripSize,
-                            actions)) {
-           if (rootdir) {
-               chroot(".");
-               chdir(currDir);
-           }
-           return 2;
-       }
+static void callback(struct cpioCallbackInfo * cpioInfo, void * data)
+{
+    struct callbackInfo * ourInfo = data;
+    char * chptr;
 
-       freeFileMem = 1;
-    } else {
-       files = NULL;
+    if (ourInfo->notify)
+       ourInfo->notify(ourInfo->h, RPMCALLBACK_INST_PROGRESS,
+                       cpioInfo->bytesProcessed, 
+                       ourInfo->archiveSize, ourInfo->pkgKey, 
+                       ourInfo->notifyData);
+
+    if (ourInfo->specFilePtr) {
+       chptr = cpioInfo->file + strlen(cpioInfo->file) - 5;
+       if (!strcmp(chptr, ".spec")) 
+           *ourInfo->specFilePtr = strdup(cpioInfo->file);
     }
-    
-    if (flags & RPMTRANS_FLAG_TEST) {
-       if (rootdir) {
-           chroot(".");
-           chdir(currDir);
-       }
+}
 
-       rpmMessage(RPMMESS_DEBUG, _("stopping install as we're running --test\n"));
-       if (freeFileMem) freeFileMemory(fileMem);
+/* NULL files means install all files */
+static int installArchive(FD_t fd, struct fileInfo * files,
+                         int fileCount, rpmCallbackFunction notify, 
+                         void * notifyData, const void * pkgKey, Header h,
+                         char ** specFile, int archiveSize)
+{
+    int rc, i;
+    struct cpioFileMapping * map = NULL;
+    int mappedFiles = 0;
+    char * failedFile;
+    struct callbackInfo info;
+
+    if (!files) {
+       /* install all files */
+       fileCount = 0;
+    } else if (!fileCount) {
+       /* no files to install */
        return 0;
     }
 
-    rpmMessage(RPMMESS_DEBUG, _("running preinstall script (if any)\n"));
-    if (runInstScript("/", h, RPMTAG_PREIN, RPMTAG_PREINPROG, scriptArg, 
-                     flags & RPMTRANS_FLAG_NOSCRIPTS, scriptFd)) {
-       if (freeFileMem) freeFileMemory(fileMem);
+    info.archiveSize = archiveSize;
+    info.notify = notify;
+    info.notifyData = notifyData;
+    info.specFilePtr = specFile;
+    info.h = h;
+    info.pkgKey = pkgKey;
 
-       if (rootdir) {
-           chroot(".");
-           chdir(currDir);
+    if (specFile) *specFile = NULL;
+
+    if (files) {
+       map = alloca(sizeof(*map) * fileCount);
+       for (i = 0, mappedFiles = 0; i < fileCount; i++) {
+           if (!files[i].install) continue;
+
+           map[mappedFiles].archivePath = files[i].cpioPath;
+           map[mappedFiles].fsPath = files[i].relativePath;
+           map[mappedFiles].finalMode = files[i].mode;
+           map[mappedFiles].finalUid = files[i].uid;
+           map[mappedFiles].finalGid = files[i].gid;
+           map[mappedFiles].mapFlags = CPIO_MAP_PATH | CPIO_MAP_MODE | 
+                                       CPIO_MAP_UID | CPIO_MAP_GID;
+           mappedFiles++;
        }
 
-       return 2;
+       qsort(map, mappedFiles, sizeof(*map), cpioFileMapCmp);
     }
 
-    if (files) {
-       setFileOwners(h, files, fileCount);
+    if (notify)
+       notify(h, RPMCALLBACK_INST_PROGRESS, 0, archiveSize, pkgKey, 
+              notifyData);
 
-       for (i = 0; i < fileCount; i++) {
-           switch (files[i].action) {
-             case FA_BACKUP:
-               ext = ".rpmorig";
-               installFile = 1;
-               break;
+  { CFD_t cfdbuf, *cfd = &cfdbuf;
+    cfd->cpioIoType = cpioIoTypeGzFd;
+    cfd->cpioGzFd = gzdFdopen(fdDup(fdFileno(fd)), "r");
+    rc = cpioInstallArchive(cfd, map, mappedFiles, 
+                           ((notify && archiveSize) || specFile) ? 
+                               callback : NULL, 
+                           &info, &failedFile);
+    gzdClose(cfd->cpioGzFd);
+  }
 
-             case FA_ALTNAME:
-               ext = NULL;
-               installFile = 1;
-
-               newpath = alloca(strlen(files[i].relativePath) + 20);
-               strcpy(newpath, files[i].relativePath);
-               strcat(newpath, ".rpmnew");
-               rpmError(RPMMESS_ALTNAME, _("warning: %s created as %s"),
-                       files[i].relativePath, newpath);
-               files[i].relativePath = newpath;
-               
-               break;
-
-             case FA_SAVE:
-               ext = ".rpmsave";
-               installFile = 1;
-               break;
-
-             case FA_CREATE:
-               installFile = 1;
-               ext = NULL;
-               break;
-
-             case FA_SKIP:
-               installFile = 0;
-               ext = NULL;
-               break;
-
-             case FA_SKIPNSTATE:
-               installFile = 0;
-               ext = NULL;
-               files[i].state = RPMFILE_STATE_NOTINSTALLED;
-               break;
-
-             case FA_UNKNOWN:
-             case FA_REMOVE:
-               break;
-           }
-
-           if (ext) {
-               newpath = alloca(strlen(files[i].relativePath) + 20);
-               strcpy(newpath, files[i].relativePath);
-               strcat(newpath, ext);
-               rpmError(RPMMESS_BACKUP, _("warning: %s saved as %s"), 
-                       files[i].relativePath, newpath);
-
-               if (rename(files[i].relativePath, newpath)) {
-                   rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s"),
-                         files[i].relativePath, newpath, strerror(errno));
-                   if (freeFileMem) freeFileMemory(fileMem);
-
-                   if (rootdir) {
-                       chroot(".");
-                       chdir(currDir);
-                   }
-
-                   return 2;
-               }
-           }
-
-           if (!installFile) {
-               files[i].install = 0;
-           }
-       }
-
-       if (!headerGetEntry(h, RPMTAG_ARCHIVESIZE, &type, 
-                               (void **) &archiveSizePtr, &count))
-           archiveSizePtr = NULL;
-
-       if (notify) {
-           notify(h, RPMCALLBACK_INST_START, 0, 0, pkgKey, notifyData);
-       }
-
-       /* the file pointer for fd is pointing at the cpio archive */
-       if (installArchive(fd, files, fileCount, notify, notifyData, pkgKey, h,
-                          NULL, archiveSizePtr ? *archiveSizePtr : 0)) {
-           headerFree(h);
-           if (freeFileMem) freeFileMemory(fileMem);
-
-           if (rootdir) {
-               chroot(".");
-               chdir(currDir);
-           }
-
-           return 2;
-       }
-
-       fileStates = malloc(sizeof(*fileStates) * fileCount);
-       for (i = 0; i < fileCount; i++)
-           fileStates[i] = files[i].state;
-
-       headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fileStates, 
-                       fileCount);
-
-       free(fileStates);
-       if (freeFileMem) freeFileMemory(fileMem);
-    } else if (flags & RPMTRANS_FLAG_JUSTDB) {
-       if (headerGetEntry(h, RPMTAG_FILENAMES, NULL, NULL, &fileCount)) {
-           fileStates = malloc(sizeof(*fileStates) * fileCount);
-           memset(fileStates, RPMFILE_STATE_NORMAL, fileCount);
-           headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fileStates, 
-                           fileCount);
-           free(fileStates);
-       }
-    }
-
-    installTime = time(NULL);
-    headerAddEntry(h, RPMTAG_INSTALLTIME, RPM_INT32_TYPE, &installTime, 1);
-
-    if (rootdir) {
-       chroot(".");
-       chdir(currDir);
-    }
-
-    trimChangelog(h);
-
-    /* if this package has already been installed, remove it from the database
-       before adding the new one */
-    if (otherOffset) {
-        rpmdbRemove(db, otherOffset, 1);
-    }
-
-    if (rpmdbAdd(db, h)) {
-       headerFree(h);
-       return 2;
-    }
-
-    rpmMessage(RPMMESS_DEBUG, _("running postinstall script (if any)\n"));
-
-    if (runInstScript(rootdir, h, RPMTAG_POSTIN, RPMTAG_POSTINPROG, scriptArg,
-                     flags & RPMTRANS_FLAG_NOSCRIPTS, scriptFd)) {
-       return 2;
-    }
-
-    if (!(flags & RPMTRANS_FLAG_NOTRIGGERS)) {
-       /* Run triggers this package sets off */
-       if (runTriggers(rootdir, db, RPMSENSE_TRIGGERIN, h, 0, scriptFd)) {
-           return 2;
-       }
-
-       /* Run triggers in this package which are set off by other things in
-          the database. */
-       if (runImmedTriggers(rootdir, db, RPMSENSE_TRIGGERIN, h, 0, scriptFd)) {
-           return 2;
-       }
-    }
-
-    if (sharedList) 
-       markReplacedFiles(db, sharedList);
-
-    return 0;
-}
-
-static void callback(struct cpioCallbackInfo * cpioInfo, void * data) {
-    struct callbackInfo * ourInfo = data;
-    char * chptr;
-
-    if (ourInfo->notify)
-       ourInfo->notify(ourInfo->h, RPMCALLBACK_INST_PROGRESS,
-                       cpioInfo->bytesProcessed, 
-                       ourInfo->archiveSize, ourInfo->pkgKey, 
-                       ourInfo->notifyData);
-
-    if (ourInfo->specFilePtr) {
-       chptr = cpioInfo->file + strlen(cpioInfo->file) - 5;
-       if (!strcmp(chptr, ".spec")) 
-           *ourInfo->specFilePtr = strdup(cpioInfo->file);
-    }
-}
-
-/* NULL files means install all files */
-static int installArchive(FD_t fd, struct fileInfo * files,
-                         int fileCount, rpmCallbackFunction notify, 
-                         void * notifyData, const void * pkgKey, Header h,
-                         char ** specFile, int archiveSize) {
-    int rc, i;
-    struct cpioFileMapping * map = NULL;
-    int mappedFiles = 0;
-    char * failedFile;
-    struct callbackInfo info;
-
-    if (!files) {
-       /* install all files */
-       fileCount = 0;
-    } else if (!fileCount) {
-       /* no files to install */
-       return 0;
-    }
-
-    info.archiveSize = archiveSize;
-    info.notify = notify;
-    info.notifyData = notifyData;
-    info.specFilePtr = specFile;
-    info.h = h;
-    info.pkgKey = pkgKey;
-
-    if (specFile) *specFile = NULL;
-
-    if (files) {
-       map = alloca(sizeof(*map) * fileCount);
-       for (i = 0, mappedFiles = 0; i < fileCount; i++) {
-           if (!files[i].install) continue;
-
-           map[mappedFiles].archivePath = files[i].cpioPath;
-           map[mappedFiles].fsPath = files[i].relativePath;
-           map[mappedFiles].finalMode = files[i].mode;
-           map[mappedFiles].finalUid = files[i].uid;
-           map[mappedFiles].finalGid = files[i].gid;
-           map[mappedFiles].mapFlags = CPIO_MAP_PATH | CPIO_MAP_MODE | 
-                                       CPIO_MAP_UID | CPIO_MAP_GID;
-           mappedFiles++;
-       }
-
-       qsort(map, mappedFiles, sizeof(*map), cpioFileMapCmp);
-    }
-
-    if (notify)
-       notify(h, RPMCALLBACK_INST_PROGRESS, 0, archiveSize, pkgKey, 
-              notifyData);
-
-  { CFD_t cfdbuf, *cfd = &cfdbuf;
-    cfd->cpioIoType = cpioIoTypeGzFd;
-    cfd->cpioGzFd = gzdFdopen(fdDup(fdFileno(fd)), "r");
-    rc = cpioInstallArchive(cfd, map, mappedFiles, 
-                           ((notify && archiveSize) || specFile) ? 
-                               callback : NULL, 
-                           &info, &failedFile);
-    gzdClose(cfd->cpioGzFd);
-  }
-
-    if (rc) {
-       /* this would probably be a good place to check if disk space
-          was used up - if so, we should return a different error */
-       rpmError(RPMERR_CPIO, _("unpacking of archive failed%s%s: %s"), 
-               (failedFile != NULL ? _(" on file ") : ""),
-               (failedFile != NULL ? failedFile : ""),
-               cpioStrerror(rc));
-       return 1;
-    }
+    if (rc) {
+       /* this would probably be a good place to check if disk space
+          was used up - if so, we should return a different error */
+       rpmError(RPMERR_CPIO, _("unpacking of archive failed%s%s: %s"), 
+               (failedFile != NULL ? _(" on file ") : ""),
+               (failedFile != NULL ? failedFile : ""),
+               cpioStrerror(rc));
+       return 1;
+    }
 
     if (notify && archiveSize)
        notify(h, RPMCALLBACK_INST_PROGRESS, archiveSize, archiveSize, 
@@ -634,7 +354,8 @@ static int installArchive(FD_t fd, struct fileInfo * files,
 /* 2 error */
 static int installSources(Header h, const char * rootdir, FD_t fd, 
                          const char ** specFilePtr, rpmCallbackFunction notify,
-                         void * notifyData) {
+                         void * notifyData)
+{
     char * specFile;
     int specFileIndex = -1;
     const char * realSourceDir = NULL;
@@ -811,62 +532,17 @@ exit:
     return rc;
 }
 
-static int markReplacedFiles(rpmdb db, struct sharedFileInfo * replList) {
-    struct sharedFileInfo * fileInfo;
-    Header secHeader = NULL, sh;
-    char * secStates;
-    int type, count;
-    
-    int secOffset = 0;
-
-    for (fileInfo = replList; fileInfo->otherPkg; fileInfo++) {
-       if (secOffset != fileInfo->otherPkg) {
-           if (secHeader != NULL) {
-               /* ignore errors here - just do the best we can */
+int rpmVersionCompare(Header first, Header second)
+{
+    char * one, * two;
+    int_32 * epochOne, * epochTwo;
+    int rc;
 
-               rpmdbUpdateRecord(db, secOffset, secHeader);
-               headerFree(secHeader);
-           }
-
-           secOffset = fileInfo->otherPkg;
-           sh = rpmdbGetRecord(db, secOffset);
-           if (sh == NULL) {
-               secOffset = 0;
-           } else {
-               secHeader = headerCopy(sh);     /* so we can modify it */
-               headerFree(sh);
-           }
-
-           headerGetEntry(secHeader, RPMTAG_FILESTATES, &type, 
-                          (void **) &secStates, &count);
-       }
-
-       /* by now, secHeader is the right header to modify, secStates is
-          the right states list to modify  */
-       
-       secStates[fileInfo->otherFileNum] = RPMFILE_STATE_REPLACED;
-    }
-
-    if (secHeader != NULL) {
-       /* ignore errors here - just do the best we can */
-
-       rpmdbUpdateRecord(db, secOffset, secHeader);
-       headerFree(secHeader);
-    }
-
-    return 0;
-}
-
-int rpmVersionCompare(Header first, Header second) {
-    char * one, * two;
-    int_32 * epochOne, * epochTwo;
-    int rc;
-
-    if (!headerGetEntry(first, RPMTAG_EPOCH, NULL, (void **) &epochOne, NULL))
-       epochOne = NULL;
-    if (!headerGetEntry(second, RPMTAG_EPOCH, NULL, (void **) &epochTwo, 
-                       NULL))
-       epochTwo = NULL;
+    if (!headerGetEntry(first, RPMTAG_EPOCH, NULL, (void **) &epochOne, NULL))
+       epochOne = NULL;
+    if (!headerGetEntry(second, RPMTAG_EPOCH, NULL, (void **) &epochTwo, 
+                       NULL))
+       epochTwo = NULL;
 
     if (epochOne && !epochTwo) 
        return 1;
@@ -892,7 +568,8 @@ int rpmVersionCompare(Header first, Header second) {
     return rpmvercmp(one, two);
 }
 
-const char * fileActionString(enum fileActions a) {
+const char * fileActionString(enum fileActions a)
+{
     switch (a) {
       case FA_UNKNOWN: return "unknown";
       case FA_CREATE: return "create";
@@ -906,3 +583,324 @@ const char * fileActionString(enum fileActions a) {
 
     return "???";
 }
+
+/* 0 success */
+/* 1 bad magic */
+/* 2 error */
+int rpmInstallSourcePackage(const char * rootdir, FD_t fd, 
+                           const char ** specFile, rpmCallbackFunction notify, 
+                           void * notifyData, char ** cookie)
+{
+    int rc, isSource;
+    Header h;
+    int major, minor;
+
+    rc = rpmReadPackageHeader(fd, &h, &isSource, &major, &minor);
+    if (rc) return rc;
+
+    if (!isSource) {
+       rpmError(RPMERR_NOTSRPM, _("source package expected, binary found"));
+       return 2;
+    }
+
+#if defined(ENABLE_V1_PACKAGES)
+    if (major == 1) {
+       notify = NULL;
+       h = NULL;
+    }
+#endif /* ENABLE_V1_PACKAGES */
+
+    if (cookie) {
+       *cookie = NULL;
+       if (h && headerGetEntry(h, RPMTAG_COOKIE, NULL, (void **) cookie,
+                               NULL)) {
+           *cookie = strdup(*cookie);
+       }
+    }
+
+    rpmInstallLoadMacros(h);
+    
+    rc = installSources(h, rootdir, fd, specFile, notify, notifyData);
+    if (h != NULL) headerFree(h);
+    return rc;
+}
+
+/* 0 success */
+/* 1 bad magic */
+/* 2 error */
+int installBinaryPackage(const char * rootdir, rpmdb db, FD_t fd, Header h,
+                        int flags, rpmCallbackFunction notify, 
+                        void * notifyData, const void * pkgKey, 
+                        enum fileActions * actions, 
+                        struct sharedFileInfo * sharedList, FD_t scriptFd)
+{
+    int rc;
+    char * name, * version, * release;
+    int fileCount, type, count;
+    struct fileInfo * files;
+    int_32 installTime;
+    char * fileStates;
+    int i;
+    int installFile = 0;
+    int otherOffset = 0;
+    char * ext = NULL, * newpath;
+    char * defaultPrefix;
+    dbiIndexSet matches;
+    int scriptArg;
+    int stripSize = 1;         /* strip at least first / for cpio */
+    uint_32 * archiveSizePtr;
+    struct fileMemory fileMem;
+    int freeFileMem = 0;
+    char * currDir = NULL, * tmpptr;
+
+    if (flags & RPMTRANS_FLAG_JUSTDB)
+       flags |= RPMTRANS_FLAG_NOSCRIPTS;
+
+    headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &fileCount);
+    headerGetEntry(h, RPMTAG_VERSION, &type, (void **) &version, &fileCount);
+    headerGetEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &fileCount);
+
+    rpmMessage(RPMMESS_DEBUG, _("package: %s-%s-%s files test = %d\n"), 
+               name, version, release, flags & RPMTRANS_FLAG_TEST);
+
+    rc = rpmdbFindPackage(db, name, &matches);
+    if (rc == -1) return 2;
+    if (rc) {
+       scriptArg = 1;
+    } else {
+       scriptArg = dbiIndexSetCount(matches) + 1;
+       dbiFreeIndexRecord(matches);
+    }
+
+    if (!rpmdbFindByHeader(db, h, &matches)) {
+       otherOffset = matches.recs[0].recOffset;
+       dbiFreeIndexRecord(matches);
+    }
+
+    if (rootdir) {
+       /* this loads all of the name services libraries, in case we
+          don't have access to them in the chroot() */
+       (void)getpwnam("root");
+       endpwent();
+
+       tmpptr = currentDirectory();
+       currDir = alloca(strlen(tmpptr) + 1);
+       strcpy(currDir, tmpptr);
+       free(tmpptr);
+
+       chdir("/");
+       chroot(rootdir);
+    }
+
+    if (!(flags & RPMTRANS_FLAG_JUSTDB) && headerIsEntry(h, RPMTAG_FILENAMES)) {
+       /* 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 (assembleFileList(h, &fileMem, &fileCount, &files, stripSize,
+                            actions)) {
+           if (rootdir) {
+               chroot(".");
+               chdir(currDir);
+           }
+           return 2;
+       }
+
+       freeFileMem = 1;
+    } else {
+       files = NULL;
+    }
+    
+    if (flags & RPMTRANS_FLAG_TEST) {
+       if (rootdir) {
+           chroot(".");
+           chdir(currDir);
+       }
+
+       rpmMessage(RPMMESS_DEBUG, _("stopping install as we're running --test\n"));
+       if (freeFileMem) freeFileMemory(fileMem);
+       return 0;
+    }
+
+    rpmMessage(RPMMESS_DEBUG, _("running preinstall script (if any)\n"));
+    if (runInstScript("/", h, RPMTAG_PREIN, RPMTAG_PREINPROG, scriptArg, 
+                     flags & RPMTRANS_FLAG_NOSCRIPTS, scriptFd)) {
+       if (freeFileMem) freeFileMemory(fileMem);
+
+       if (rootdir) {
+           chroot(".");
+           chdir(currDir);
+       }
+
+       return 2;
+    }
+
+    if (files) {
+       setFileOwners(h, files, fileCount);
+
+       for (i = 0; i < fileCount; i++) {
+           switch (files[i].action) {
+             case FA_BACKUP:
+               ext = ".rpmorig";
+               installFile = 1;
+               break;
+
+             case FA_ALTNAME:
+               ext = NULL;
+               installFile = 1;
+
+               newpath = alloca(strlen(files[i].relativePath) + 20);
+               strcpy(newpath, files[i].relativePath);
+               strcat(newpath, ".rpmnew");
+               rpmError(RPMMESS_ALTNAME, _("warning: %s created as %s"),
+                       files[i].relativePath, newpath);
+               files[i].relativePath = newpath;
+               
+               break;
+
+             case FA_SAVE:
+               ext = ".rpmsave";
+               installFile = 1;
+               break;
+
+             case FA_CREATE:
+               installFile = 1;
+               ext = NULL;
+               break;
+
+             case FA_SKIP:
+               installFile = 0;
+               ext = NULL;
+               break;
+
+             case FA_SKIPNSTATE:
+               installFile = 0;
+               ext = NULL;
+               files[i].state = RPMFILE_STATE_NOTINSTALLED;
+               break;
+
+             case FA_UNKNOWN:
+             case FA_REMOVE:
+               break;
+           }
+
+           if (ext) {
+               newpath = alloca(strlen(files[i].relativePath) + 20);
+               strcpy(newpath, files[i].relativePath);
+               strcat(newpath, ext);
+               rpmError(RPMMESS_BACKUP, _("warning: %s saved as %s"), 
+                       files[i].relativePath, newpath);
+
+               if (rename(files[i].relativePath, newpath)) {
+                   rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s"),
+                         files[i].relativePath, newpath, strerror(errno));
+                   if (freeFileMem) freeFileMemory(fileMem);
+
+                   if (rootdir) {
+                       chroot(".");
+                       chdir(currDir);
+                   }
+
+                   return 2;
+               }
+           }
+
+           if (!installFile) {
+               files[i].install = 0;
+           }
+       }
+
+       if (!headerGetEntry(h, RPMTAG_ARCHIVESIZE, &type, 
+                               (void **) &archiveSizePtr, &count))
+           archiveSizePtr = NULL;
+
+       if (notify) {
+           notify(h, RPMCALLBACK_INST_START, 0, 0, pkgKey, notifyData);
+       }
+
+       /* the file pointer for fd is pointing at the cpio archive */
+       if (installArchive(fd, files, fileCount, notify, notifyData, pkgKey, h,
+                          NULL, archiveSizePtr ? *archiveSizePtr : 0)) {
+           headerFree(h);
+           if (freeFileMem) freeFileMemory(fileMem);
+
+           if (rootdir) {
+               chroot(".");
+               chdir(currDir);
+           }
+
+           return 2;
+       }
+
+       fileStates = malloc(sizeof(*fileStates) * fileCount);
+       for (i = 0; i < fileCount; i++)
+           fileStates[i] = files[i].state;
+
+       headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fileStates, 
+                       fileCount);
+
+       free(fileStates);
+       if (freeFileMem) freeFileMemory(fileMem);
+    } else if (flags & RPMTRANS_FLAG_JUSTDB) {
+       if (headerGetEntry(h, RPMTAG_FILENAMES, NULL, NULL, &fileCount)) {
+           fileStates = malloc(sizeof(*fileStates) * fileCount);
+           memset(fileStates, RPMFILE_STATE_NORMAL, fileCount);
+           headerAddEntry(h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fileStates, 
+                           fileCount);
+           free(fileStates);
+       }
+    }
+
+    installTime = time(NULL);
+    headerAddEntry(h, RPMTAG_INSTALLTIME, RPM_INT32_TYPE, &installTime, 1);
+
+    if (rootdir) {
+       chroot(".");
+       chdir(currDir);
+    }
+
+    trimChangelog(h);
+
+    /* if this package has already been installed, remove it from the database
+       before adding the new one */
+    if (otherOffset) {
+        rpmdbRemove(db, otherOffset, 1);
+    }
+
+    if (rpmdbAdd(db, h)) {
+       headerFree(h);
+       return 2;
+    }
+
+    rpmMessage(RPMMESS_DEBUG, _("running postinstall script (if any)\n"));
+
+    if (runInstScript(rootdir, h, RPMTAG_POSTIN, RPMTAG_POSTINPROG, scriptArg,
+                     flags & RPMTRANS_FLAG_NOSCRIPTS, scriptFd)) {
+       return 2;
+    }
+
+    if (!(flags & RPMTRANS_FLAG_NOTRIGGERS)) {
+       /* Run triggers this package sets off */
+       if (runTriggers(rootdir, db, RPMSENSE_TRIGGERIN, h, 0, scriptFd)) {
+           return 2;
+       }
+
+       /* Run triggers in this package which are set off by other things in
+          the database. */
+       if (runImmedTriggers(rootdir, db, RPMSENSE_TRIGGERIN, h, 0, scriptFd)) {
+           return 2;
+       }
+    }
+
+    if (sharedList) 
+       markReplacedFiles(db, sharedList);
+
+    return 0;
+}