rpm/install.c

243 lines
5.2 KiB
C
Raw Normal View History

#include <alloca.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "ftp.h"
#include "install.h"
#include "lib/rpmlib.h"
#include "messages.h"
#include "query.h"
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 void printHash(const unsigned long amount, const unsigned long total) {
int hashesNeeded;
if (hashesPrinted != 50) {
hashesNeeded = 50 * (total ? (((float) amount) / total) : 1);
while (hashesNeeded > hashesPrinted) {
printf("#");
hashesPrinted++;
}
fflush(stdout);
hashesPrinted = hashesNeeded;
if (hashesPrinted == 50)
printf("\n");
}
}
static void printPercent(const unsigned long amount, const unsigned long total)
{
printf("%%%% %f\n", (total
? ((float) ((((float) amount) / total) * 100))
: 100.0));
fflush(stdout);
}
int doInstall(char * prefix, char * arg, int installFlags, int interfaceFlags) {
rpmdb db;
int fd;
int mode, rc;
char * chptr;
notifyFunction fn;
char * printFormat = NULL;
hashesPrinted = 0;
if (installFlags & INSTALL_TEST)
mode = O_RDONLY;
else
mode = O_RDWR;
if (interfaceFlags & RPMINSTALL_PERCENT)
fn = printPercent;
else if (interfaceFlags & RPMINSTALL_HASH)
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);
}
message(MESS_DEBUG, "installing %s\n", arg);
if (!strncmp(arg, "ftp://", 6)) {
if (isVerbose()) {
printf("Retrieving %s\n", arg);
}
fd = getFtpURL(prefix, arg + 6);
if (fd < 0) {
fprintf(stderr, "error: ftp of %s failed - %s\n", arg,
ftpStrerror(fd));
return 1;
}
} else {
fd = open(arg, O_RDONLY);
if (fd < 0) {
rpmdbClose(db);
fprintf(stderr, "error: cannot open %s\n", arg);
return 1;
}
}
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);
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 (rc) {
fprintf(stderr, "error: %s cannot be installed\n", arg);
}
close(fd);
rpmdbClose(db);
return rc;
}
void doUninstall(char * prefix, char * arg, int flags, int uninstallFlags) {
rpmdb db;
dbIndexSet matches;
int i;
int mode;
int rc;
int count;
if (flags & UNINSTALL_TEST)
mode = O_RDONLY;
else
mode = O_RDWR | O_EXCL;
if (rpmdbOpen(prefix, &db, mode, 0644)) {
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);
}
}
}
freeDBIndexRecord(matches);
}
rpmdbClose(db);
}
int doSourceInstall(char * prefix, char * arg, char ** specFile) {
int fd;
int rc;
fd = open(arg, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "error: cannot open %s\n", arg);
return 1;
}
if (isVerbose())
printf("Installing %s\n", arg);
rc = rpmInstallSourcePackage(prefix, fd, specFile);
if (rc == 1) {
fprintf(stderr, "error: %s cannot be installed\n", arg);
}
close(fd);
return rc;
}
static int getFtpURL(char * prefix, char * hostAndFile) {
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);
strcpy(buf, hostAndFile);
chptr = buf;
while (*chptr && (*chptr != '/')) chptr++;
if (!*chptr) return -1;
*chptr = '\0';
ftpconn = ftpOpen(buf, NULL, NULL);
if (ftpconn < 0) return ftpconn;
*chptr = '/';
tmp = alloca(strlen(prefix) + 60);
sprintf(tmp, "%s/var/tmp/rpm.ftp.%d", prefix, getpid());
fd = creat(tmp, 0600);
if (fd < 0) {
unlink(tmp);
ftpClose(ftpconn);
return FTPERR_UNKNOWN;
}
if ((rc = ftpGetFile(ftpconn, chptr, fd))) {
unlink(tmp);
close(fd);
ftpClose(ftpconn);
return rc;
}
ftpClose(ftpconn);
close(fd);
fd = open(tmp, O_RDONLY);
unlink(tmp);
return fd;
}