From 8c20f1d6dc869c453298903d9743a6f28270aec3 Mon Sep 17 00:00:00 2001 From: ewt Date: Mon, 10 Jun 1996 17:41:24 +0000 Subject: [PATCH] 1) changed doInstall() and doUninstall() calls to pass all of the arguments at once 2) added dependency checking CVS patchset: 631 CVS date: 1996/06/10 17:41:24 --- install.c | 366 ++++++++++++++++++++++++++++++++++++++++++++++---------------- install.h | 13 ++- 2 files changed, 283 insertions(+), 96 deletions(-) diff --git a/install.c b/install.c index 7b2f1c0..213b68f 100644 --- a/install.c +++ b/install.c @@ -1,12 +1,14 @@ #include #include #include +#include #include #include #include "ftp.h" #include "install.h" #include "lib/rpmlib.h" +#include "lib/package.h" #include "messages.h" #include "query.h" @@ -14,7 +16,7 @@ static int hashesPrinted = 0; static void printHash(const unsigned long amount, const unsigned long total); static void printPercent(const unsigned long amount, const unsigned long total); -static int getFtpURL(char * prefix, char * hostAndFile); +static int getFtpURL(char * hostAndFile, char * dest); static void printHash(const unsigned long amount, const unsigned long total) { int hashesNeeded; @@ -41,20 +43,16 @@ static void printPercent(const unsigned long amount, const unsigned long total) fflush(stdout); } -int doInstall(char * prefix, char * arg, int installFlags, int interfaceFlags) { - rpmdb db; - int fd; - int mode, rc; +static int installPackages(char * prefix, char ** packages, + int numPackages, int installFlags, + int interfaceFlags, rpmdb db) { + int i, fd; + int numFailed = 0; + char ** filename; + char * printFormat = NULL; char * chptr; + int rc; notifyFunction fn; - char * printFormat = NULL; - - hashesPrinted = 0; - - if (installFlags & INSTALL_TEST) - mode = O_RDONLY; - else - mode = O_RDWR; if (interfaceFlags & RPMINSTALL_PERCENT) fn = printPercent; @@ -62,71 +60,225 @@ int doInstall(char * prefix, char * arg, int installFlags, int interfaceFlags) { fn = printHash; else fn = NULL; - - if (rpmdbOpen(prefix, &db, mode | O_CREAT, 0644)) { - fprintf(stderr, "error: cannot open %s/var/lib/rpm/packages.rpm\n", - prefix); - exit(1); + + for (i = 0, filename = packages; i < numPackages; i++, filename++) { + if (!*filename) continue; + + fd = open(*filename, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "error: cannot open %s\n", *filename); + numFailed++; + *filename = NULL; + } + + if (interfaceFlags & RPMINSTALL_PERCENT) + printFormat = "%%f %s:%s:%s\n"; + else if (isVerbose() && (interfaceFlags & RPMINSTALL_HASH)) { + chptr = strrchr(*filename, '/'); + if (!chptr) + chptr = *filename; + else + chptr++; + + printFormat = "%-28s"; + } else if (isVerbose()) + printf("Installing %s\n", *filename); + + if (db) { + rc = rpmInstallPackage(prefix, db, fd, installFlags, fn, + printFormat); + } else { + if (installFlags &= INSTALL_TEST) { + message(MESS_DEBUG, "stopping source install as we're " + "just testing\n"); + rc = 0; + } else + rc = rpmInstallSourcePackage(prefix, fd, NULL); + } + + if (rc == 1) { + fprintf(stderr, "error: %s does not appear to be a RPM package\n", + *filename); + } + + if (rc) { + fprintf(stderr, "error: %s cannot be installed\n", *filename); + numFailed++; + } + + close(fd); } - message(MESS_DEBUG, "installing %s\n", arg); + return numFailed; +} + +int doInstall(char * prefix, char ** argv, int installFlags, + int interfaceFlags) { + rpmdb db; + int fd, i; + int mode, rc; + char ** packages, ** tmpPackages; + char ** filename; + int numPackages; + int numTmpPackages = 0, numBinaryPackages = 0, numSourcePackages = 0; + int numFailed = 0; + Header * binaryHeaders; + int isSource; + int tmpnum = 0; + rpmDependencies rpmdep; + struct rpmDependencyConflict * conflicts; + int numConflicts; + int stopInstall = 0; + + if (installFlags & INSTALL_TEST) + mode = O_RDONLY; + else + mode = O_RDWR; - if (!strncmp(arg, "ftp://", 6)) { - if (isVerbose()) { - printf("Retrieving %s\n", arg); + message(MESS_DEBUG, "counting packages to install\n"); + for (filename = argv, numPackages = 0; *filename; filename++, numPackages++) + ; + + message(MESS_DEBUG, "found %d packages\n", numPackages); + packages = alloca((numPackages + 1) * sizeof(char *)); + packages[numPackages] = NULL; + tmpPackages = alloca((numPackages + 1) * sizeof(char *)); + binaryHeaders = alloca((numPackages + 1) * sizeof(Header)); + + message(MESS_DEBUG, "looking for packages to download\n"); + for (filename = argv, i = 0; *filename; filename++) { + if (!strncmp(*filename, "ftp://", 6)) { + if (isVerbose()) { + printf("Retrieving %s\n", *filename); + } + packages[i] = alloca(strlen(*filename) + 30 + strlen(prefix)); + sprintf(packages[i], "%s/var/tmp/rpm-ftp-%d-%d.tmp", prefix, + tmpnum++, getpid()); + message(MESS_DEBUG, "getting %s as %s\n", *filename, packages[i]); + fd = getFtpURL(*filename + 6, packages[i]); + if (fd < 0) { + fprintf(stderr, "error: skipping %s - ftp failed - %s\n", + *filename, ftpStrerror(fd)); + numFailed++; + } else { + tmpPackages[numTmpPackages++] = packages[i]; + i++; + } + } else { + packages[i++] = *filename; } - fd = getFtpURL(prefix, arg + 6); + } + + message(MESS_DEBUG, "retrieved %d packages\n", numTmpPackages); + + message(MESS_DEBUG, "finding source and binary packages\n"); + for (filename = packages; *filename; filename++) { + fd = open(*filename, O_RDONLY); if (fd < 0) { - fprintf(stderr, "error: ftp of %s failed - %s\n", arg, - ftpStrerror(fd)); - return 1; + fprintf(stderr, "error: cannot open %s\n", *filename); + numFailed++; + *filename = NULL; } - } else { - fd = open(arg, O_RDONLY); - if (fd < 0) { - rpmdbClose(db); - fprintf(stderr, "error: cannot open %s\n", arg); - return 1; + + rc = pkgReadHeader(fd, &binaryHeaders[numBinaryPackages], &isSource); + + close(fd); + + if (rc == 1) { + fprintf(stderr, "error: %s does not appear to be a RPM package\n", + *filename); + } + + if (rc) { + fprintf(stderr, "error: %s cannot be installed\n", *filename); + numFailed++; + *filename = NULL; + } else if (isSource) { + freeHeader(binaryHeaders[numBinaryPackages]); + numSourcePackages++; + } else { + numBinaryPackages++; } } - if (interfaceFlags & RPMINSTALL_PERCENT) - printFormat = "%%f %s:%s:%s\n"; - else if (isVerbose() && (interfaceFlags & RPMINSTALL_HASH)) { - chptr = strrchr(arg, '/'); - if (!chptr) - chptr = arg; - else - chptr++; - - printFormat = "%-28s"; - } else if (isVerbose()) - printf("Installing %s\n", arg); + message(MESS_DEBUG, "found %d source and %d binary packages\n", + numSourcePackages, numBinaryPackages); - rc = rpmInstallPackage(prefix, db, fd, installFlags, fn, printFormat); - if (rc == 1) { - fprintf(stderr, "error: %s does not appear to be a RPM package\n", arg); + if (numBinaryPackages) { + message(MESS_DEBUG, "opening database mode: 0%o\n", mode | O_CREAT); + if (rpmdbOpen(prefix, &db, mode | O_CREAT, 0644)) { + fprintf(stderr, "error: cannot open %s/var/lib/rpm/packages.rpm\n", + prefix); + exit(1); + } + + if (!(interfaceFlags & RPMINSTALL_NODEPS)) { + rpmdep = rpmdepDependencies(db); + for (i = 0; i < numBinaryPackages; i++) + rpmdepAddPackage(rpmdep, binaryHeaders[i]); + + if (rpmdepCheck(rpmdep, &conflicts, &numConflicts)) { + numFailed = numPackages; + stopInstall = 1; + } + + if (!stopInstall && conflicts) { + fprintf(stderr, "failed dependencies:\n"); + for (i = 0; i < numConflicts; i++) { + fprintf(stderr, "\t%s is needed by %s-%s-%s\n", + conflicts[i].needsName, conflicts[i].byName, + conflicts[i].byVersion, conflicts[i].byRelease); + } + + free(conflicts); + numFailed = numPackages; + stopInstall = 1; + } + } } - - if (rc) { - fprintf(stderr, "error: %s cannot be installed\n", arg); + else + db = NULL; + + if (!stopInstall) { + hashesPrinted = 0; + message(MESS_DEBUG, "installing binary packages\n"); + numFailed += installPackages(prefix, packages, numPackages, + installFlags, interfaceFlags, db); } - close(fd); - rpmdbClose(db); + for (i = 0; i < numTmpPackages; i++) + unlink(tmpPackages[i]); - return rc; + if (db) rpmdbClose(db); + + return numFailed; } -void doUninstall(char * prefix, char * arg, int flags, int uninstallFlags) { +int doUninstall(char * prefix, char ** argv, int uninstallFlags, + int interfaceFlags) { rpmdb db; dbIndexSet matches; - int i; + int i, j; int mode; int rc; int count; - - if (flags & UNINSTALL_TEST) + int numPackages; + int * packageOffsets; + char ** arg; + int numFailed = 0; + rpmDependencies rpmdep; + struct rpmDependencyConflict * conflicts; + int numConflicts; + int stopUninstall = 0; + + message(MESS_DEBUG, "counting packages to uninstall\n"); + for (arg = argv, numPackages = 0; *arg; arg++, numPackages++) + ; + message(MESS_DEBUG, "found %d packages to uninstall\n", numPackages); + + packageOffsets = alloca(sizeof(int *) * numPackages); + + if (uninstallFlags & UNINSTALL_TEST) mode = O_RDONLY; else mode = O_RDWR | O_EXCL; @@ -135,35 +287,73 @@ void doUninstall(char * prefix, char * arg, int flags, int uninstallFlags) { fprintf(stderr, "cannot open %s/var/lib/rpm/packages.rpm\n", prefix); exit(1); } - - rc = findPackageByLabel(db, arg, &matches); - if (rc == 1) - fprintf(stderr, "package %s is not installed\n", arg); - else if (rc == 2) - fprintf(stderr, "error searching for package %s\n", arg); - else { - count = 0; - for (i = 0; i < matches.count; i++) - if (matches.recs[i].recOffset) count++; - - if (count > 1) { - fprintf(stderr, "\"%s\" specifies multiple packages\n", arg); - } - else { - for (i = 0; i < matches.count; i++) { - if (matches.recs[i].recOffset) { - message(MESS_DEBUG, "uninstalling record number %d\n", - matches.recs[i].recOffset); - rpmRemovePackage(prefix, db, matches.recs[i].recOffset, - 0, flags & UNINSTALL_TEST); + + j = 0; + for (arg = argv, numPackages = 0; *arg; arg++, numPackages++) { + rc = findPackageByLabel(db, *arg, &matches); + if (rc == 1) { + fprintf(stderr, "package %s is not installed\n", *arg); + numFailed++; + } else if (rc == 2) { + fprintf(stderr, "error searching for package %s\n", *arg); + numFailed++; + } else { + count = 0; + for (i = 0; i < matches.count; i++) + if (matches.recs[i].recOffset) count++; + + if (count > 1) { + fprintf(stderr, "\"%s\" specifies multiple packages\n", *arg); + numFailed++; + } + else { + for (i = 0; i < matches.count; i++) { + if (matches.recs[i].recOffset) { + packageOffsets[j++] = matches.recs[i].recOffset; + } } } + + freeDBIndexRecord(matches); + } + } + numPackages = j; + + if (!(interfaceFlags & RPMUNINSTALL_NODEPS)) { + rpmdep = rpmdepDependencies(db); + for (i = 0; i < numPackages; i++) + rpmdepRemovePackage(rpmdep, packageOffsets[i]); + + if (rpmdepCheck(rpmdep, &conflicts, &numConflicts)) { + numFailed = numPackages; + stopUninstall = 1; + } + + if (!stopUninstall && conflicts) { + fprintf(stderr, "failed dependencies:\n"); + for (i = 0; i < numConflicts; i++) { + fprintf(stderr, "\t%s is needed by %s-%s-%s\n", + conflicts[i].needsName, conflicts[i].byName, + conflicts[i].byVersion, conflicts[i].byRelease); + } + + free(conflicts); + numFailed += numPackages; + stopUninstall = 1; } + } - freeDBIndexRecord(matches); + if (!stopUninstall) { + for (i = 0; i < numPackages; i++) { + message(MESS_DEBUG, "uninstalling record number %d\n", + packageOffsets[i]); + rpmRemovePackage(prefix, db, packageOffsets[i], 0, uninstallFlags); + } } rpmdbClose(db); + + return numFailed; } int doSourceInstall(char * prefix, char * arg, char ** specFile) { @@ -189,15 +379,13 @@ int doSourceInstall(char * prefix, char * arg, char ** specFile) { return rc; } -static int getFtpURL(char * prefix, char * hostAndFile) { +static int getFtpURL(char * hostAndFile, char * dest) { char * buf; char * chptr; int ftpconn; int fd; int rc; - char * tmp; - message(MESS_DEBUG, "getting %s via anonymous ftp\n", hostAndFile); buf = alloca(strlen(hostAndFile) + 1); @@ -214,18 +402,17 @@ static int getFtpURL(char * prefix, char * hostAndFile) { *chptr = '/'; - tmp = alloca(strlen(prefix) + 60); - sprintf(tmp, "%s/var/tmp/rpm.ftp.%d", prefix, getpid()); - fd = creat(tmp, 0600); + fd = creat(dest, 0600); if (fd < 0) { - unlink(tmp); + message(MESS_DEBUG, "failed to create %s\n", dest); + unlink(dest); ftpClose(ftpconn); return FTPERR_UNKNOWN; } if ((rc = ftpGetFile(ftpconn, chptr, fd))) { - unlink(tmp); + unlink(dest); close(fd); ftpClose(ftpconn); return rc; @@ -233,10 +420,5 @@ static int getFtpURL(char * prefix, char * hostAndFile) { ftpClose(ftpconn); - close(fd); - fd = open(tmp, O_RDONLY); - - unlink(tmp); - return fd; } diff --git a/install.h b/install.h index efc8edf..c8e9ab1 100644 --- a/install.h +++ b/install.h @@ -1,12 +1,17 @@ #ifndef _H_INSTALL #define _H_INSTALL -#define RPMINSTALL_PERCENT 1 -#define RPMINSTALL_HASH 2 +#define RPMINSTALL_PERCENT (1 << 0) +#define RPMINSTALL_HASH (1 << 1) +#define RPMINSTALL_NODEPS (1 << 2) -int doInstall(char * prefix, char * arg, int installFlags, int interfaceFlags); +#define RPMUNINSTALL_NODEPS (1 << 0) + +int doInstall(char * prefix, char ** argv, int installFlags, + int interfaceFlags); int doSourceInstall(char * prefix, char * arg, char ** specFile); -void doUninstall(char * prefix, char * arg, int test, int uninstallFlags); +int doUninstall(char * prefix, char ** argv, int uninstallFlags, + int interfaceFlags); #endif -- 2.7.4