summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--ftp.c292
-rw-r--r--ftp.h14
-rw-r--r--install.c99
-rw-r--r--lib/query.c27
-rw-r--r--lib/rpmio.h2
-rw-r--r--po/rpm.pot176
-rw-r--r--popt/po/popt.pot2
-rw-r--r--url.c324
-rw-r--r--url.h19
-rw-r--r--verify.c38
11 files changed, 594 insertions, 404 deletions
diff --git a/CHANGES b/CHANGES
index bd0bd651c..68f33073a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,5 @@
2.5.6 -> 2.90
+ - permit http:// and file:// url's as well as ftp://.
- change --rcfile to permit colon separated file list.
- compile in defaults from rpmrc/macros.
- finish hiding rpmdb index record data ("matches").
@@ -34,6 +35,10 @@
- there must be a { between two % in a query format (unless %% is used)
2.5.5 -> 2.5.6:
+ - attempt ftp ABOR on query/verify url's.
+ - cache open ftp control descriptor with password.
+ - verify needed same realpath semantics as query.
+ - plug fd leak in urlGetFile().
- translate cpio errors using cpioStrerror.
- display "..?....." rather than "..5....." for unreadable files.
- run time (rather than compile time) host endian check.
diff --git a/ftp.c b/ftp.c
index c2c8b76ff..5d9c84a38 100644
--- a/ftp.c
+++ b/ftp.c
@@ -27,6 +27,7 @@ extern int h_errno;
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
+#include <arpa/telnet.h>
#include "rpmio.h"
@@ -48,12 +49,15 @@ int inet_aton(const char *cp, struct in_addr *inp);
#include "url.h"
#include "ftp.h"
-static int ftpCheckResponse(int sock, char ** str);
-static int ftpCommand(int sock, char * command, ...);
-static int ftpReadData(int sock, FD_t fdo);
+static int ftpDebug = 0;
+static int ftpTimeoutSecs = TIMEOUT_SECS;
+
+static int ftpCheckResponse(urlinfo *u, char ** str);
+static int ftpCommand(urlinfo *u, char * command, ...);
+static int copyData(FD_t sfd, FD_t tfd);
static int getHostAddress(const char * host, struct in_addr * address);
-static int ftpCheckResponse(int sock, char ** str) {
+static int ftpCheckResponse(urlinfo *u, char ** str) {
static char buf[BUFFER_SIZE + 1];
int bufLength = 0;
fd_set emptySet, readSet;
@@ -68,12 +72,12 @@ static int ftpCheckResponse(int sock, char ** str) {
do {
FD_ZERO(&emptySet);
FD_ZERO(&readSet);
- FD_SET(sock, &readSet);
+ FD_SET(u->ftpControl, &readSet);
- timeout.tv_sec = TIMEOUT_SECS;
+ timeout.tv_sec = ftpTimeoutSecs;
timeout.tv_usec = 0;
- rc = select(sock + 1, &readSet, &emptySet, &emptySet, &timeout);
+ rc = select(u->ftpControl + 1, &readSet, &emptySet, &emptySet, &timeout);
if (rc < 1) {
if (rc==0)
return FTPERR_BAD_SERVER_RESPONSE;
@@ -82,7 +86,7 @@ static int ftpCheckResponse(int sock, char ** str) {
} else
rc = 0;
- bytesRead = read(sock, buf + bufLength, sizeof(buf) - bufLength - 1);
+ bytesRead = read(u->ftpControl, buf + bufLength, sizeof(buf) - bufLength - 1);
bufLength += bytesRead;
@@ -127,10 +131,14 @@ static int ftpCheckResponse(int sock, char ** str) {
}
} while (doesContinue && !rc);
+if (ftpDebug)
+fprintf(stderr, "<- %s\n", buf);
+
if (*errorCode == '4' || *errorCode == '5') {
- if (!strncmp(errorCode, "550", 3)) {
+ if (!strncmp(errorCode, "550", 3))
return FTPERR_FILE_NOT_FOUND;
- }
+ if (!strncmp(errorCode, "552", 3))
+ return FTPERR_NIC_ABORT_IN_PROGRESS;
return FTPERR_BAD_SERVER_RESPONSE;
}
@@ -140,7 +148,7 @@ static int ftpCheckResponse(int sock, char ** str) {
return 0;
}
-int ftpCommand(int sock, char * command, ...) {
+int ftpCommand(urlinfo *u, char * command, ...) {
va_list ap;
int len;
char * s;
@@ -171,12 +179,14 @@ int ftpCommand(int sock, char * command, ...) {
buf[len - 2] = '\r';
buf[len - 1] = '\n';
buf[len] = '\0';
-
- if (write(sock, buf, len) != len) {
+
+if (ftpDebug)
+fprintf(stderr, "-> %s", buf);
+ if (write(u->ftpControl, buf, len) != len) {
return FTPERR_SERVER_IO_ERROR;
}
- return ftpCheckResponse(sock, NULL);
+ return ftpCheckResponse(u, NULL);
}
#if !defined(USE_ALT_DNS) || !USE_ALT_DNS
@@ -208,28 +218,44 @@ static int getHostAddress(const char * host, struct in_addr * address) {
static int tcpConnect(const char *host, int port)
{
- int sock;
struct sockaddr_in sin;
+ int sock = -1;
+ int rc;
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
- if ((sock = getHostAddress(host, &sin.sin_addr)) < 0)
- return sock;
+ sin.sin_addr.s_addr = INADDR_ANY;
+
+ do {
+ if ((rc = getHostAddress(host, &sin.sin_addr)) < 0)
+ break;
- if ((sock = socket(sin.sin_family, SOCK_STREAM, IPPROTO_IP)) < 0)
- return FTPERR_FAILED_CONNECT;
+ if ((sock = socket(sin.sin_family, SOCK_STREAM, IPPROTO_IP)) < 0) {
+ rc = FTPERR_FAILED_CONNECT;
+ break;
+ }
if (connect(sock, (struct sockaddr *) &sin, sizeof(sin))) {
+ rc = FTPERR_FAILED_CONNECT;
+ break;
+ }
+ } while (0);
+
+ if (rc < 0 && sock >= 0) {
close(sock);
- return FTPERR_FAILED_CONNECT;
+ return rc;
}
+
+if (ftpDebug)
+fprintf(stderr,"++ connect %s:%d on fd %d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), sock);
+
return sock;
}
int httpOpen(urlinfo *u)
{
int sock;
- char *host;
+ const char *host;
int port;
char *buf;
size_t len;
@@ -247,21 +273,23 @@ int httpOpen(urlinfo *u)
strcpy(buf, "GET ");
strcat(buf, u->path);
strcat(buf, "\r\n");
+
if (write(sock, buf, len) != len) {
close(sock);
return FTPERR_SERVER_IO_ERROR;
}
+if (ftpDebug)
+fprintf(stderr, "-> %s", buf);
return sock;
}
int ftpOpen(urlinfo *u)
{
- char * host;
- char * user;
- char * password;
+ const char * host;
+ const char * user;
+ const char * password;
int port;
- int sock;
int rc;
if (u == NULL || ((host = u->host) == NULL))
@@ -274,85 +302,132 @@ int ftpOpen(urlinfo *u)
if ((password = u->password) == NULL) {
if (getuid()) {
- struct passwd * pw;
- pw = getpwuid(getuid());
- password = alloca(strlen(pw->pw_name) + 2);
- strcpy(password, pw->pw_name);
- strcat(password, "@");
+ struct passwd * pw = getpwuid(getuid());
+ char *myp = alloca(strlen(pw->pw_name) + sizeof("@"));
+ strcpy(myp, pw->pw_name);
+ strcat(myp, "@");
+ password = myp;
} else {
password = "root@";
}
}
- if ((sock = tcpConnect(host, port)) < 0)
- return sock;
+ if ((u->ftpControl = tcpConnect(host, port)) < 0)
+ return u->ftpControl;
/* ftpCheckResponse() assumes the socket is nonblocking */
- if (fcntl(sock, F_SETFL, O_NONBLOCK)) {
- close(sock);
+ if (fcntl(u->ftpControl, F_SETFL, O_NONBLOCK)) {
+ close(u->ftpControl);
+ u->ftpControl = -1;
return FTPERR_FAILED_CONNECT;
}
- if ((rc = ftpCheckResponse(sock, NULL))) {
+ if ((rc = ftpCheckResponse(u, NULL))) {
return rc;
}
- if ((rc = ftpCommand(sock, "USER", user, NULL))) {
- close(sock);
+ if ((rc = ftpCommand(u, "USER", user, NULL))) {
+ close(u->ftpControl);
+ u->ftpControl = -1;
return rc;
}
- if ((rc = ftpCommand(sock, "PASS", password, NULL))) {
- close(sock);
+ if ((rc = ftpCommand(u, "PASS", password, NULL))) {
+ close(u->ftpControl);
+ u->ftpControl = -1;
return rc;
}
- if ((rc = ftpCommand(sock, "TYPE", "I", NULL))) {
- close(sock);
+ if ((rc = ftpCommand(u, "TYPE", "I", NULL))) {
+ close(u->ftpControl);
+ u->ftpControl = -1;
return rc;
}
- return sock;
+ return u->ftpControl;
}
-int ftpReadData(int sock, FD_t fdo) {
+int copyData(FD_t sfd, FD_t tfd) {
char buf[BUFFER_SIZE];
fd_set emptySet, readSet;
struct timeval timeout;
- int bytesRead, rc;
+ int bytesRead;
+ int bytesCopied = 0;
+ int rc;
while (1) {
FD_ZERO(&emptySet);
FD_ZERO(&readSet);
- FD_SET(sock, &readSet);
+ FD_SET(fdFileno(sfd), &readSet);
- timeout.tv_sec = TIMEOUT_SECS;
+ timeout.tv_sec = ftpTimeoutSecs;
timeout.tv_usec = 0;
- rc = select(sock + 1, &readSet, &emptySet, &emptySet, &timeout);
+ rc = select(fdFileno(sfd) + 1, &readSet, &emptySet, &emptySet, &timeout);
if (rc == 0) {
- close(sock);
- return FTPERR_SERVER_TIMEOUT;
+ rc = FTPERR_SERVER_TIMEOUT;
+ break;
} else if (rc < 0) {
- close(sock);
- return FTPERR_UNKNOWN;
+ rc = FTPERR_UNKNOWN;
+ break;
}
- bytesRead = read(sock, buf, sizeof(buf));
+ bytesRead = fdRead(sfd, buf, sizeof(buf));
if (bytesRead == 0) {
- close(sock);
- return 0;
+ rc = 0;
+ break;
}
- if (fdWrite(fdo, buf, bytesRead) != bytesRead) {
- close(sock);
- return FTPERR_FILE_IO_ERROR;
+ if (fdWrite(tfd, buf, bytesRead) != bytesRead) {
+ rc = FTPERR_FILE_IO_ERROR;
+ break;
}
+ bytesCopied += bytesRead;
}
+
+if (ftpDebug)
+fprintf(stderr, "++ copied %d bytes: %s\n", bytesCopied, ftpStrerror(rc));
+
+ fdClose(sfd);
+ return rc;
}
-int ftpGetFileDesc(int sock, char * remotename) {
- int dataSocket;
+int ftpAbort(FD_t fd) {
+ urlinfo *u = (urlinfo *)fd->fd_url;
+ char buf[BUFFER_SIZE];
+ int rc;
+ int tosecs = ftpTimeoutSecs;
+
+if (ftpDebug)
+fprintf(stderr, "-> ABOR\n");
+
+ sprintf(buf, "%c%c%c", IAC, IP, IAC);
+ send(u->ftpControl, buf, 3, MSG_OOB);
+ sprintf(buf, "%cABOR\r\n", DM);
+ if (write(u->ftpControl, buf, 7) != 7) {
+ return FTPERR_SERVER_IO_ERROR;
+ }
+ if (fdFileno(fd) >= 0) {
+ while(read(fdFileno(fd), buf, sizeof(buf)) > 0)
+ ;
+ }
+
+ ftpTimeoutSecs = 10;
+ if ((rc = ftpCheckResponse(u, NULL)) == FTPERR_NIC_ABORT_IN_PROGRESS) {
+ rc = ftpCheckResponse(u, NULL);
+ }
+ rc = ftpCheckResponse(u, NULL);
+ ftpTimeoutSecs = tosecs;
+
+ if (fdFileno(fd) >= 0)
+ fdClose(fd);
+ return 0;
+}
+
+int ftpGetFileDesc(FD_t fd)
+{
+ urlinfo *u;
+ const char *remotename;
struct sockaddr_in dataAddress;
int i, j;
char * passReply;
@@ -360,10 +435,15 @@ int ftpGetFileDesc(int sock, char * remotename) {
char * retrCommand;
int rc;
- if (write(sock, "PASV\r\n", 6) != 6) {
+ u = (urlinfo *)fd->fd_url;
+ remotename = u->path;
+
+if (ftpDebug)
+fprintf(stderr, "-> PASV\n");
+ if (write(u->ftpControl, "PASV\r\n", 6) != 6) {
return FTPERR_SERVER_IO_ERROR;
}
- if ((rc = ftpCheckResponse(sock, &passReply)))
+ if ((rc = ftpCheckResponse(u, &passReply)))
return FTPERR_PASSIVE_ERROR;
chptr = passReply;
@@ -399,8 +479,8 @@ int ftpGetFileDesc(int sock, char * remotename) {
if (!inet_aton(passReply, &dataAddress.sin_addr))
return FTPERR_PASSIVE_ERROR;
- dataSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
- if (dataSocket < 0) {
+ fd->fd_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+ if (fdFileno(fd) < 0) {
return FTPERR_FAILED_CONNECT;
}
@@ -408,72 +488,91 @@ int ftpGetFileDesc(int sock, char * remotename) {
sprintf(retrCommand, "RETR %s\r\n", remotename);
i = strlen(retrCommand);
- if (write(sock, retrCommand, i) != i) {
- return FTPERR_SERVER_IO_ERROR;
+ while (connect(fdFileno(fd), (struct sockaddr *) &dataAddress,
+ sizeof(dataAddress)) < 0) {
+ if (errno == EINTR)
+ continue;
+ fdClose(fd);
+ return FTPERR_FAILED_DATA_CONNECT;
}
- if (connect(dataSocket, (struct sockaddr *) &dataAddress,
- sizeof(dataAddress))) {
- close(dataSocket);
- return FTPERR_FAILED_DATA_CONNECT;
+if (ftpDebug)
+fprintf(stderr, "-> %s", retrCommand);
+ if (write(u->ftpControl, retrCommand, i) != i) {
+ return FTPERR_SERVER_IO_ERROR;
}
- if ((rc = ftpCheckResponse(sock, NULL))) {
- close(dataSocket);
+ if ((rc = ftpCheckResponse(u, NULL))) {
+ fdClose(fd);
return rc;
}
- return dataSocket;
+ return 0;
}
-int ftpGetFileDone(int sock) {
- if (ftpCheckResponse(sock, NULL)) {
+static int ftpGetFileDone(urlinfo *u) {
+ if (ftpCheckResponse(u, NULL))
return FTPERR_BAD_SERVER_RESPONSE;
- }
-
return 0;
}
-int ftpGetFile(int sock, char * remotename, FD_t dest) {
- int dataSocket, rc;
+int httpGetFile(FD_t sfd, FD_t tfd) {
+ return copyData(sfd, tfd);
+}
- dataSocket = ftpGetFileDesc(sock, remotename);
- if (dataSocket < 0) return dataSocket;
+int ftpGetFile(FD_t sfd, FD_t tfd)
+{
+ urlinfo *u;
+ int rc;
- rc = ftpReadData(dataSocket, dest);
- close(dataSocket);
-
- if (rc) return rc;
+ /* XXX sfd will be freed by copyData -- grab sfd->fd_url now */
+ u = (urlinfo *)sfd->fd_url;
- return ftpGetFileDone(sock);
+ /* XXX normally sfd = ufdOpen(...) and this code does not execute */
+ if (fdFileno(sfd) < 0 && (rc = ftpGetFileDesc(sfd)) < 0) {
+ fdClose(sfd);
+ return rc;
+ }
+
+ rc = copyData(sfd, tfd);
+ if (rc < 0)
+ return rc;
+
+ return ftpGetFileDone(u);
}
-void ftpClose(int sock) {
- close(sock);
+int ftpClose(FD_t fd) {
+ int fdno = ((urlinfo *)fd->fd_url)->ftpControl;
+ if (fdno >= 0)
+ close(fdno);
+ return 0;
}
const char *ftpStrerror(int errorNumber) {
switch (errorNumber) {
+ case 0:
+ return _("Success");
+
case FTPERR_BAD_SERVER_RESPONSE:
- return _("Bad FTP server response");
+ return _("Bad server response");
case FTPERR_SERVER_IO_ERROR:
- return _("FTP IO error");
+ return _("Server IO error");
case FTPERR_SERVER_TIMEOUT:
- return _("FTP server timeout");
+ return _("Server timeout");
case FTPERR_BAD_HOST_ADDR:
- return _("Unable to lookup FTP server host address");
+ return _("Unable to lookup server host address");
case FTPERR_BAD_HOSTNAME:
- return _("Unable to lookup FTP server host name");
+ return _("Unable to lookup server host name");
case FTPERR_FAILED_CONNECT:
- return _("Failed to connect to FTP server");
+ return _("Failed to connect to server");
case FTPERR_FAILED_DATA_CONNECT:
- return _("Failed to establish data connection to FTP server");
+ return _("Failed to establish data connection to server");
case FTPERR_FILE_IO_ERROR:
return _("IO error to local file");
@@ -484,9 +583,12 @@ const char *ftpStrerror(int errorNumber) {
case FTPERR_FILE_NOT_FOUND:
return _("File not found on server");
+ case FTPERR_NIC_ABORT_IN_PROGRESS:
+ return _("Abort in progress");
+
case FTPERR_UNKNOWN:
default:
- return _("FTP Unknown or unexpected error");
+ return _("Unknown or unexpected error");
}
}
diff --git a/ftp.h b/ftp.h
index 3a2510fbc..54eefe8cd 100644
--- a/ftp.h
+++ b/ftp.h
@@ -13,14 +13,16 @@ const char * ftpStrerror(int ftpErrno);
#define FTPERR_PASSIVE_ERROR -8
#define FTPERR_FAILED_DATA_CONNECT -9
#define FTPERR_FILE_NOT_FOUND -10
+#define FTPERR_NIC_ABORT_IN_PROGRESS -11
#define FTPERR_UNKNOWN -100
-int httpOpen(urlinfo *u);
+int httpOpen(urlinfo *u);
+int ftpOpen(urlinfo *u);
-int ftpOpen(urlinfo *u);
-int ftpGetFile(int sock, char * remotename, FD_t dest);
-int ftpGetFileDesc(int sock, char * remotename);
-int ftpGetFileDone(int sock);
-void ftpClose(int sock);
+int httpGetFile(FD_t sfd, FD_t tfd);
+int ftpGetFile(FD_t sfd, FD_t tfd);
+int ftpGetFileDesc(FD_t);
+int ftpAbort(FD_t fd);
+int ftpClose(FD_t fd);
#endif
diff --git a/install.c b/install.c
index a5f74a281..e8084acf1 100644
--- a/install.c
+++ b/install.c
@@ -4,6 +4,7 @@
#include "install.h"
#include "url.h"
+#include "ftp.h"
static int hashesPrinted = 0;
@@ -64,7 +65,7 @@ static int installPackages(char * rootdir, char ** packages,
fd = fdOpen(*filename, O_RDONLY, 0);
if (fdFileno(fd) < 0) {
- fprintf(stderr, _("error: cannot open file %s\n"), *filename);
+ rpmMessage(RPMMESS_ERROR, _("cannot open file %s\n"), *filename);
numFailed++;
*filename = NULL;
continue;
@@ -98,13 +99,13 @@ static int installPackages(char * rootdir, char ** packages,
}
if (rc == 1) {
- fprintf(stderr,
- _("error: %s does not appear to be a RPM package\n"),
+ rpmMessage(RPMMESS_ERROR,
+ _("%s does not appear to be a RPM package\n"),
*filename);
}
if (rc) {
- fprintf(stderr, _("error: %s cannot be installed\n"), *filename);
+ rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), *filename);
numFailed++;
}
@@ -128,13 +129,13 @@ int doInstall(char * rootdir, char ** argv, int installFlags,
Header * binaryHeaders;
int isSource;
int tmpnum = 0;
- const char *tmppath = rpmGetVar(RPMVAR_TMPPATH);
- int tmppathlen = strlen(tmppath);
- int rootdirlen = strlen(rootdir);
rpmDependencies rpmdep;
struct rpmDependencyConflict * conflicts;
int numConflicts;
int stopInstall = 0;
+ size_t nb;
+ const char *tmppath = rpmGetVar(RPMVAR_TMPPATH);
+ const char *myroot;
if (installFlags & RPMINSTALL_TEST)
mode = O_RDONLY;
@@ -146,53 +147,67 @@ int doInstall(char * rootdir, char ** argv, int installFlags,
;
rpmMessage(RPMMESS_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));
-
+
+ nb = (numPackages + 1) * sizeof(char *);
+ packages = alloca(nb);
+ memset(packages, 0, nb);
+ tmpPackages = alloca(nb);
+ memset(tmpPackages, 0, nb);
+ nb = (numPackages + 1) * sizeof(Header);
+ binaryHeaders = alloca(nb);
+ memset(binaryHeaders, 0, nb);
+
+ myroot = rootdir;
+ if (myroot[0] == '/' && myroot[1] == '\0' && tmppath[0] == '/')
+ myroot = "";
+
rpmMessage(RPMMESS_DEBUG, _("looking for packages to download\n"));
for (filename = argv, i = 0; *filename; filename++) {
switch (urlIsURL(*filename)) {
case URL_IS_FTP:
+ case URL_IS_HTTP:
+ case URL_IS_PATH:
{ int myrc;
+ char *tfn;
if (rpmIsVerbose()) {
fprintf(stdout, _("Retrieving %s\n"), *filename);
}
- packages[i] =
- alloca(strlen(*filename) + 30 + rootdirlen + tmppathlen);
- sprintf(packages[i], "%s%s/rpm-ftp-%d-%d.tmp", rootdir,
- tmppath, tmpnum++, (int) getpid());
- rpmMessage(RPMMESS_DEBUG,
- _("getting %s as %s\n"), *filename, packages[i]);
- myrc = urlGetFile(*filename, packages[i]);
+
+ nb = strlen(myroot) + strlen(tmppath) +
+ sizeof("/rpm-12345-12345");
+ tfn = malloc(nb);
+ sprintf(tfn, "%s%s/rpm-%.5u-%.5u", myroot,
+ tmppath, (int) getpid(), tmpnum++);
+
+ rpmMessage(RPMMESS_DEBUG, _(" ... as %s\n"), tfn);
+ myrc = urlGetFile(*filename, tfn);
if (myrc < 0) {
- fprintf(stderr,
- _("error: skipping %s - transfer failed - %s\n"),
+ rpmMessage(RPMMESS_ERROR,
+ _("skipping %s - transfer failed - %s\n"),
*filename, ftpStrerror(myrc));
numFailed++;
+ packages[i] = NULL;
+ free(tfn);
} else {
- tmpPackages[numTmpPackages++] = packages[i];
- i++;
+ tmpPackages[numTmpPackages++] = packages[i++] = tfn;
}
} break;
default:
packages[i++] = *filename;
break;
}
-
}
rpmMessage(RPMMESS_DEBUG, _("retrieved %d packages\n"), numTmpPackages);
rpmMessage(RPMMESS_DEBUG, _("finding source and binary packages\n"));
- for (filename = packages; *filename; filename++) {
+ for (filename = packages, i = 0; *filename; filename++, i++) {
fd = fdOpen(*filename, O_RDONLY, 0);
if (fdFileno(fd) < 0) {
- fprintf(stderr, _("error: cannot open file %s\n"), *filename);
+ rpmMessage(RPMMESS_ERROR, _("cannot open file %s\n"), *filename);
numFailed++;
- *filename = NULL;
+ packages[i] = NULL;
continue;
}
@@ -202,15 +217,15 @@ int doInstall(char * rootdir, char ** argv, int installFlags,
fdClose(fd);
if (rc == 1) {
- fprintf(stderr,
- _("error: %s does not appear to be a RPM package\n"),
+ rpmMessage(RPMMESS_ERROR,
+ _("%s does not appear to be a RPM package\n"),
*filename);
}
if (rc) {
- fprintf(stderr, _("error: %s cannot be installed\n"), *filename);
+ rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), *filename);
numFailed++;
- *filename = NULL;
+ packages[i] = NULL;
} else if (isSource) {
/* the header will be NULL if this is a v1 source package */
if (binaryHeaders[numBinaryPackages] != NULL)
@@ -228,7 +243,7 @@ int doInstall(char * rootdir, char ** argv, int installFlags,
if (numBinaryPackages) {
rpmMessage(RPMMESS_DEBUG, _("opening database mode: 0%o\n"), mode);
if (rpmdbOpen(rootdir, &db, mode, 0644)) {
- fprintf(stderr, _("error: cannot open %s%s/packages.rpm\n"),
+ rpmMessage(RPMMESS_ERROR, _("cannot open %s%s/packages.rpm\n"),
rootdir, rpmGetVar(RPMVAR_DBPATH));
exit(EXIT_FAILURE);
}
@@ -249,7 +264,7 @@ int doInstall(char * rootdir, char ** argv, int installFlags,
}
if (!stopInstall && conflicts) {
- fprintf(stderr, _("failed dependencies:\n"));
+ rpmMessage(RPMMESS_ERROR, _("failed dependencies:\n"));
printDepProblems(stderr, conflicts, numConflicts);
rpmdepFreeConflicts(conflicts, numConflicts);
numFailed = numPackages;
@@ -276,8 +291,10 @@ int doInstall(char * rootdir, char ** argv, int installFlags,
relocations);
}
- for (i = 0; i < numTmpPackages; i++)
+ for (i = 0; i < numTmpPackages; i++) {
unlink(tmpPackages[i]);
+ free(tmpPackages[i]);
+ }
for (i = 0; i < numBinaryPackages; i++)
headerFree(binaryHeaders[i]);
@@ -317,7 +334,7 @@ int doUninstall(char * rootdir, char ** argv, int uninstallFlags,
mode = O_RDWR | O_EXCL;
if (rpmdbOpen(rootdir, &db, mode, 0644)) {
- fprintf(stderr, _("error: cannot open %s%s/packages.rpm\n"),
+ rpmMessage(RPMMESS_ERROR, _("cannot open %s%s/packages.rpm\n"),
rootdir, rpmGetVar(RPMVAR_DBPATH));
exit(EXIT_FAILURE);
}
@@ -327,10 +344,10 @@ int doUninstall(char * rootdir, char ** argv, int uninstallFlags,
for (arg = argv; *arg; arg++) {
rc = rpmdbFindByLabel(db, *arg, &matches);
if (rc == 1) {
- fprintf(stderr, _("package %s is not installed\n"), *arg);
+ rpmMessage(RPMMESS_ERROR, _("package %s is not installed\n"), *arg);
numFailed++;
} else if (rc == 2) {
- fprintf(stderr, _("error searching for package %s\n"), *arg);
+ rpmMessage(RPMMESS_ERROR, _("searching for package %s\n"), *arg);
numFailed++;
} else {
count = 0;
@@ -338,7 +355,7 @@ int doUninstall(char * rootdir, char ** argv, int uninstallFlags,
if (dbiIndexRecordOffset(matches, i)) count++;
if (count > 1 && !(interfaceFlags & UNINSTALL_ALLMATCHES)) {
- fprintf(stderr, _("\"%s\" specifies multiple packages\n"),
+ rpmMessage(RPMMESS_ERROR, _("\"%s\" specifies multiple packages\n"),
*arg);
numFailed++;
}
@@ -376,7 +393,7 @@ int doUninstall(char * rootdir, char ** argv, int uninstallFlags,
rpmdepDone(rpmdep);
if (!stopUninstall && conflicts) {
- fprintf(stderr, _("removing these packages would break "
+ rpmMessage(RPMMESS_ERROR, _("removing these packages would break "
"dependencies:\n"));
printDepProblems(stderr, conflicts, numConflicts);
rpmdepFreeConflicts(conflicts, numConflicts);
@@ -409,7 +426,7 @@ int doSourceInstall(char * rootdir, char * arg, char ** specFile,
fd = fdOpen(arg, O_RDONLY, 0);
if (fdFileno(fd) < 0) {
- fprintf(stderr, _("error: cannot open %s\n"), arg);
+ rpmMessage(RPMMESS_ERROR, _("cannot open %s\n"), arg);
return 1;
}
@@ -418,7 +435,7 @@ int doSourceInstall(char * rootdir, char * arg, char ** specFile,
rc = rpmInstallSourcePackage(rootdir, fd, specFile, NULL, NULL, cookie);
if (rc == 1) {
- fprintf(stderr, _("error: %s cannot be installed\n"), arg);
+ rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), arg);
if (specFile) FREE(*specFile);
if (cookie) FREE(*cookie);
}
diff --git a/lib/query.c b/lib/query.c
index 10d3db31a..65e33e73b 100644
--- a/lib/query.c
+++ b/lib/query.c
@@ -454,17 +454,14 @@ int rpmQuery(char * prefix, enum rpmQuerySources source, int queryFlags,
{ FD_t fd;
fd = ufdOpen(arg, O_RDONLY, 0);
- if (fd == NULL) {
+ if (fdFileno(fd) < 0) {
fprintf(stderr, _("open of %s failed\n"), arg);
ufdClose(fd);
retcode = 1;
break;
}
- if (fdFileno(fd) >= 0) {
- rc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
- } else
- rc = 2;
+ rc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
ufdClose(fd);
@@ -576,22 +573,22 @@ int rpmQuery(char * prefix, enum rpmQuerySources source, int queryFlags,
case QUERY_PATH:
if (*arg != '/') {
- /* Using realpath on the arg isn't correct if the arg is a symlink,
- * especially if the symlink is a dangling link. What we should
- * instead do is use realpath() on `.' and then append arg to
- * it.
- */
+ /* Using realpath on the arg isn't correct if the arg is a symlink,
+ * especially if the symlink is a dangling link. What we should
+ * instead do is use realpath() on `.' and then append arg to
+ * it.
+ */
if (realpath(".", path) != NULL) {
if (path[strlen(path)] != '/') {
- if (strncat(path, "/", PATH_MAX - strlen(path) - 1) == NULL) {
+ if (strncat(path, "/", sizeof(path) - strlen(path) - 1) == NULL) {
fprintf(stderr, _("maximum path length exceeded\n"));
return 1;
- }
+ }
}
/* now append the original file name to the real path */
- if (strncat(path, arg, PATH_MAX - strlen(path) - 1) == NULL) {
- fprintf(stderr, _("maximum path length exceeded\n"));
- return 1;
+ if (strncat(path, arg, sizeof(path) - strlen(path) - 1) == NULL) {
+ fprintf(stderr, _("maximum path length exceeded\n"));
+ return 1;
}
arg = path;
}
diff --git a/lib/rpmio.h b/lib/rpmio.h
index a4ef31fdd..25804b49d 100644
--- a/lib/rpmio.h
+++ b/lib/rpmio.h
@@ -126,7 +126,6 @@ extern inline int gzdClose(/*@only@*/ FD_t fd) {
fd->fd_fd = -1;
fd->fd_bzd = NULL;
fd->fd_gzd = NULL;
- fd->fd_url = NULL;
free(fd);
zerror = gzclose(gzfile);
return 0;
@@ -199,7 +198,6 @@ extern inline int bzdClose(/*@only@*/ FD_t fd) {
fd->fd_fd = -1;
fd->fd_bzd = NULL;
fd->fd_gzd = NULL;
- fd->fd_url = NULL;
free(fd);
bzclose(bzfile);
return 0;
diff --git a/po/rpm.pot b/po/rpm.pot
index 8e16d7eda..d40233531 100644
--- a/po/rpm.pot
+++ b/po/rpm.pot
@@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 1998-12-05 18:16-0500\n"
+"POT-Creation-Date: 1998-12-14 16:12-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"
@@ -171,56 +171,64 @@ msgstr ""
msgid "OK"
msgstr ""
-#: ../ftp.c:458
-msgid "Bad FTP server response"
+#: ../ftp.c:554
+msgid "Success"
msgstr ""
-#: ../ftp.c:461
-msgid "FTP IO error"
+#: ../ftp.c:557
+msgid "Bad server response"
msgstr ""
-#: ../ftp.c:464
-msgid "FTP server timeout"
+#: ../ftp.c:560
+msgid "Server IO error"
msgstr ""
-#: ../ftp.c:467
-msgid "Unable to lookup FTP server host address"
+#: ../ftp.c:563
+msgid "Server timeout"
msgstr ""
-#: ../ftp.c:470
-msgid "Unable to lookup FTP server host name"
+#: ../ftp.c:566
+msgid "Unable to lookup server host address"
msgstr ""
-#: ../ftp.c:473
-msgid "Failed to connect to FTP server"
+#: ../ftp.c:569
+msgid "Unable to lookup server host name"
msgstr ""
-#: ../ftp.c:476
-msgid "Failed to establish data connection to FTP server"
+#: ../ftp.c:572
+msgid "Failed to connect to server"
msgstr ""
-#: ../ftp.c:479
+#: ../ftp.c:575
+msgid "Failed to establish data connection to server"
+msgstr ""
+
+#: ../ftp.c:578
msgid "IO error to local file"
msgstr ""
-#: ../ftp.c:482
+#: ../ftp.c:581
msgid "Error setting remote server to passive mode"
msgstr ""
-#: ../ftp.c:485
+#: ../ftp.c:584
msgid "File not found on server"
msgstr ""
-#: ../ftp.c:489
-msgid "FTP Unknown or unexpected error"
+#: ../ftp.c:587
+msgid "Abort in progress"
+msgstr ""
+
+#: ../ftp.c:591
+msgid "Unknown or unexpected error"
msgstr ""
-#: ../install.c:67 ../install.c:193
+#: ../install.c:67 ../install.c:207
#, c-format
-msgid "error: cannot open file %s\n"
+msgid "cannot open file %s\n"
msgstr ""
-#: ../install.c:84 ../install.c:417
+#: ../install.c:84 ../install.c:433
#, c-format
msgid "Installing %s\n"
msgstr ""
@@ -229,14 +237,14 @@ msgstr ""
msgid "stopping source install as we're just testing\n"
msgstr ""
-#: ../install.c:102 ../install.c:206
+#: ../install.c:102 ../install.c:220 ../lib/query.c:479
#, c-format
-msgid "error: %s does not appear to be a RPM package\n"
+msgid "%s does not appear to be a RPM package\n"
msgstr ""
-#: ../install.c:107 ../install.c:211 ../install.c:421
+#: ../install.c:107 ../install.c:225 ../install.c:437
#, c-format
-msgid "error: %s cannot be installed\n"
+msgid "%s cannot be installed\n"
msgstr ""
#: ../install.c:144
@@ -248,101 +256,101 @@ msgstr ""
msgid "found %d packages\n"
msgstr ""
-#: ../install.c:154
+#: ../install.c:163
msgid "looking for packages to download\n"
msgstr ""
-#: ../install.c:161
+#: ../install.c:173
#, c-format
msgid "Retrieving %s\n"
msgstr ""
-#: ../install.c:168
+#: ../install.c:182
#, c-format
-msgid "getting %s as %s\n"
+msgid " ... as %s\n"
msgstr ""
-#: ../install.c:172
+#: ../install.c:186
#, c-format
-msgid "error: skipping %s - transfer failed - %s\n"
+msgid "skipping %s - transfer failed - %s\n"
msgstr ""
-#: ../install.c:187
+#: ../install.c:201
#, c-format
msgid "retrieved %d packages\n"
msgstr ""
-#: ../install.c:189
+#: ../install.c:203
msgid "finding source and binary packages\n"
msgstr ""
-#: ../install.c:225
+#: ../install.c:239
#, c-format
msgid "found %d source and %d binary packages\n"
msgstr ""
-#: ../install.c:229
+#: ../install.c:243
#, c-format
msgid "opening database mode: 0%o\n"
msgstr ""
-#: ../install.c:231 ../install.c:320
+#: ../install.c:245 ../install.c:336
#, c-format
-msgid "error: cannot open %s%s/packages.rpm\n"
+msgid "cannot open %s%s/packages.rpm\n"
msgstr ""
-#: ../install.c:252
+#: ../install.c:266
msgid "failed dependencies:\n"
msgstr ""
-#: ../install.c:273
+#: ../install.c:287
msgid "installing binary packages\n"
msgstr ""
-#: ../install.c:307
+#: ../install.c:323
msgid "counting packages to uninstall\n"
msgstr ""
-#: ../install.c:330 ../lib/query.c:639 ../verify.c:248
+#: ../install.c:346 ../lib/query.c:636 ../verify.c:266
#, c-format
msgid "package %s is not installed\n"
msgstr ""
-#: ../install.c:333
+#: ../install.c:349
#, c-format
-msgid "error searching for package %s\n"
+msgid "searching for package %s\n"
msgstr ""
-#: ../install.c:341
+#: ../install.c:357
#, c-format
msgid "\"%s\" specifies multiple packages\n"
msgstr ""
-#: ../install.c:364
+#: ../install.c:380
#, c-format
msgid "found %d packages to uninstall\n"
msgstr ""
-#: ../install.c:379
+#: ../install.c:395
msgid "removing these packages would break dependencies:\n"
msgstr ""
-#: ../install.c:390
+#: ../install.c:406
#, c-format
msgid "uninstalling record number %d\n"
msgstr ""
-#: ../install.c:412
+#: ../install.c:428
#, c-format
-msgid "error: cannot open %s\n"
+msgid "cannot open %s\n"
msgstr ""
-#: ../install.c:460
+#: ../install.c:476
#, c-format
msgid " is needed by %s-%s-%s\n"
msgstr ""
-#: ../install.c:463
+#: ../install.c:479
#, c-format
msgid " conflicts with %s-%s-%s\n"
msgstr ""
@@ -1326,30 +1334,30 @@ msgstr ""
msgid "no arguments given for verify"
msgstr ""
-#: ../url.c:83
+#: ../url.c:104
#, c-format
msgid "Password for %s@%s: "
msgstr ""
-#: ../url.c:97 ../url.c:301
-#, c-format
-msgid "getting %s via anonymous ftp\n"
+#: ../url.c:168
+msgid "url port must be a number\n"
msgstr ""
-#: ../url.c:102
+#: ../url.c:206
#, c-format
msgid "logging into %s as %s, pw %s\n"
msgstr ""
-#: ../url.c:120
+#: ../url.c:229
msgid "error: ftpport must be a number\n"
msgstr ""
-#: ../url.c:202
-msgid "error: url port must be a number\n"
+#: ../lib/rpmdb.c:124 ../url.c:333
+#, c-format
+msgid "failed to open %s\n"
msgstr ""
-#: ../url.c:307
+#: ../url.c:348
#, c-format
msgid "failed to create %s\n"
msgstr ""
@@ -1373,7 +1381,7 @@ msgstr ""
msgid "error: could not read database record\n"
msgstr ""
-#: ../lib/query.c:528 ../verify.c:181
+#: ../lib/query.c:525 ../verify.c:181
msgid "could not read database record!\n"
msgstr ""
@@ -1387,17 +1395,21 @@ msgstr ""
msgid "%s is not an RPM\n"
msgstr ""
-#: ../lib/query.c:539 ../verify.c:223
+#: ../lib/query.c:536 ../verify.c:223
#, c-format
msgid "group %s does not contain any packages\n"
msgstr ""
-#: ../lib/query.c:608 ../verify.c:237
+#: ../lib/query.c:584 ../lib/query.c:590 ../verify.c:241 ../verify.c:247
+msgid "maximum path length exceeded\n"
+msgstr ""
+
+#: ../lib/query.c:605 ../verify.c:255
#, c-format
msgid "file %s is not owned by any package\n"
msgstr ""
-#: ../lib/query.c:642 ../verify.c:250
+#: ../lib/query.c:639 ../verify.c:268
#, c-format
msgid "error looking for package %s\n"
msgstr ""
@@ -2792,60 +2804,51 @@ msgstr ""
msgid "rpmQuery: rpmdbOpen() failed\n"
msgstr ""
-#: ../lib/query.c:474
+#: ../lib/query.c:471
msgid "old format source packages cannot be queried\n"
msgstr ""
#: ../lib/query.c:482
#, c-format
-msgid "%s does not appear to be a RPM package\n"
-msgstr ""
-
-#: ../lib/query.c:485
-#, c-format
msgid "query of %s failed\n"
msgstr ""
-#: ../lib/query.c:504
+#: ../lib/query.c:501
#, c-format
msgid "query of specfile %s failed, can't parse\n"
msgstr ""
-#: ../lib/query.c:549
+#: ../lib/query.c:546
#, c-format
msgid "no package provides %s\n"
msgstr ""
-#: ../lib/query.c:559
+#: ../lib/query.c:556
#, c-format
msgid "no package triggers %s\n"
msgstr ""
-#: ../lib/query.c:569
+#: ../lib/query.c:566
#, c-format
msgid "no package requires %s\n"
msgstr ""
-#: ../lib/query.c:587 ../lib/query.c:593
-msgid "maximum path length exceeded\n"
-msgstr ""
-
-#: ../lib/query.c:605
+#: ../lib/query.c:602
#, c-format
msgid "file %s: %s\n"
msgstr ""
-#: ../lib/query.c:621
+#: ../lib/query.c:618
#, c-format
msgid "invalid package number: %s\n"
msgstr ""
-#: ../lib/query.c:624
+#: ../lib/query.c:621
#, c-format
msgid "showing package: %d\n"
msgstr ""
-#: ../lib/query.c:627
+#: ../lib/query.c:624
#, c-format
msgid "record %d could not be read\n"
msgstr ""
@@ -2915,11 +2918,6 @@ msgstr ""
msgid "opening database in %s\n"
msgstr ""
-#: ../lib/rpmdb.c:124
-#, c-format
-msgid "failed to open %s\n"
-msgstr ""
-
#: ../lib/rpmdb.c:137 ../lib/rpmdb.c:144
#, c-format
msgid "cannot get %s lock on database"
diff --git a/popt/po/popt.pot b/popt/po/popt.pot
index 8c3b4118d..51c452b5a 100644
--- a/popt/po/popt.pot
+++ b/popt/po/popt.pot
@@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 1998-12-05 12:58-0500\n"
+"POT-Creation-Date: 1998-12-11 12:08-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"
diff --git a/url.c b/url.c
index a24585f6a..99863899c 100644
--- a/url.c
+++ b/url.c
@@ -7,12 +7,6 @@
#include "url.h"
#include "ftp.h"
-struct pwcacheEntry {
- char * machine;
- char * account;
- char * pw;
-} ;
-
static struct urlstring {
const char *leadin;
urltype ret;
@@ -24,13 +18,10 @@ static struct urlstring {
{ NULL, URL_IS_UNKNOWN }
};
-#if DYING
-static char * getFtpPassword(char * machine, char * account, int mustAsk);
-static int urlFtpLogin(const char * url, char ** fileNamePtr);
-#endif
-
void freeUrlinfo(urlinfo *u)
{
+ if (u->ftpControl >= 0)
+ close(u->ftpControl);
FREE(u->service);
FREE(u->user);
FREE(u->password);
@@ -52,97 +43,69 @@ urlinfo *newUrlinfo(void)
return u;
}
-static char * getFtpPassword(char * machine, char * account, int mustAsk)
-{
- static /*@only@*/ struct pwcacheEntry * pwCache = NULL;
- static int pwCount = 0;
- int i;
- char * prompt;
-
- for (i = 0; i < pwCount; i++) {
- if (!strcmp(pwCache[i].machine, machine) &&
- !strcmp(pwCache[i].account, account))
- break;
- }
-
- if (i < pwCount && !mustAsk) {
- return pwCache[i].pw;
- } else if (i == pwCount) {
- pwCount++;
- if (pwCache)
- pwCache = realloc(pwCache, sizeof(*pwCache) * pwCount);
- else
- pwCache = malloc(sizeof(*pwCache));
-
- pwCache[i].machine = strdup(machine);
- pwCache[i].account = strdup(account);
- } else
- free(pwCache[i].pw);
-
- prompt = alloca(strlen(machine) + strlen(account) + 50);
- sprintf(prompt, _("Password for %s@%s: "), account, machine);
-
- pwCache[i].pw = strdup(getpass(prompt));
-
- return pwCache[i].pw;
-}
-
-static int urlFtpLogin(const char * url, char ** fileNamePtr)
+static void findUrlinfo(urlinfo **uret, int mustAsk)
{
urlinfo *u;
- char *proxy;
- char *proxyport;
- int ftpconn;
-
- rpmMessage(RPMMESS_DEBUG, _("getting %s via anonymous ftp\n"), url);
+ urlinfo **empty;
+ static urlinfo **uCache = NULL;
+ static int uCount = 0;
+ int i;
- if (urlSplit(url, &u))
- return -1;
+ if (uret == NULL)
+ return;
- rpmMessage(RPMMESS_DEBUG, _("logging into %s as %s, pw %s\n"),
- u->host,
- u->user ? u->user : "ftp",
- u->password ? u->password : "(username)");
+ u = *uret;
- if ((proxy = rpmGetVar(RPMVAR_FTPPROXY)) != NULL) {
- u->user = realloc(u->user, (strlen(u->user) + strlen(u->host) + 2) );
- strcat(u->user, "@");
- strcat(u->user, u->host);
- free(u->host);
- u->host = strdup(proxy);
+ empty = NULL;
+ for (i = 0; i < uCount; i++) {
+ urlinfo *ou;
+ if ((ou = uCache[i]) == NULL) {
+ if (empty == NULL)
+ empty = &uCache[i];
+ continue;
+ }
+ if (u->service && ou->service && strcmp(ou->service, u->service))
+ continue;
+ if (u->host && ou->host && strcmp(ou->host, u->host))
+ continue;
+ if (u->user && ou->user && strcmp(ou->user, u->user))
+ continue;
+ if (u->password && ou->password && strcmp(ou->password, u->password))
+ continue;
+ if (u->portstr && ou->portstr && strcmp(ou->portstr, u->portstr))
+ continue;
+ break;
}
- if ((proxyport = rpmGetVar(RPMVAR_FTPPORT)) != NULL) {
- int port;
- char *end;
- port = strtol(proxyport, &end, 0);
- if (*end) {
- fprintf(stderr, _("error: ftpport must be a number\n"));
- return -1;
+ if (i == uCount) {
+ if (empty == NULL) {
+ uCount++;
+ if (uCache)
+ uCache = realloc(uCache, sizeof(*uCache) * uCount);
+ else
+ uCache = malloc(sizeof(*uCache));
+ empty = &uCache[i];
}
- u->port = port;
+ *empty = u;
+ } else {
+ const char *up = uCache[i]->path;
+ uCache[i]->path = u->path;
+ u->path = up;
+ freeUrlinfo(u);
}
- ftpconn = ftpOpen(u);
-
- if (fileNamePtr && ftpconn >= 0)
- *fileNamePtr = strdup(u->path);
+ *uret = u = uCache[i];
- freeUrlinfo(u);
- return ftpconn;
-}
-
-urltype urlIsURL(const char * url)
-{
- struct urlstring *us;
-
- for (us = urlstrings; us->leadin != NULL; us++) {
- if (strncmp(url, us->leadin, strlen(us->leadin)))
- continue;
- return us->ret;
+ if (!strcmp(u->service, "ftp")) {
+ if (mustAsk || (u->user != NULL && u->password == NULL)) {
+ char * prompt;
+ FREE(u->password);
+ prompt = alloca(strlen(u->host) + strlen(u->user) + 40);
+ sprintf(prompt, _("Password for %s@%s: "), u->user, u->host);
+ u->password = strdup(getpass(prompt));
+ }
}
-
- return URL_IS_UNKNOWN;
+ return;
}
int urlSplit(const char * url, urlinfo **uret)
@@ -151,6 +114,8 @@ int urlSplit(const char * url, urlinfo **uret)
char *myurl;
char *s, *se, *f, *fe;
+ if (uret == NULL)
+ return -1;
if ((u = newUrlinfo()) == NULL)
return -1;
@@ -161,6 +126,7 @@ int urlSplit(const char * url, urlinfo **uret)
do {
while (*se && *se != '/') se++;
if (*se == '\0') {
+ /* XXX can't find path */
if (myurl) free(myurl);
freeUrlinfo(u);
return -1;
@@ -199,7 +165,7 @@ int urlSplit(const char * url, urlinfo **uret)
char *end;
u->port = strtol(u->portstr, &end, 0);
if (*end) {
- fprintf(stderr, _("error: url port must be a number\n"));
+ rpmMessage(RPMMESS_ERROR, _("url port must be a number\n"));
if (myurl) free(myurl);
freeUrlinfo(u);
return -1;
@@ -216,31 +182,99 @@ int urlSplit(const char * url, urlinfo **uret)
u->port = IPPORT_FTP;
else if (!strcasecmp(u->service, "http"))
u->port = IPPORT_HTTP;
+ }
+
+ if (myurl) free(myurl);
+ if (uret) {
+ *uret = u;
+ findUrlinfo(uret, 0);
+ }
+ return 0;
+}
+
+static int urlConnect(const char * url, urlinfo ** uret)
+{
+ urlinfo *u;
+
+ if (urlSplit(url, &u) < 0)
+ return -1;
+
+ if (!strcmp(u->service, "ftp") && u->ftpControl < 0) {
+ char *proxy;
+ char *proxyport;
+
+ rpmMessage(RPMMESS_DEBUG, _("logging into %s as %s, pw %s\n"),
+ u->host,
+ u->user ? u->user : "ftp",
+ u->password ? u->password : "(username)");
- /* XXX move elsewhere */
- if (!strcmp(u->service, "ftp") && u->user && u->password == NULL) {
- u->password = getFtpPassword(u->host, u->user, 0);
- if (u->password)
- u->password = strdup(u->password);
+ /* XXX FIXME: this doesn't work with urlinfo caching */
+ if ((proxy = rpmGetVar(RPMVAR_FTPPROXY)) != NULL) {
+ char *nu = malloc(strlen(u->user) + strlen(u->host) + sizeof("@"));
+ strcpy(nu, u->user);
+ strcat(nu, "@");
+ strcat(nu, u->host);
+ free((void *)u->user);
+ u->user = nu;
+ free((void *)u->host);
+ u->host = strdup(proxy);
}
+
+ /* XXX FIXME: this doesn't work with urlinfo caching */
+ if ((proxyport = rpmGetVar(RPMVAR_FTPPORT)) != NULL) {
+ int port;
+ char *end;
+ port = strtol(proxyport, &end, 0);
+ if (*end) {
+ fprintf(stderr, _("error: ftpport must be a number\n"));
+ return -1;
+ }
+ u->port = port;
+ }
+
+ u->ftpControl = ftpOpen(u);
+
+ if (u->ftpControl < 0)
+ return u->ftpControl;
+
}
- if (myurl) free(myurl);
- if (uret)
+ if (uret != NULL)
*uret = u;
- else
- freeUrlinfo(u);
+
return 0;
}
+urltype urlIsURL(const char * url)
+{
+ struct urlstring *us;
+
+ for (us = urlstrings; us->leadin != NULL; us++) {
+ if (strncmp(url, us->leadin, strlen(us->leadin)))
+ continue;
+ return us->ret;
+ }
+
+ return URL_IS_UNKNOWN;
+}
+
+#ifdef NOTYET
+int urlAbort(FD_t fd)
+{
+ if (fd != NULL && fd->fd_url) {
+ urlinfo *u = (urlinfo *)fd->fd_url;
+ if (u->ftpControl >= 0)
+ ftpAbort(fd);
+ }
+}
+#endif
+
int ufdClose(FD_t fd)
{
if (fd != NULL && fd->fd_url) {
- int fdno = ((urlinfo *)fd->fd_url)->ftpControl;
- if (fdno >= 0)
- ftpClose(fdno);
- free(fd->fd_url);
- fd->fd_url = NULL;
+ urlinfo *u = (urlinfo *)fd->fd_url;
+ if (u->ftpControl >= 0)
+ ftpAbort(fd);
}
return fdClose(fd);
}
@@ -252,21 +286,19 @@ FD_t ufdOpen(const char *url, int flags, mode_t mode)
switch (urlIsURL(url)) {
case URL_IS_FTP:
- if ((fd = fdNew()) == NULL)
+ if (urlConnect(url, &u) < 0)
break;
- if ((u = newUrlinfo()) == NULL)
+ if ((fd = fdNew()) == NULL)
break;
- { char * fileName;
- if ((u->ftpControl = urlFtpLogin(url, &fileName)) < 0)
+ fd->fd_url = u;
+ if (ftpGetFileDesc(fd) < 0)
break;
- fd->fd_fd = ftpGetFileDesc(u->ftpControl, fileName);
- free(fileName);
- } break;
+ break;
case URL_IS_HTTP:
- if ((fd = fdNew()) == NULL)
- break;
if (urlSplit(url, &u))
break;
+ if ((fd = fdNew()) == NULL)
+ break;
fd->fd_url = u;
fd->fd_fd = httpOpen(u);
break;
@@ -274,7 +306,6 @@ FD_t ufdOpen(const char *url, int flags, mode_t mode)
if (urlSplit(url, &u))
break;
fd = fdOpen(u->path, flags, mode);
- freeUrlinfo(u);
break;
case URL_IS_DASH:
fd = fdDup(STDIN_FILENO);
@@ -292,35 +323,58 @@ FD_t ufdOpen(const char *url, int flags, mode_t mode)
return fd;
}
-int urlGetFile(char * url, char * dest) {
- char * fileName;
- int ftpconn;
+int urlGetFile(const char * url, const char * dest) {
int rc;
- FD_t fd;
+ FD_t sfd = NULL;
+ FD_t tfd = NULL;
- rpmMessage(RPMMESS_DEBUG, _("getting %s via anonymous ftp\n"), url);
+ sfd = ufdOpen(url, O_RDONLY, 0);
+ if (sfd == NULL || fdFileno(sfd) < 0) {
+ rpmMessage(RPMMESS_DEBUG, _("failed to open %s\n"), url);
+ ufdClose(sfd);
+ return FTPERR_UNKNOWN;
+ }
- if ((ftpconn = urlFtpLogin(url, &fileName)) < 0) return ftpconn;
+ if (sfd->fd_url != NULL && dest == NULL) {
+ const char *fileName = ((urlinfo *)sfd->fd_url)->path;
+ if ((dest = strrchr(fileName, '/')) != NULL)
+ dest++;
+ else
+ dest = fileName;
+ }
- fd = fdOpen(dest, O_CREAT|O_WRONLY|O_TRUNC, 0600);
- if (fdFileno(fd) < 0) {
+ tfd = fdOpen(dest, O_CREAT|O_WRONLY|O_TRUNC, 0600);
+ if (fdFileno(tfd) < 0) {
rpmMessage(RPMMESS_DEBUG, _("failed to create %s\n"), dest);
- ftpClose(ftpconn);
- free(fileName);
+ fdClose(tfd);
+ ufdClose(sfd);
return FTPERR_UNKNOWN;
}
- if ((rc = ftpGetFile(ftpconn, fileName, fd))) {
- free(fileName);
- unlink(dest);
- fdClose(fd);
- ftpClose(ftpconn);
- return rc;
- }
-
- free(fileName);
+ switch (urlIsURL(url)) {
+ case URL_IS_FTP:
+ if ((rc = ftpGetFile(sfd, tfd))) {
+ unlink(dest);
+ ufdClose(sfd);
+ }
+ /* XXX fdClose(sfd) done by copyData */
+ break;
+ case URL_IS_HTTP:
+ case URL_IS_PATH:
+ case URL_IS_DASH:
+ if ((rc = httpGetFile(sfd, tfd))) {
+ unlink(dest);
+ ufdClose(sfd);
+ }
+ /* XXX fdClose(sfd) done by copyData */
+ break;
+ case URL_IS_UNKNOWN:
+ default:
+ rc = FTPERR_UNKNOWN;
+ break;
+ }
- ftpClose(ftpconn);
+ fdClose(tfd);
return rc;
}
diff --git a/url.h b/url.h
index 532e520c2..63e07723c 100644
--- a/url.h
+++ b/url.h
@@ -5,18 +5,17 @@ typedef enum {
URL_IS_UNKNOWN = 0,
URL_IS_DASH = 1,
URL_IS_PATH = 2,
- URL_IS_FILE = 3,
- URL_IS_FTP = 4,
- URL_IS_HTTP = 5,
+ URL_IS_FTP = 3,
+ URL_IS_HTTP = 4,
} urltype;
typedef struct urlinfo {
- char *service;
- char *user;
- char *password;
- char *host;
- char *portstr;
- char *path;
+ const char *service;
+ const char *user;
+ const char *password;
+ const char *host;
+ const char *portstr;
+ const char *path;
int port;
int ftpControl;
} urlinfo;
@@ -37,7 +36,7 @@ void freeUrlinfo(urlinfo *u);
FD_t ufdOpen(const char * pathname, int flags, mode_t mode);
int ufdClose(FD_t fd);
-int urlGetFile(char * url, char * dest);
+int urlGetFile(const char * url, const char * dest);
#ifdef __cplusplus
}
diff --git a/verify.c b/verify.c
index 16c0ae9b4..732a60520 100644
--- a/verify.c
+++ b/verify.c
@@ -161,7 +161,7 @@ int doVerify(char * prefix, enum verifysources source, char ** argv,
rpmdb db;
dbiIndexSet matches;
char * arg;
- char path[255];
+ char path[PATH_MAX];
ec = 0;
if (source == VERIFY_RPM && !(verifyFlags & VERIFY_DEPS)) {
@@ -191,7 +191,7 @@ int doVerify(char * prefix, enum verifysources source, char ** argv,
rc = 0;
switch (source) {
- case VERIFY_RPM:
+ case VERIFY_RPM:
{ FD_t fd;
fd = ufdOpen(arg, O_RDONLY, 0);
@@ -217,7 +217,7 @@ int doVerify(char * prefix, enum verifysources source, char ** argv,
}
} break;
- case VERIFY_GRP:
+ case VERIFY_GRP:
if (rpmdbFindByGroup(db, arg, &matches)) {
fprintf(stderr,
_("group %s does not contain any packages\n"),
@@ -228,11 +228,29 @@ int doVerify(char * prefix, enum verifysources source, char ** argv,
}
break;
- case VERIFY_PATH:
- if (*arg != '/') {
- if (realpath(arg, path) != NULL)
- arg = path;
+ case VERIFY_PATH:
+ if (*arg != '/') {
+ /* Using realpath on the arg isn't correct if the arg is a symlink,
+ * especially if the symlink is a dangling link. What we should
+ * instead do is use realpath() on `.' and then append arg to
+ * it.
+ */
+ if (realpath(".", path) != NULL) {
+ if (path[strlen(path)] != '/') {
+ if (strncat(path, "/", sizeof(path) - strlen(path) - 1) == NULL) {
+ fprintf(stderr, _("maximum path length exceeded\n"));
+ return 1;
+ }
}
+ /* now append the original file name to the real path */
+ if (strncat(path, arg, sizeof(path) - strlen(path) - 1) == NULL) {
+ fprintf(stderr, _("maximum path length exceeded\n"));
+ return 1;
+ }
+ arg = path;
+ }
+ }
+
if (rpmdbFindByFile(db, arg, &matches)) {
fprintf(stderr, _("file %s is not owned by any package\n"),
arg);
@@ -242,7 +260,7 @@ int doVerify(char * prefix, enum verifysources source, char ** argv,
}
break;
- case VERIFY_PACKAGE:
+ case VERIFY_PACKAGE:
rc = rpmdbFindByLabel(db, arg, &matches);
if (rc == 1)
fprintf(stderr, _("package %s is not installed\n"), arg);
@@ -254,8 +272,8 @@ int doVerify(char * prefix, enum verifysources source, char ** argv,
}
break;
- case VERIFY_EVERY:
- ; /* nop */
+ case VERIFY_EVERY:
+ break;
}
if (rc)
ec = rc;