Isolate install/erase actions.
authorjbj <devnull@localhost>
Thu, 25 Jan 2001 12:58:03 +0000 (12:58 +0000)
committerjbj <devnull@localhost>
Thu, 25 Jan 2001 12:58:03 +0000 (12:58 +0000)
Start wrapping src rpm installs in a transaction.

CVS patchset: 4497
CVS date: 2001/01/25 12:58:03

build/files.c
lib/depends.c
lib/install.c
lib/rpminstall.c
lib/uninstall.c
po/rpm.pot

index 7be4698..4caabb6 100644 (file)
@@ -1089,7 +1089,7 @@ static void genCpioListAndHeader(struct FileList *fl, TFI_t *cpioList,
        rpmlibNeedsFeature(h, "CompressedFileNames", "3.0.4-1");
     }
 
-  { TFI_t fi = xmalloc(sizeof(*fi) * fl->fileListRecsUsed);
+  { TFI_t fi = xcalloc(sizeof(*fi), 1);
     char * a, * d;
 
     fi->type = TR_ADDED;
@@ -1097,13 +1097,14 @@ static void genCpioListAndHeader(struct FileList *fl, TFI_t *cpioList,
     if (fi->dnl) {
        free((void *)fi->dnl); fi->dnl = NULL;
     }
+    if (fi->bnl) {
+       free((void *)fi->bnl); fi->bnl = NULL;
+    }
+
     fi->dnl = xmalloc(fi->fc * sizeof(*fi->dnl) + dpathlen);
     d = (char *)(fi->dnl + fi->fc);
     *d = '\0';
 
-    if (fi->bnl) {
-       free((void *)fi->bnl); fi->bnl = NULL;
-    }
     fi->bnl = xmalloc(fi->fc * (sizeof(*fi->bnl) + sizeof(*fi->dil)));
     fi->dil = (int *)(fi->bnl + fi->fc);
 
index d154171..918b2e5 100644 (file)
@@ -759,15 +759,12 @@ int rpmtransAddPackage(rpmTransactionSet ts, Header h, FD_t fd,
     const char ** obsoletes;
     int alNum;
 
-    /* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */
-    if (headerIsEntry(h, RPMTAG_SOURCEPACKAGE))
-       return 1;
-
-    /* FIXME: handling upgrades like this is *almost* okay. It doesn't
-       check to make sure we're upgrading to a newer version, and it
-       makes it difficult to generate a return code based on the number of
-       packages which failed. */
-
+    /*
+     * FIXME: handling upgrades like this is *almost* okay. It doesn't
+     * check to make sure we're upgrading to a newer version, and it
+     * makes it difficult to generate a return code based on the number of
+     * packages which failed.
+     */
     if (ts->orderCount == ts->orderAlloced) {
        ts->orderAlloced += ts->delta;
        ts->order = xrealloc(ts->order, sizeof(*ts->order) * ts->orderAlloced);
@@ -777,7 +774,12 @@ int rpmtransAddPackage(rpmTransactionSet ts, Header h, FD_t fd,
                ts->addedPackages.list;
     ts->order[ts->orderCount++].u.addedIndex = alNum;
 
-    if (!upgrade || ts->rpmdb == NULL) return 0;
+    if (!upgrade || ts->rpmdb == NULL)
+       return 0;
+
+    /* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */
+    if (headerIsEntry(h, RPMTAG_SOURCEPACKAGE))
+       return 0;
 
     headerNVR(h, &name, NULL, NULL);
 
index 72c00fb..e99bb70 100644 (file)
@@ -74,38 +74,6 @@ static int rpmInstallLoadMacros(Header h)
     return 0;
 }
 
-/* files should not be preallocated */
-/**
- * Build file information array.
- * @param fi           transaction file info (NULL for source package)
- * @param h            header
- * @retval memPtr      address of allocated memory from header access
- * @retval files       address of install file information
- * @param actions      array of file dispositions
- * @return             0 always
- */
-static int assembleFileList(TFI_t fi, Header h)
-{
-    int i;
-
-    if (fi->fc == 0)
-       return 0;
-
-    if (headerIsEntry(h, RPMTAG_ORIGBASENAMES)) {
-       buildOrigFileList(h, &fi->apath, NULL);
-    } else {
-       rpmBuildFileList(h, &fi->apath, NULL);
-    }
-
-    for (i = 0; i < fi->fc; i++) {
-       rpmMessage(RPMMESS_DEBUG, _("   file: %s%s action: %s\n"),
-                       fi->dnl[fi->dil[i]], fi->bnl[i],
-               fileActionString((fi->actions ? fi->actions[i] : FA_UNKNOWN)) );
-    }
-
-    return 0;
-}
-
 /**
  * Localize user/group id's.
  * @param fi           transaction element file info
@@ -453,31 +421,27 @@ static void callback(struct cpioCallbackInfo * cpioInfo, void * data)
 /**
  * Setup payload map and install payload archive.
  *
- * @todo Add endian tag so that srpm MD5 sums can ber verified when installed.
+ * @todo Add endian tag so that srpm MD5 sums can be verified when installed.
  *
  * @param ts           transaction set
  * @param fi           transaction element file info (NULL means all files)
- * @param fd           file handle of package (positioned at payload)
- * @param notify       callback function
- * @param notifyData   callback private data
- * @param pkgKey       package private data (e.g. file name)
- * @param h            header
  * @retval specFile    address of spec file name
  * @param archiveSize  @todo Document.
+ * @param allFiles     install all files?
  * @return             0 on success
  */
-static int installArchive(const rpmTransactionSet ts, TFI_t fi, FD_t fd,
-                       rpmCallbackFunction notify, rpmCallbackData notifyData,
-                       const void * pkgKey, Header h,
-                       /*@out@*/ const char ** specFile, int archiveSize)
+static int installArchive(const rpmTransactionSet ts, TFI_t fi,
+                       /*@out@*/ const char ** specFile, int archiveSize,
+                       int allFiles)
 {
+    struct availablePackage * alp = fi->ap;
     const char * failedFile = NULL;
     cbInfo cbi = alloca(sizeof(*cbi));
     char * rpmio_flags;
     int saveerrno;
     int rc;
 
-    if (fi == NULL) {
+    if (allFiles) {
        /* install all files */
     } else if (fi->fc == 0) {
        /* no files to install */
@@ -485,23 +449,23 @@ static int installArchive(const rpmTransactionSet ts, TFI_t fi, FD_t fd,
     }
 
     cbi->archiveSize = archiveSize;    /* arg9 */
-    cbi->notify = notify;              /* arg4 */
-    cbi->notifyData = notifyData;      /* arg5 */
+    cbi->notify = ts->notify;          /* arg4 */
+    cbi->notifyData = ts->notifyData;  /* arg5 */
     cbi->specFilePtr = specFile;       /* arg8 */
-    cbi->h = headerLink(h);            /* arg7 */
-    cbi->pkgKey = pkgKey;              /* arg6 */
+    cbi->h = headerLink(fi->h);                /* arg7 */
+    cbi->pkgKey = alp->key;            /* arg6 */
 
     if (specFile) *specFile = NULL;
 
-    if (notify)
-       (void)notify(h, RPMCALLBACK_INST_PROGRESS, 0, archiveSize, pkgKey,
-              notifyData);
+    if (ts->notify)
+       (void)ts->notify(fi->h, RPMCALLBACK_INST_PROGRESS, 0, archiveSize,
+                       alp->key, ts->notifyData);
 
     /* Retrieve type of payload compression. */
     {  const char * payload_compressor = NULL;
        char * t;
 
-       if (!headerGetEntry(h, RPMTAG_PAYLOADCOMPRESSOR, NULL,
+       if (!headerGetEntry(fi->h, RPMTAG_PAYLOADCOMPRESSOR, NULL,
                            (void **) &payload_compressor, NULL))
            payload_compressor = "gzip";
        rpmio_flags = t = alloca(sizeof("r.gzdio"));
@@ -513,10 +477,10 @@ static int installArchive(const rpmTransactionSet ts, TFI_t fi, FD_t fd,
     }
 
     {  FD_t cfd;
-       (void) Fflush(fd);
-       cfd = Fdopen(fdDup(Fileno(fd)), rpmio_flags);
+       (void) Fflush(alp->fd);
+       cfd = Fdopen(fdDup(Fileno(alp->fd)), rpmio_flags);
        rc = cpioInstallArchive(cfd, fi,
-                   ((notify && archiveSize) || specFile) ? callback : NULL,
+                   ((ts->notify && archiveSize) || specFile) ? callback : NULL,
                    cbi, &failedFile);
        saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */
        Fclose(cfd);
@@ -534,11 +498,11 @@ static int installArchive(const rpmTransactionSet ts, TFI_t fi, FD_t fd,
                (failedFile != NULL ? failedFile : ""),
                cpioStrerror(rc));
        rc = 1;
-    } else if (notify) {
+    } else if (ts->notify) {
        if (archiveSize == 0)
            archiveSize = 100;
-       (void)notify(h, RPMCALLBACK_INST_PROGRESS, archiveSize, archiveSize,
-               pkgKey, notifyData);
+       (void)ts->notify(fi->h, RPMCALLBACK_INST_PROGRESS,
+                       archiveSize, archiveSize, alp->key, ts->notifyData);
        rc = 0;
     }
 
@@ -581,24 +545,20 @@ static int chkdir (const char * dpath, const char * dname)
     }
     return 0;
 }
+
 /**
- * @param h            header
- * @param rootDir      path to top of install tree
- * @param fd           file handle of package (positioned at payload)
+ * @param ts           transaction set
+ * @param fi           transaction element file info
  * @retval specFilePtr address of spec file name
- * @param notify       callback function
- * @param notifyData   callback private data
  * @return             0 on success, 1 on bad magic, 2 on error
  */
-static int installSources(Header h, const char * rootDir, FD_t fd,
-                       const char ** specFilePtr,
-                       rpmCallbackFunction notify, rpmCallbackData notifyData)
+static int installSources(const rpmTransactionSet ts, TFI_t fi,
+                       /*@out@*/ const char ** specFilePtr)
 {
-    TFI_t fi = xcalloc(sizeof(*fi), 1);
+    const char * _sourcedir = rpmGenPath(ts->rootDir, "%{_sourcedir}", "");
+    const char * _specdir = rpmGenPath(ts->rootDir, "%{_specdir}", "");
     const char * specFile = NULL;
     int specFileIndex = -1;
-    const char * _sourcedir = rpmGenPath(rootDir, "%{_sourcedir}", "");
-    const char * _specdir = rpmGenPath(rootDir, "%{_specdir}", "");
     uint_32 * archiveSizePtr = NULL;
     int rc = 0;
     int i;
@@ -617,30 +577,8 @@ static int installSources(Header h, const char * rootDir, FD_t fd,
        goto exit;
     }
 
-    fi->type = TR_ADDED;
-    loadFi(h, fi);
-    if (fi->fmd5s) {           /* DYING */
-       free((void **)fi->fmd5s); fi->fmd5s = NULL;
-    }
-    if (fi->fmapflags) {       /* DYING */
-       free((void **)fi->fmapflags); fi->fmapflags = NULL;
-    }
-    fi->uid = getuid();
-    fi->gid = getgid();
-    fi->striplen = 0;
-    fi->mapflags = CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
-
-    fi->fuids = xcalloc(sizeof(*fi->fuids), fi->fc);
-    fi->fgids = xcalloc(sizeof(*fi->fgids), fi->fc);
-    for (i = 0; i < fi->fc; i++) {
-       fi->fuids[i] = fi->uid;
-       fi->fgids[i] = fi->gid;
-    }
-
-    assembleFileList(fi, h);
-
     i = fi->fc;
-    if (headerIsEntry(h, RPMTAG_COOKIE))
+    if (headerIsEntry(fi->h, RPMTAG_COOKIE))
        for (i = 0; i < fi->fc; i++)
                if (fi->fflags[i] & RPMFILE_SPECFILE) break;
 
@@ -665,19 +603,20 @@ static int installSources(Header h, const char * rootDir, FD_t fd,
        goto exit;
     }
 
-    if (notify)
-       (void)notify(h, RPMCALLBACK_INST_START, 0, 0, NULL, notifyData);
+    if (ts->notify)
+       (void)ts->notify(fi->h, RPMCALLBACK_INST_START, 0, 0,
+                       NULL, ts->notifyData);
 
-    if (!headerGetEntry(h, RPMTAG_ARCHIVESIZE, NULL,
+    if (!headerGetEntry(fi->h, RPMTAG_ARCHIVESIZE, NULL,
                            (void **) &archiveSizePtr, NULL))
        archiveSizePtr = NULL;
 
     {  const char * currDir = currentDirectory();
        Chdir(_sourcedir);
-       rc = installArchive(NULL, NULL, fd,
-                         notify, notifyData, NULL, h,
-                         specFileIndex >= 0 ? NULL : &specFile,
-                         archiveSizePtr ? *archiveSizePtr : 0);
+       rc = installArchive(ts, fi,
+                       specFileIndex >= 0 ? NULL : &specFile,
+                       archiveSizePtr ? *archiveSizePtr : 0,
+                       1);
 
        Chdir(currDir);
        free((void *)currDir);
@@ -736,10 +675,6 @@ static int installSources(Header h, const char * rootDir, FD_t fd,
     rc = 0;
 
 exit:
-    if (fi) {
-       freeFi(fi);
-       free(fi);
-    }
     if (_specdir)      free((void *)_specdir);
     if (_sourcedir)    free((void *)_sourcedir);
     return rc;
@@ -804,32 +739,161 @@ int rpmInstallSourcePackage(const char * rootDir, FD_t fd,
                        rpmCallbackFunction notify, rpmCallbackData notifyData,
                        char ** cookie)
 {
-    int rc, isSource;
+    rpmdb rpmdb = NULL;
+    rpmTransactionSet ts = rpmtransCreateSet(rpmdb, rootDir);
+    TFI_t fi = xcalloc(sizeof(*fi), 1);
+    int isSource;
     Header h;
     int major, minor;
+    int rc;
+    int i;
+
+    ts->notify = notify;
+    ts->notifyData = notifyData;
 
     rc = rpmReadPackageHeader(fd, &h, &isSource, &major, &minor);
-    if (rc) return rc;
+    if (rc)
+       goto exit;
 
     if (!isSource) {
        rpmError(RPMERR_NOTSRPM, _("source package expected, binary found\n"));
-       return 2;
+       rc = 2;
+       goto exit;
     }
 
     if (cookie) {
        *cookie = NULL;
-       if (h != NULL &&
-          headerGetEntry(h, RPMTAG_COOKIE, NULL, (void **) cookie, NULL)) {
+       if (headerGetEntry(h, RPMTAG_COOKIE, NULL, (void **) cookie, NULL))
            *cookie = xstrdup(*cookie);
-       }
     }
 
-    rpmInstallLoadMacros(h);
+    rc = rpmtransAddPackage(ts, h, fd, NULL, 0, NULL);
+    headerFree(h);     /* XXX reference held by transaction set */
 
-    rc = installSources(h, rootDir, fd, specFile, notify, notifyData);
-    if (h)
-       headerFree(h);
+    fi->type = TR_ADDED;
+    fi->ap = ts->addedPackages.list;
+    loadFi(h, fi);
+    if (fi->fmd5s) {           /* DYING */
+       free((void **)fi->fmd5s); fi->fmd5s = NULL;
+    }
+    if (fi->fmapflags) {       /* DYING */
+       free((void **)fi->fmapflags); fi->fmapflags = NULL;
+    }
+    fi->uid = getuid();
+    fi->gid = getgid();
+    fi->striplen = 0;
+    fi->mapflags = CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
 
+    fi->fuids = xcalloc(sizeof(*fi->fuids), fi->fc);
+    fi->fgids = xcalloc(sizeof(*fi->fgids), fi->fc);
+    for (i = 0; i < fi->fc; i++) {
+       fi->fuids[i] = fi->uid;
+       fi->fgids[i] = fi->gid;
+    }
+
+    rpmBuildFileList(fi->h, &fi->apath, NULL);
+
+    rpmInstallLoadMacros(fi->h);
+
+    rc = installSources(ts, fi, specFile);
+
+exit:
+    if (fi) {
+       freeFi(fi);
+       free(fi);
+    }
+    if (ts)
+       rpmtransFree(ts);
+    return rc;
+}
+
+#define        SUFFIX_RPMORIG  ".rpmorig"
+#define        SUFFIX_RPMSAVE  ".rpmsave"
+#define        SUFFIX_RPMNEW   ".rpmnew"
+
+/**
+ * Perform install file actions.
+ * @param ts           transaction set
+ * @param fi           transaction element file info
+ * @return             0 on success, 1 on failure
+ */
+static int installActions(const rpmTransactionSet ts, TFI_t fi)
+{
+    static char * stepName = "install";
+    int nb = (!ts->chrootDone ? strlen(ts->rootDir) : 0);
+    char * opath = alloca(nb + fi->dnlmax + fi->bnlmax + 64);
+    char * o = (!ts->chrootDone ? stpcpy(opath, ts->rootDir) : opath);
+    char * npath = alloca(nb + fi->dnlmax + fi->bnlmax + 64);
+    char * n = (!ts->chrootDone ? stpcpy(npath, ts->rootDir) : npath);
+    int rc = 0;
+    int i;
+
+    if (fi->actions == NULL)
+       return rc;
+
+    for (i = 0; i < fi->fc; i++) {
+       char * ext, * t;
+
+       rpmMessage(RPMMESS_DEBUG, _("   file: %s%s action: %s\n"),
+                       fi->dnl[fi->dil[i]], fi->bnl[i],
+               fileActionString((fi->actions ? fi->actions[i] : FA_UNKNOWN)) );
+
+       ext = NULL;
+
+       switch (fi->actions[i]) {
+       case FA_CREATE:
+       case FA_SKIP:
+       case FA_SKIPMULTILIB:
+       case FA_UNKNOWN:
+       case FA_REMOVE:
+           break;
+
+       case FA_SKIPNSTATE:
+           fi->fstates[i] = RPMFILE_STATE_NOTINSTALLED;
+           break;
+
+       case FA_SKIPNETSHARED:
+           fi->fstates[i] = RPMFILE_STATE_NETSHARED;
+           break;
+       case FA_BACKUP:
+           ext = SUFFIX_RPMORIG;
+           break;
+
+       case FA_ALTNAME:
+           ext = SUFFIX_RPMNEW;
+           t = xmalloc(strlen(fi->bnl[i]) + strlen(ext) + 1);
+           (void)stpcpy(stpcpy(t, fi->bnl[i]), ext);
+           rpmMessage(RPMMESS_WARNING, _("%s%s created as %s\n"),
+                       fi->dnl[fi->dil[i]], fi->bnl[i], t);
+           fi->bnl[i] = t;             /* XXX memory leak iff i = 0 */
+           ext = NULL;
+           break;
+
+       case FA_SAVE:
+           ext = SUFFIX_RPMSAVE;
+           break;
+       }
+
+       if (ext == NULL)
+           continue;
+
+       /* Append file name to (possible) root dir. */
+       (void) stpcpy( stpcpy(o, fi->dnl[fi->dil[i]]), fi->bnl[i]);
+
+       if (access(opath, F_OK) != 0)
+           continue;
+
+       (void) stpcpy( stpcpy(n, o), ext);
+       rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"), o, n);
+
+       if (!rename(opath, npath))
+           continue;
+
+       rpmError(RPMERR_RENAME, _("%s rename of %s to %s failed: %s\n"),
+                       stepName, o, n, strerror(errno));
+       rc = 1;
+       break;
+    }
     return rc;
 }
 
@@ -841,12 +905,10 @@ int installBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
 {
     static char * stepName = "install";
     struct availablePackage * alp = fi->ap;
-    char * fstates = alloca(sizeof(*fstates) * fi->fc);
     Header oldH = NULL;
     int otherOffset = 0;
     int ec = 2;                /* assume error return */
     int rc;
-    int i;
 
     rpmMessage(RPMMESS_DEBUG, _("%s: %s-%s-%s has %d files, test = %d\n"),
                stepName, fi->name, fi->version, fi->release,
@@ -873,9 +935,12 @@ int installBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
        rpmdbFreeIterator(mi);
     }
 
-    memset(fstates, RPMFILE_STATE_NORMAL, fi->fc);
+    if (fi->fc > 0 && fi->fstates == NULL) {
+       fi->fstates = xmalloc(sizeof(*fi->fstates) * fi->fc);
+       memset(fi->fstates, RPMFILE_STATE_NORMAL, fi->fc);
+    }
 
-    if (!(ts->transFlags & RPMTRANS_FLAG_JUSTDB) && fi->fc > 0) {
+    if (fi->fc > 0 && !(ts->transFlags & RPMTRANS_FLAG_JUSTDB)) {
        const char * p;
 
        /*
@@ -888,8 +953,23 @@ int installBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
        fi->striplen = (rc ? strlen(p) + 1 : 1); 
        fi->mapflags =
                CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
-       if (assembleFileList(fi, fi->h))
-           goto exit;
+
+       if (headerIsEntry(fi->h, RPMTAG_ORIGBASENAMES))
+           buildOrigFileList(fi->h, &fi->apath, NULL);
+       else
+           rpmBuildFileList(fi->h, &fi->apath, NULL);
+
+       if (fi->fuser == NULL)
+           headerGetEntryMinMemory(fi->h, RPMTAG_FILEUSERNAME, NULL,
+                               (const void **) &fi->fuser, NULL);
+       if (fi->fgroup == NULL)
+           headerGetEntryMinMemory(fi->h, RPMTAG_FILEGROUPNAME, NULL,
+                               (const void **) &fi->fgroup, NULL);
+       if (fi->fuids == NULL)
+           fi->fuids = xcalloc(sizeof(*fi->fuids), fi->fc);
+       if (fi->fgids == NULL)
+           fi->fgids = xcalloc(sizeof(*fi->fgids), fi->fc);
+
     }
 
     if (ts->transFlags & RPMTRANS_FLAG_TEST) {
@@ -910,122 +990,46 @@ int installBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
     }
 
     if (ts->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();
+       static int _loaded = 0;
+
+       /*
+        * This loads all of the name services libraries, in case we
+        * don't have access to them in the chroot().
+        */
+       if (!_loaded) {
+           (void)getpwnam("root");
+           endpwent();
+           _loaded++;
+       }
 
        chdir("/");
        /*@-unrecog@*/ chroot(ts->rootDir); /*@=unrecog@*/
        ts->chrootDone = 1;
     }
 
-    if (!(ts->transFlags & RPMTRANS_FLAG_JUSTDB) && fi->fc > 0) {
-       if (fi->fuser == NULL)
-           headerGetEntryMinMemory(fi->h, RPMTAG_FILEUSERNAME, NULL,
-                               (const void **) &fi->fuser, NULL);
-       if (fi->fgroup == NULL)
-           headerGetEntryMinMemory(fi->h, RPMTAG_FILEGROUPNAME, NULL,
-                               (const void **) &fi->fgroup, NULL);
-       if (fi->fuids == NULL)
-           fi->fuids = xcalloc(sizeof(*fi->fuids), fi->fc);
-       if (fi->fgids == NULL)
-           fi->fgids = xcalloc(sizeof(*fi->fgids), fi->fc);
+       
+    if (fi->fc > 0 && !(ts->transFlags & RPMTRANS_FLAG_JUSTDB)) {
+       uint_32 archiveSize, * asp;
 
        setFileOwners(fi);
 
-      if (fi->actions) {
-       char * opath = alloca(fi->dnlmax + fi->bnlmax + 64);
-       char * npath = alloca(fi->dnlmax + fi->bnlmax + 64);
-
-       for (i = 0; i < fi->fc; i++) {
-           char * ext, * t;
-
-           ext = NULL;
-
-           switch (fi->actions[i]) {
-           case FA_BACKUP:
-               ext = ".rpmorig";
-               break;
-
-           case FA_ALTNAME:
-               ext = ".rpmnew";
-               t = xmalloc(strlen(fi->bnl[i]) + strlen(ext) + 1);
-               (void)stpcpy(stpcpy(t, fi->bnl[i]), ext);
-               rpmMessage(RPMMESS_WARNING, _("%s%s created as %s\n"),
-                       fi->dnl[fi->dil[i]], fi->bnl[i], t);
-               fi->bnl[i] = t;         /* XXX memory leak iff i = 0 */
-               ext = NULL;
-               break;
-
-           case FA_SAVE:
-               ext = ".rpmsave";
-               break;
-
-           case FA_CREATE:
-               break;
-
-           case FA_SKIP:
-           case FA_SKIPMULTILIB:
-               break;
-
-           case FA_SKIPNSTATE:
-               fstates[i] = RPMFILE_STATE_NOTINSTALLED;
-               break;
-
-           case FA_SKIPNETSHARED:
-               fstates[i] = RPMFILE_STATE_NETSHARED;
-               break;
-
-           case FA_UNKNOWN:
-           case FA_REMOVE:
-               break;
-           }
-
-           if (ext == NULL)
-               continue;
-           (void) stpcpy( stpcpy(opath, fi->dnl[fi->dil[i]]), fi->bnl[i]);
-           if (access(opath, F_OK) != 0)
-               continue;
-           (void) stpcpy( stpcpy(npath, opath), ext);
-           rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"), opath, npath);
-
-           if (!rename(opath, npath))
-               continue;
-
-           rpmError(RPMERR_RENAME, _("%s rename of %s to %s failed: %s\n"),
-                       stepName, opath, npath, strerror(errno));
+       rc = installActions(ts, fi);
+       if (rc)
            goto exit;
-       }
-      }
-
-       {   uint_32 archiveSize, * asp;
 
-           rc = headerGetEntry(fi->h, RPMTAG_ARCHIVESIZE, NULL,
-               (void **) &asp, NULL);
-           archiveSize = (rc ? *asp : 0);
+       rc = headerGetEntry(fi->h, RPMTAG_ARCHIVESIZE, NULL,
+                               (void **) &asp, NULL);
+       archiveSize = (rc ? *asp : 0);
 
-           if (ts->notify) {
-               (void)ts->notify(fi->h, RPMCALLBACK_INST_START, 0, 0,
+       if (ts->notify)
+           (void)ts->notify(fi->h, RPMCALLBACK_INST_START, 0, 0,
                    alp->key, ts->notifyData);
-           }
-
-           /* the file pointer for fd is pointing at the cpio archive */
-           rc = installArchive(ts, fi, alp->fd,
-                       ts->notify, ts->notifyData, alp->key,
-                       fi->h, NULL, archiveSize);
-           if (rc)
-               goto exit;
-       }
 
-       headerAddEntry(fi->h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fstates, fi->fc);
+       rc = installArchive(ts, fi, NULL, archiveSize, 0);
 
-    } else if (fi->fc > 0 && ts->transFlags & RPMTRANS_FLAG_JUSTDB) {
-       headerAddEntry(fi->h, RPMTAG_FILESTATES, RPM_CHAR_TYPE, fstates, fi->fc);
-    }
-
-    {  int_32 installTime = time(NULL);
-       headerAddEntry(fi->h, RPMTAG_INSTALLTIME, RPM_INT32_TYPE, &installTime, 1);
+       /* XXX WTFO? RPMCALLBACK_INST_STOP event? */
+       if (rc)
+           goto exit;
     }
 
     if (ts->rootDir) {
@@ -1034,6 +1038,16 @@ int installBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
        chdir(ts->currDir);
     }
 
+    if (fi->fc > 0 && fi->fstates) {
+       headerAddEntry(fi->h, RPMTAG_FILESTATES, RPM_CHAR_TYPE,
+                       fi->fstates, fi->fc);
+    }
+
+    {  int_32 installTime = time(NULL);
+       headerAddEntry(fi->h, RPMTAG_INSTALLTIME, RPM_INT32_TYPE,
+                       &installTime, 1);
+    }
+
 #ifdef DYING
     trimChangelog(h);
 #endif
index 26f84b9..eae1228 100644 (file)
@@ -34,22 +34,23 @@ static void printHash(const unsigned long amount, const unsigned long total)
 
 #ifdef FANCY_HASH
     if (isatty (STDOUT_FILENO))
-       hashesTotal = 44;
+       hashesTotal = 44;
 #endif
 
     if (hashesPrinted != hashesTotal) {
-        hashesNeeded = hashesTotal * (total ? (((float) amount) / total) : 1);
+       hashesNeeded = hashesTotal * (total ? (((float) amount) / total) : 1);
        while (hashesNeeded > hashesPrinted) {
 #ifdef FANCY_HASH
-           if (isatty (STDOUT_FILENO)) {
-               int i;
-               for (i = 0; i < hashesPrinted; i++) putchar ('#');
-               for (; i < hashesTotal; i++) putchar (' ');
-               printf ("(%3d%%)", (int)(100 * (total ? (((float) amount) / total) : 1)));
-               for (i = 0; i < (hashesTotal + 6); i++) putchar ('\b');
-           } else
+           if (isatty (STDOUT_FILENO)) {
+               int i;
+               for (i = 0; i < hashesPrinted; i++) putchar ('#');
+               for (; i < hashesTotal; i++) putchar (' ');
+               printf ("(%3d%%)",
+                       (int)(100 * (total ? (((float) amount) / total) : 1)));
+               for (i = 0; i < (hashesTotal + 6); i++) putchar ('\b');
+           } else
 #endif
-               fprintf(stdout, "#");
+           fprintf(stdout, "#");
 
            fflush(stdout);
            hashesPrinted++;
@@ -57,17 +58,17 @@ static void printHash(const unsigned long amount, const unsigned long total)
        fflush(stdout);
        hashesPrinted = hashesNeeded;
 
-       if (hashesPrinted == hashesTotal) {
+       if (hashesPrinted == hashesTotal) {
 #ifdef FANCY_HASH
-           int i;
-           progressCurrent++;
-           for (i = 1; i < hashesPrinted; i++) putchar ('#');
-           printf (" [%3d%%]\n", (int)(100 * (progressTotal ?
-               (((float) progressCurrent) / progressTotal) : 1)));
+           int i;
+           progressCurrent++;
+           for (i = 1; i < hashesPrinted; i++) putchar ('#');
+           printf (" [%3d%%]\n", (int)(100 * (progressTotal ?
+                       (((float) progressCurrent) / progressTotal) : 1)));
 #else
-           fprintf (stdout, "\n");
+           fprintf (stdout, "\n");
 #endif
-       }
+       }
     }
 }
 
@@ -86,12 +87,14 @@ static void * showProgress(const void * arg, const rpmCallbackType what,
     static FD_t fd;
 
     switch (what) {
-      case RPMCALLBACK_INST_OPEN_FILE:
+    case RPMCALLBACK_INST_OPEN_FILE:
        fd = Fopen(filename, "r.ufdio");
-       fd = fdLink(fd, "persist (showProgress)");
+       if (fd)
+           fd = fdLink(fd, "persist (showProgress)");
        return fd;
+       /*@notreached@*/ break;
 
-      case RPMCALLBACK_INST_CLOSE_FILE:
+    case RPMCALLBACK_INST_CLOSE_FILE:
        fd = fdFree(fd, "persist (showProgress)");
        if (fd) {
            Fclose(fd);
@@ -99,31 +102,30 @@ static void * showProgress(const void * arg, const rpmCallbackType what,
        }
        break;
 
-      case RPMCALLBACK_INST_START:
+    case RPMCALLBACK_INST_START:
        hashesPrinted = 0;
-       if (flags & INSTALL_LABEL) {
-           if (flags & INSTALL_HASH) {
-               s = headerSprintf(h, "%{NAME}",
-                                 rpmTagTable, rpmHeaderFormats, NULL);
+       if (!(flags & INSTALL_LABEL))
+           break;
+       if (flags & INSTALL_HASH) {
+           s = headerSprintf(h, "%{NAME}", rpmTagTable, rpmHeaderFormats,NULL);
 #ifdef FANCY_HASH
-               if (isatty (STDOUT_FILENO))
-                   fprintf(stdout, "%4d:%-23.23s", progressCurrent + 1, s);
-              else
+           if (isatty (STDOUT_FILENO))
+               fprintf(stdout, "%4d:%-23.23s", progressCurrent + 1, s);
+           else
 #else
-                   fprintf(stdout, "%-28s", s);
+               fprintf(stdout, "%-28s", s);
 #endif
-               fflush(stdout);
-           } else {
-               s = headerSprintf(h, "%{NAME}-%{VERSION}-%{RELEASE}", 
+           fflush(stdout);
+       } else {
+           s = headerSprintf(h, "%{NAME}-%{VERSION}-%{RELEASE}", 
                                  rpmTagTable, rpmHeaderFormats, NULL);
-               fprintf(stdout, "%s\n", s);
-           }
-           free(s);
+           fprintf(stdout, "%s\n", s);
        }
+       free(s);
        break;
 
-      case RPMCALLBACK_TRANS_PROGRESS:
-      case RPMCALLBACK_INST_PROGRESS:
+    case RPMCALLBACK_TRANS_PROGRESS:
+    case RPMCALLBACK_INST_PROGRESS:
        if (flags & INSTALL_PERCENT) {
            fprintf(stdout, "%%%% %f\n", (total
                                ? ((float) ((((float) amount) / total) * 100))
@@ -133,35 +135,34 @@ static void * showProgress(const void * arg, const rpmCallbackType what,
        }
        break;
 
-      case RPMCALLBACK_TRANS_START:
-       hashesPrinted = 0;
+    case RPMCALLBACK_TRANS_START:
+       hashesPrinted = 0;
 #ifdef FANCY_HASH
-       progressTotal = 1;
-       progressCurrent = 0;
+       progressTotal = 1;
+       progressCurrent = 0;
 #endif
-       if (flags & INSTALL_LABEL) {
-           if (flags & INSTALL_HASH) {
-               fprintf(stdout, "%-28s", _("Preparing..."));
-               fflush(stdout);
-           } else {
-               printf("%s\n", _("Preparing packages for installation..."));
-           }
-       }
-       break;
-
-      case RPMCALLBACK_TRANS_STOP:
-       if (flags & INSTALL_HASH) {
-           printHash(1, 1);            /* Fixes "preparing..." progress bar */
-       }
+       if (!(flags & INSTALL_LABEL))
+           break;
+       if (flags & INSTALL_HASH) {
+           fprintf(stdout, "%-28s", _("Preparing..."));
+           fflush(stdout);
+       } else {
+           printf("%s\n", _("Preparing packages for installation..."));
+       }
+       break;
+
+    case RPMCALLBACK_TRANS_STOP:
+       if (flags & INSTALL_HASH)
+           printHash(1, 1);    /* Fixes "preparing..." progress bar */
 #ifdef FANCY_HASH
-       progressTotal = packagesTotal;
-       progressCurrent = 0;
+       progressTotal = packagesTotal;
+       progressCurrent = 0;
 #endif
-       break;
+       break;
 
-      case RPMCALLBACK_UNINST_PROGRESS:
-      case RPMCALLBACK_UNINST_START:
-      case RPMCALLBACK_UNINST_STOP:
+    case RPMCALLBACK_UNINST_PROGRESS:
+    case RPMCALLBACK_UNINST_START:
+    case RPMCALLBACK_UNINST_STOP:
        /* ignore */
        break;
     }
@@ -297,8 +298,8 @@ int rpmInstall(const char * rootdir, const char ** fileArgv,
        (void) urlPath(*fileURL, &fileName);
        fd = Fopen(*fileURL, "r.ufdio");
        if (fd == NULL || Ferror(fd)) {
-           rpmMessage(RPMMESS_ERROR, _("cannot open file %s: %s\n"), *fileURL,
-               Fstrerror(fd));
+           rpmMessage(RPMMESS_ERROR, _("cannot open file %s: %s\n"),
+                               *fileURL, Fstrerror(fd));
            if (fd) Fclose(fd);
            numFailed++;
            pkgURL[i] = NULL;
@@ -449,7 +450,7 @@ int rpmInstall(const char * rootdir, const char ** fileArgv,
        rpmProblemSet probs = NULL;
 
 #ifdef FANCY_HASH
-       packagesTotal = numRPMS;
+       packagesTotal = numRPMS;
 #endif
        rpmMessage(RPMMESS_DEBUG, _("installing binary packages\n"));
        rc = rpmRunTransactions(ts, showProgress, (void *) ((long)notifyFlags), 
index 52b2876..97bce23 100644 (file)
 
 /*@access Header@*/            /* XXX compared with NULL */
 
+#define        SUFFIX_RPMORIG  ".rpmorig"
 #define        SUFFIX_RPMSAVE  ".rpmsave"
+#define        SUFFIX_RPMNEW   ".rpmnew"
 
 /**
- * Remove (or rename) file according to file disposition.
+ * Perform erase file actions.
+ * @todo Permit missingok for dirs, add %missingok VFA_t when building.
+ * @param ts           transaction set
  * @param fi           transaction element file info
- * @param i            file info index
- * @param file         file name (root prepended)
- * @return
+ * @return             0 on success, 1 on failure
  */
-static int removeFile(TFI_t fi, int i, const char * ofn)
+static int eraseActions(const rpmTransactionSet ts, TFI_t fi)
 {
+    static char * stepName = "erase";
+    int nb = (!ts->chrootDone ? strlen(ts->rootDir) : 0);
+    char * opath = alloca(nb + fi->dnlmax + fi->bnlmax + 64);
+    char * o = (!ts->chrootDone ? stpcpy(opath, ts->rootDir) : opath);
+    char * npath = alloca(nb + fi->dnlmax + fi->bnlmax + 64);
+    char * n = (!ts->chrootDone ? stpcpy(npath, ts->rootDir) : npath);
     int rc = 0;
-       
-    switch (fi->actions[i]) {
+    int i;
 
-    case FA_BACKUP:
-    {  char * nfn = alloca(strlen(ofn) + sizeof(SUFFIX_RPMSAVE));
-       (void)stpcpy(stpcpy(nfn, ofn), SUFFIX_RPMSAVE);
+    if (fi->actions == NULL)
+       return rc;
 
-       if (rename(ofn, nfn)) {
-           rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s\n"),
-                       ofn, nfn, strerror(errno));
-           rc = 1;
-       }
-    }  break;
+    /* Traverse filelist backwards to help insure that rmdir() will work. */
+    for (i = fi->fc - 1; i >= 0; i--) {
 
-    case FA_REMOVE:
-       if (S_ISDIR(fi->fmodes[i])) {
-           /* XXX should permit %missingok for directories as well */
-           if (rmdir(ofn)) {
+       rpmMessage(RPMMESS_DEBUG, _("   file: %s action: %s\n"),
+                       o, fileActionString(fi->actions[i]));
+
+       if (ts->transFlags & RPMTRANS_FLAG_TEST)
+           continue;
+
+       if (ts->notify)
+           (void) ts->notify(fi->h, RPMCALLBACK_UNINST_PROGRESS, i,
+                       fi->actions[i], o, ts->notifyData);
+
+       switch (fi->actions[i]) {
+       case FA_ALTNAME:
+       case FA_SAVE:
+       case FA_CREATE:
+       case FA_SKIP:
+       case FA_SKIPMULTILIB:
+       case FA_SKIPNSTATE:
+       case FA_SKIPNETSHARED:
+       case FA_UNKNOWN:
+           continue;
+           /*@notreached@*/ break;
+
+       case FA_BACKUP:
+           /* Append file name to (possible) root dir. */
+           (void) stpcpy( stpcpy(o, fi->dnl[fi->dil[i]]), fi->bnl[i]);
+           (void) stpcpy( stpcpy(n, o), SUFFIX_RPMSAVE);
+           rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"), o, n);
+           if (!rename(opath, npath))
+               continue;
+           rpmError(RPMERR_RENAME, _("%s rename of %s to %s failed: %s\n"),
+                       stepName, o, n, strerror(errno));
+           rc = 1;
+           break;
+
+       case FA_REMOVE:
+           /* Append file name to (possible) root dir. */
+           (void) stpcpy( stpcpy(o, fi->dnl[fi->dil[i]]), fi->bnl[i]);
+           if (S_ISDIR(fi->fmodes[i])) {
+               if (!rmdir(opath))
+                   continue;
                switch (errno) {
-               case ENOENT:    /* XXX rmdir("/") linux 2.2.x kernel hack */
+               case ENOENT: /* XXX rmdir("/") linux 2.2.x kernel hack */
                case ENOTEMPTY:
+#ifdef NOTYET
+                   if (fi->fflags[i] & RPMFILE_MISSINGOK)
+                       continue;
+#endif
                    rpmError(RPMERR_RMDIR, 
-                       _("cannot remove %s - directory not empty\n"), 
-                       ofn);
+                               _("cannot remove %s - directory not empty\n"), 
+                               o);
                    break;
                default:
-                   rpmError(RPMERR_RMDIR, _("rmdir of %s failed: %s\n"),
-                               ofn, strerror(errno));
+                   rpmError(RPMERR_RMDIR,
+                               _("rmdir of %s failed: %s\n"),
+                               o, strerror(errno));
                    break;
                }
                rc = 1;
+               break;
            }
-       } else {
-           if (unlink(ofn)) {
-               if (errno != ENOENT || !(fi->fflags[i] & RPMFILE_MISSINGOK)) {
-                   rpmError(RPMERR_UNLINK, 
-                             _("removal of %s failed: %s\n"),
-                               ofn, strerror(errno));
-               }
-               rc = 1;
-           }
+           if (!unlink(opath))
+               continue;
+           if (errno == ENOENT && (fi->fflags[i] & RPMFILE_MISSINGOK))
+               continue;
+           rpmError(RPMERR_UNLINK, _("removal of %s failed: %s\n"),
+                               o, strerror(errno));
+           rc = 1;
+           break;
        }
-       break;
-    case FA_UNKNOWN:
-    case FA_CREATE:
-    case FA_SAVE:
-    case FA_ALTNAME:
-    case FA_SKIP:
-    case FA_SKIPNSTATE:
-    case FA_SKIPNETSHARED:
-    case FA_SKIPMULTILIB:
-       break;
     }
-    return 0;
+    return rc;
 }
 
 int removeBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
@@ -89,7 +121,6 @@ int removeBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
     Header h;
     const void * pkgKey = NULL;
     int rc = 0;
-    int i;
 
     rpmMessage(RPMMESS_DEBUG, _("%s: %s-%s-%s has %d files, test = %d\n"),
                stepName, fi->name, fi->version, fi->release,
@@ -130,61 +161,32 @@ int removeBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
     }
 
     rpmMessage(RPMMESS_DEBUG, _("%s: running %s script(s) (if any)\n"),
-       stepName, "pre-erase");
+               stepName, "pre-erase");
 
-    if (!(ts->transFlags & RPMTRANS_FLAG_TEST)) {
-       rc = runInstScript(ts, h, RPMTAG_PREUN, RPMTAG_PREUNPROG, fi->scriptArg,
+    rc = runInstScript(ts, h, RPMTAG_PREUN, RPMTAG_PREUNPROG, fi->scriptArg,
                          (ts->transFlags & RPMTRANS_FLAG_NOSCRIPTS));
-       if (rc)
-           return 1;
-    }
-    if (!(ts->transFlags & RPMTRANS_FLAG_JUSTDB) && fi->fc > 0) {
-       int rdlen = (ts->rootDir && !(ts->rootDir[0] == '/' && ts->rootDir[1] == '\0'))
-                       ? strlen(ts->rootDir) : 0;
-       int fnmaxlen = fi->dnlmax + fi->bnlmax + rdlen + sizeof("/") - 1;
-       char * ofn = alloca(fnmaxlen);
-
-       *ofn = '\0';
-       if (rdlen) {
-           strcpy(ofn, ts->rootDir);
-           (void) rpmCleanPath(ofn);
-           rdlen = strlen(ofn);
-       }
+    if (rc)
+       return 1;
+
+    if (fi->fc > 0 && !(ts->transFlags & RPMTRANS_FLAG_JUSTDB)) {
 
        if (ts->notify)
            (void)ts->notify(h, RPMCALLBACK_UNINST_START, fi->fc, fi->fc,
                pkgKey, ts->notifyData);
 
-       /* Traverse filelist backwards to help insure that rmdir() will work. */
-       for (i = fi->fc - 1; i >= 0; i--) {
-
-           /* XXX this assumes that dirNames always starts/ends with '/' */
-           (void) stpcpy( stpcpy(ofn+rdlen, fi->dnl[fi->dil[i]]), fi->bnl[i]);
-
-           rpmMessage(RPMMESS_DEBUG, _("   file: %s action: %s\n"),
-                       ofn, fileActionString(fi->actions[i]));
-
-           if (ts->transFlags & RPMTRANS_FLAG_TEST)
-               continue;
-           if (ts->notify)
-               (void) ts->notify(h, RPMCALLBACK_UNINST_PROGRESS, i,
-                       fi->actions[i], ofn, ts->notifyData);
-           removeFile(fi, i, ofn);
-       }
+       rc = eraseActions(ts, fi);
 
        if (ts->notify)
            (void)ts->notify(h, RPMCALLBACK_UNINST_STOP, 0, fi->fc,
                        pkgKey, ts->notifyData);
     }
 
-    if (!(ts->transFlags & RPMTRANS_FLAG_TEST)) {
-       rpmMessage(RPMMESS_DEBUG, _("%s: running %s script(s) (if any)\n"),
+    rpmMessage(RPMMESS_DEBUG, _("%s: running %s script(s) (if any)\n"),
                stepName, "post-erase");
 
-       rc = runInstScript(ts, h, RPMTAG_POSTUN, RPMTAG_POSTUNPROG,
-                       fi->scriptArg, (ts->transFlags & RPMTRANS_FLAG_NOSCRIPTS));
-       /* XXX postun failures are not cause for erasure failure. */
-    }
+    rc = runInstScript(ts, h, RPMTAG_POSTUN, RPMTAG_POSTUNPROG,
+               fi->scriptArg, (ts->transFlags & RPMTRANS_FLAG_NOSCRIPTS));
+    /* XXX postun failures are not cause for erasure failure. */
 
     if (!(ts->transFlags & RPMTRANS_FLAG_NOTRIGGERS)) {
        /* Run postun triggers which are set off by this package's removal. */
index fda1e89..377e71f 100644 (file)
@@ -6,7 +6,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2001-01-24 16:31-0500\n"
+"POT-Creation-Date: 2001-01-24 22:29-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"
@@ -1628,82 +1628,82 @@ msgstr ""
 msgid "Symlink points to BuildRoot: %s -> %s\n"
 msgstr ""
 
-#: build/files.c:1225
+#: build/files.c:1226
 #, c-format
 msgid "File doesn't match prefix (%s): %s\n"
 msgstr ""
 
-#: build/files.c:1235
+#: build/files.c:1236
 #, c-format
 msgid "File not found: %s\n"
 msgstr ""
 
-#: build/files.c:1278 build/files.c:1799 build/parsePrep.c:42
+#: build/files.c:1279 build/files.c:1800 build/parsePrep.c:42
 #, c-format
 msgid "Bad owner/group: %s\n"
 msgstr ""
 
-#: build/files.c:1290
+#: build/files.c:1291
 #, c-format
 msgid "File %4d: %07o %s.%s\t %s\n"
 msgstr ""
 
-#: build/files.c:1367
+#: build/files.c:1368
 #, c-format
 msgid "File needs leading \"/\": %s\n"
 msgstr ""
 
-#: build/files.c:1397
+#: build/files.c:1398
 #, c-format
 msgid "File not found by glob: %s\n"
 msgstr ""
 
-#: build/files.c:1451
+#: build/files.c:1452
 msgid "Could not open %%files file %s: %s\n"
 msgstr ""
 
-#: build/files.c:1460 build/pack.c:108
+#: build/files.c:1461 build/pack.c:108
 #, c-format
 msgid "line: %s\n"
 msgstr ""
 
-#: build/files.c:1787
+#: build/files.c:1788
 #, c-format
 msgid "Bad file: %s: %s\n"
 msgstr ""
 
 #. XXX this error message is probably not seen.
-#: build/files.c:1855
+#: build/files.c:1856
 #, c-format
 msgid "Couldn't exec %s: %s\n"
 msgstr ""
 
-#: build/files.c:1860
+#: build/files.c:1861
 #, c-format
 msgid "Couldn't fork %s: %s\n"
 msgstr ""
 
-#: build/files.c:1942
+#: build/files.c:1943
 #, c-format
 msgid "%s failed\n"
 msgstr ""
 
-#: build/files.c:1946
+#: build/files.c:1947
 #, c-format
 msgid "failed to write all data to %s\n"
 msgstr ""
 
-#: build/files.c:2073
+#: build/files.c:2074
 #, c-format
 msgid "Finding  %s: (using %s)...\n"
 msgstr ""
 
-#: build/files.c:2101 build/files.c:2115
+#: build/files.c:2102 build/files.c:2116
 #, c-format
 msgid "Failed to find %s:\n"
 msgstr ""
 
-#: build/files.c:2228
+#: build/files.c:2229
 #, c-format
 msgid "Processing files: %s-%s-%s\n"
 msgstr ""
@@ -2250,92 +2250,92 @@ msgstr ""
 msgid "  %s    A %s\tB %s\n"
 msgstr ""
 
-#: lib/depends.c:949
+#: lib/depends.c:956
 #, c-format
 msgid "%s: %-45s YES (added files)\n"
 msgstr ""
 
-#: lib/depends.c:1008
+#: lib/depends.c:1015
 #, c-format
 msgid "%s: %-45s YES (added provide)\n"
 msgstr ""
 
-#: lib/depends.c:1060
+#: lib/depends.c:1067
 #, c-format
 msgid "%s: %-45s %-3s (cached)\n"
 msgstr ""
 
-#: lib/depends.c:1079
+#: lib/depends.c:1086
 #, c-format
 msgid "%s: %-45s YES (rpmrc provides)\n"
 msgstr ""
 
-#: lib/depends.c:1096
+#: lib/depends.c:1103
 #, c-format
 msgid "%s: %-45s YES (rpmlib provides)\n"
 msgstr ""
 
-#: lib/depends.c:1118
+#: lib/depends.c:1125
 #, c-format
 msgid "%s: %-45s YES (db files)\n"
 msgstr ""
 
-#: lib/depends.c:1131
+#: lib/depends.c:1138
 #, c-format
 msgid "%s: %-45s YES (db provides)\n"
 msgstr ""
 
-#: lib/depends.c:1145
+#: lib/depends.c:1152
 #, c-format
 msgid "%s: %-45s YES (db package)\n"
 msgstr ""
 
-#: lib/depends.c:1161
+#: lib/depends.c:1168
 #, c-format
 msgid "%s: %-45s NO\n"
 msgstr ""
 
-#: lib/depends.c:1182
+#: lib/depends.c:1189
 #, c-format
 msgid "%s: (%s, %s) added to Depends cache.\n"
 msgstr ""
 
 #. requirements are not satisfied.
-#: lib/depends.c:1240
+#: lib/depends.c:1247
 #, c-format
 msgid "package %s-%s-%s require not satisfied: %s\n"
 msgstr ""
 
 #. conflicts exist.
-#: lib/depends.c:1307
+#: lib/depends.c:1314
 #, c-format
 msgid "package %s conflicts: %s\n"
 msgstr ""
 
-#: lib/depends.c:1523
+#: lib/depends.c:1530
 #, c-format
 msgid "removing %s-%s-%s \"%s\" from tsort relations.\n"
 msgstr ""
 
 #. Record all relations.
-#: lib/depends.c:1662
+#: lib/depends.c:1669
 msgid "========== recording tsort relations\n"
 msgstr ""
 
 #. T4. Scan for zeroes.
-#: lib/depends.c:1709
+#: lib/depends.c:1716
 msgid "========== tsorting packages\n"
 msgstr ""
 
-#: lib/depends.c:1754
+#: lib/depends.c:1761
 msgid "========== successors only (presentation order)\n"
 msgstr ""
 
-#: lib/depends.c:1803
+#: lib/depends.c:1810
 msgid "LOOP:\n"
 msgstr ""
 
-#: lib/depends.c:1834
+#: lib/depends.c:1841
 msgid "========== continuing tsort ...\n"
 msgstr ""
 
@@ -2512,7 +2512,7 @@ msgstr ""
 msgid "dataLength() RPM_STRING_TYPE count must be 1.\n"
 msgstr ""
 
-#: lib/header.c:207 lib/header.c:1015 lib/install.c:271
+#: lib/header.c:207 lib/header.c:1015 lib/install.c:239
 #, c-format
 msgid "Data type %d not supported\n"
 msgstr ""
@@ -2597,17 +2597,12 @@ msgstr ""
 msgid "(unknown type)"
 msgstr ""
 
-#: lib/install.c:101
-#, c-format
-msgid "   file: %s%s action: %s\n"
-msgstr ""
-
-#: lib/install.c:122
+#: lib/install.c:90
 #, c-format
 msgid "user %s does not exist - using root\n"
 msgstr ""
 
-#: lib/install.c:130
+#: lib/install.c:98
 #, c-format
 msgid "group %s does not exist - using root\n"
 msgstr ""
@@ -2617,75 +2612,80 @@ msgstr ""
 #. * was used up - if so, we should return a different error.
 #.
 #. XXX FIXME: Fclose with libio destroys errno
-#: lib/install.c:532
+#: lib/install.c:496
 #, c-format
 msgid "unpacking of archive failed%s%s: %s\n"
 msgstr ""
 
-#: lib/install.c:533
+#: lib/install.c:497
 msgid " on file "
 msgstr ""
 
-#: lib/install.c:573
+#: lib/install.c:537
 #, c-format
 msgid "cannot create %s %s\n"
 msgstr ""
 
-#: lib/install.c:579
+#: lib/install.c:543
 #, c-format
 msgid "cannot write to %s\n"
 msgstr ""
 
-#: lib/install.c:606
+#: lib/install.c:566
 msgid "installing a source package\n"
 msgstr ""
 
-#: lib/install.c:663 lib/install.c:696
+#: lib/install.c:601 lib/install.c:635
 msgid "source package contains no .spec file\n"
 msgstr ""
 
-#: lib/install.c:716
+#: lib/install.c:655
 #, c-format
 msgid "renaming %s to %s\n"
 msgstr ""
 
-#: lib/install.c:718 lib/uninstall.c:37
+#: lib/install.c:657
 #, c-format
 msgid "rename of %s to %s failed: %s\n"
 msgstr ""
 
-#: lib/install.c:815
+#: lib/install.c:759
 msgid "source package expected, binary found\n"
 msgstr ""
 
-#: lib/install.c:851 lib/uninstall.c:94
+#: lib/install.c:837
 #, c-format
-msgid "%s: %s-%s-%s has %d files, test = %d\n"
+msgid "   file: %s%s action: %s\n"
 msgstr ""
 
-#: lib/install.c:900 lib/install.c:1065 lib/uninstall.c:132
-#: lib/uninstall.c:181
+#: lib/install.c:866
 #, c-format
-msgid "%s: running %s script(s) (if any)\n"
+msgid "%s%s created as %s\n"
 msgstr ""
 
-#: lib/install.c:907
-msgid "skipping %s-%s-%s install, %%pre scriptlet failed rc %d\n"
+#: lib/install.c:887 lib/uninstall.c:71
+#, c-format
+msgid "%s saved as %s\n"
 msgstr ""
 
-#: lib/install.c:955
+#: lib/install.c:892 lib/uninstall.c:74
 #, c-format
-msgid "%s%s created as %s\n"
+msgid "%s rename of %s to %s failed: %s\n"
 msgstr ""
 
-#: lib/install.c:991
+#: lib/install.c:913 lib/uninstall.c:125
 #, c-format
-msgid "%s saved as %s\n"
+msgid "%s: %s-%s-%s has %d files, test = %d\n"
 msgstr ""
 
-#: lib/install.c:996
+#: lib/install.c:980 lib/install.c:1079 lib/uninstall.c:163
+#: lib/uninstall.c:184
 #, c-format
-msgid "%s rename of %s to %s failed: %s\n"
+msgid "%s: running %s script(s) (if any)\n"
+msgstr ""
+
+#: lib/install.c:987
+msgid "skipping %s-%s-%s install, %%pre scriptlet failed rc %d\n"
 msgstr ""
 
 #: lib/misc.c:328 lib/misc.c:333 lib/misc.c:339
@@ -3020,7 +3020,7 @@ msgstr ""
 msgid "old format source packages cannot be queried\n"
 msgstr ""
 
-#: lib/query.c:563 lib/rpminstall.c:314
+#: lib/query.c:563 lib/rpminstall.c:315
 #, c-format
 msgid "%s does not appear to be a RPM package\n"
 msgstr ""
@@ -3084,7 +3084,7 @@ msgstr ""
 msgid "record %d could not be read\n"
 msgstr ""
 
-#: lib/query.c:746 lib/rpminstall.c:550
+#: lib/query.c:746 lib/rpminstall.c:551
 #, c-format
 msgid "package %s is not installed\n"
 msgstr ""
@@ -3320,117 +3320,117 @@ msgstr ""
 msgid "failed to remove directory %s: %s\n"
 msgstr ""
 
-#: lib/rpminstall.c:144
+#: lib/rpminstall.c:147
 msgid "Preparing..."
 msgstr ""
 
-#: lib/rpminstall.c:147
+#: lib/rpminstall.c:150
 msgid "Preparing packages for installation..."
 msgstr ""
 
-#: lib/rpminstall.c:208
+#: lib/rpminstall.c:209
 msgid "counting packages to install\n"
 msgstr ""
 
-#: lib/rpminstall.c:212
+#: lib/rpminstall.c:213
 #, c-format
 msgid "found %d packages\n"
 msgstr ""
 
-#: lib/rpminstall.c:217
+#: lib/rpminstall.c:218
 msgid "looking for packages to download\n"
 msgstr ""
 
-#: lib/rpminstall.c:232
+#: lib/rpminstall.c:233
 #, c-format
 msgid "skipping %s - rpmGlob failed(%d)\n"
 msgstr ""
 
-#: lib/rpminstall.c:247
+#: lib/rpminstall.c:248
 #, c-format
 msgid "Retrieving %s\n"
 msgstr ""
 
 #. XXX undefined %{name}/%{version}/%{release} here
 #. XXX %{_tmpdir} does not exist
-#: lib/rpminstall.c:257
+#: lib/rpminstall.c:258
 #, c-format
 msgid " ... as %s\n"
 msgstr ""
 
-#: lib/rpminstall.c:261
+#: lib/rpminstall.c:262
 #, c-format
 msgid "skipping %s - transfer failed - %s\n"
 msgstr ""
 
-#: lib/rpminstall.c:288
+#: lib/rpminstall.c:289
 #, c-format
 msgid "retrieved %d packages\n"
 msgstr ""
 
-#: lib/rpminstall.c:300 lib/rpminstall.c:474
+#: lib/rpminstall.c:301 lib/rpminstall.c:475
 #, c-format
 msgid "cannot open file %s: %s\n"
 msgstr ""
 
-#: lib/rpminstall.c:318 lib/rpminstall.c:615
+#: lib/rpminstall.c:319 lib/rpminstall.c:616
 #, c-format
 msgid "%s cannot be installed\n"
 msgstr ""
 
-#: lib/rpminstall.c:333
+#: lib/rpminstall.c:334
 #, c-format
 msgid "cannot open Packages database in %s\n"
 msgstr ""
 
-#: lib/rpminstall.c:355
+#: lib/rpminstall.c:356
 #, c-format
 msgid "package %s is not relocateable\n"
 msgstr ""
 
-#: lib/rpminstall.c:400
+#: lib/rpminstall.c:401
 #, c-format
 msgid "error reading from file %s\n"
 msgstr ""
 
-#: lib/rpminstall.c:405
+#: lib/rpminstall.c:406
 #, c-format
 msgid "file %s requires a newer version of RPM\n"
 msgstr ""
 
-#: lib/rpminstall.c:422
+#: lib/rpminstall.c:423
 #, c-format
 msgid "found %d source and %d binary packages\n"
 msgstr ""
 
-#: lib/rpminstall.c:433
+#: lib/rpminstall.c:434
 msgid "failed dependencies:\n"
 msgstr ""
 
-#: lib/rpminstall.c:454
+#: lib/rpminstall.c:455
 msgid "installing binary packages\n"
 msgstr ""
 
-#: lib/rpminstall.c:537
+#: lib/rpminstall.c:538
 #, c-format
 msgid "cannot open %s/packages.rpm\n"
 msgstr ""
 
-#: lib/rpminstall.c:553
+#: lib/rpminstall.c:554
 #, c-format
 msgid "\"%s\" specifies multiple packages\n"
 msgstr ""
 
-#: lib/rpminstall.c:576
+#: lib/rpminstall.c:577
 msgid "removing these packages would break dependencies:\n"
 msgstr ""
 
-#: lib/rpminstall.c:604
+#: lib/rpminstall.c:605
 #, c-format
 msgid "cannot open %s: %s\n"
 msgstr ""
 
-#: lib/rpminstall.c:610
+#: lib/rpminstall.c:611
 #, c-format
 msgid "Installing %s\n"
 msgstr ""
@@ -3712,24 +3712,24 @@ msgstr ""
 msgid "%s skipped due to missingok flag\n"
 msgstr ""
 
-#: lib/uninstall.c:51
+#: lib/uninstall.c:45
 #, c-format
-msgid "cannot remove %s - directory not empty\n"
+msgid "   file: %s action: %s\n"
 msgstr ""
 
-#: lib/uninstall.c:55
+#: lib/uninstall.c:93
 #, c-format
-msgid "rmdir of %s failed: %s\n"
+msgid "cannot remove %s - directory not empty\n"
 msgstr ""
 
-#: lib/uninstall.c:65
+#: lib/uninstall.c:98
 #, c-format
-msgid "removal of %s failed: %s\n"
+msgid "rmdir of %s failed: %s\n"
 msgstr ""
 
-#: lib/uninstall.c:164
+#: lib/uninstall.c:109
 #, c-format
-msgid "   file: %s action: %s\n"
+msgid "removal of %s failed: %s\n"
 msgstr ""
 
 #: lib/verify.c:59