|
|
@@ -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;
|