summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--methods/ftp.cc64
-rw-r--r--methods/makefile2
-rw-r--r--methods/rfc2553emu.cc9
3 files changed, 48 insertions, 27 deletions
diff --git a/methods/ftp.cc b/methods/ftp.cc
index b567875e1..ff9dac221 100644
--- a/methods/ftp.cc
+++ b/methods/ftp.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: ftp.cc,v 1.10 1999/05/25 05:56:24 jgg Exp $
+// $Id: ftp.cc,v 1.11 1999/05/27 05:51:18 jgg Exp $
/* ######################################################################
HTTP Aquire Method - This is the FTP aquire method for APT.
@@ -35,9 +35,8 @@
#include <arpa/inet.h>
#include <netdb.h>
+#include "rfc2553emu.h"
#include "ftp.h"
-
-
/*}}}*/
unsigned long TimeOut = 120;
@@ -83,7 +82,8 @@ void FTPConn::Close()
/* Connect to the server using a non-blocking connection and perform a
login. */
string LastHost;
-in_addr LastHostA;
+int LastPort = 0;
+struct addrinfo *LastHostAddr = 0;
bool FTPConn::Open(pkgAcqMethod *Owner)
{
// Use the already open connection if possible.
@@ -111,7 +111,7 @@ bool FTPConn::Open(pkgAcqMethod *Owner)
Proxy = getenv("ftp_proxy");
// Determine what host and port to use based on the proxy settings
- int Port = 21;
+ int Port = 0;
string Host;
if (Proxy.empty() == true)
{
@@ -129,35 +129,53 @@ bool FTPConn::Open(pkgAcqMethod *Owner)
/* We used a cached address record.. Yes this is against the spec but
the way we have setup our rotating dns suggests that this is more
sensible */
- if (LastHost != Host)
+ if (LastHost != Host || LastPort != Port)
{
Owner->Status("Connecting to %s",Host.c_str());
// Lookup the host
- hostent *Addr = gethostbyname(Host.c_str());
- if (Addr == 0 || Addr->h_addr_list[0] == 0)
+ char S[30] = "ftp";
+ if (Port != 0)
+ snprintf(S,sizeof(S),"%u",Port);
+
+ // Free the old address structure
+ if (LastHostAddr != 0)
+ {
+ freeaddrinfo(LastHostAddr);
+ LastHostAddr = 0;
+ }
+
+ // We only understand SOCK_STREAM sockets.
+ struct addrinfo Hints;
+ memset(&Hints,0,sizeof(Hints));
+ Hints.ai_socktype = SOCK_STREAM;
+
+ // Resolve both the host and service simultaneously
+ if (getaddrinfo(Host.c_str(),S,&Hints,&LastHostAddr) != 0 ||
+ LastHostAddr == 0)
return _error->Error("Could not resolve '%s'",Host.c_str());
+
LastHost = Host;
- LastHostA = *(in_addr *)(Addr->h_addr_list[0]);
+ LastPort = Port;
}
-
- Owner->Status("Connecting to %s (%s)",Host.c_str(),inet_ntoa(LastHostA));
+
+ // Get the printable IP address
+ char Name[NI_MAXHOST];
+ Name[0] = 0;
+ getnameinfo(LastHostAddr->ai_addr,LastHostAddr->ai_addrlen,
+ Name,sizeof(Name),0,0,NI_NUMERICHOST);
+ Owner->Status("Connecting to %s (%s)",Host.c_str(),Name);
// Get a socket
- if ((ServerFd = socket(AF_INET,SOCK_STREAM,0)) < 0)
+ if ((ServerFd = socket(LastHostAddr->ai_family,LastHostAddr->ai_socktype,
+ LastHostAddr->ai_protocol)) < 0)
return _error->Errno("socket","Could not create a socket");
-
- // Connect to the server
- struct sockaddr_in server;
- server.sin_family = AF_INET;
- server.sin_port = htons(Port);
- server.sin_addr = LastHostA;
SetNonBlock(ServerFd,true);
- if (connect(ServerFd,(sockaddr *)&server,sizeof(server)) < 0 &&
+ if (connect(ServerFd,LastHostAddr->ai_addr,LastHostAddr->ai_addrlen) < 0 &&
errno != EINPROGRESS)
- return _error->Errno("socket","Could not create a socket");
- Peer = server;
-
+ return _error->Errno("connect","Connect initiate the connection");
+ Peer = *((struct sockaddr_in *)LastHostAddr->ai_addr);
+
/* This implements a timeout for connect by opening the connection
nonblocking */
if (WaitFd(ServerFd,true,TimeOut) == false)
@@ -582,7 +600,7 @@ bool FTPConn::CreateDataFd()
return _error->Errno("socket","Could not create a socket");
/* This implements a timeout for connect by opening the connection
- nonblocking */
+ nonblocking */
if (WaitFd(ServerFd,true,TimeOut) == false)
return _error->Error("Could not connect data socket, connection timed out");
unsigned int Err;
diff --git a/methods/makefile b/methods/makefile
index 2cfc15cae..4345307e2 100644
--- a/methods/makefile
+++ b/methods/makefile
@@ -45,5 +45,5 @@ include $(PROGRAM_H)
PROGRAM=ftp
SLIBS = -lapt-pkg
LIB_MAKES = apt-pkg/makefile
-SOURCE = ftp.cc
+SOURCE = ftp.cc rfc2553emu.cc
include $(PROGRAM_H)
diff --git a/methods/rfc2553emu.cc b/methods/rfc2553emu.cc
index 1b0628f98..bd8d2236f 100644
--- a/methods/rfc2553emu.cc
+++ b/methods/rfc2553emu.cc
@@ -1,14 +1,17 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: rfc2553emu.cc,v 1.2 1999/05/26 04:08:39 jgg Exp $
+// $Id: rfc2553emu.cc,v 1.3 1999/05/27 05:51:18 jgg Exp $
/* ######################################################################
RFC 2553 Emulation - Provides emulation for RFC 2553 getaddrinfo,
freeaddrinfo and getnameinfo
+
+ This is really C code, it just has a .cc extensions to play nicer with
+ the rest of APT.
Originally written by Jason Gunthorpe <jgg@debian.org> and placed into
the Public Domain, do with it what you will.
-
+
##################################################################### */
/*}}}*/
#include "rfc2553emu.h"
@@ -156,7 +159,7 @@ int getnameinfo(const struct sockaddr *sa, socklen_t salen,
{
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
- // This routine only support internet addresses
+ // This routine only supports internet addresses
if (sa->sa_family != AF_INET)
return EAI_ADDRFAMILY;