// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: ftp.cc,v 1.10 1999/05/25 05:56:24 jgg Exp $
+// $Id: ftp.cc,v 1.17 1999/12/09 03:45:56 jgg Exp $
/* ######################################################################
HTTP Aquire Method - This is the FTP aquire method for APT.
#include <arpa/inet.h>
#include <netdb.h>
+#include "rfc2553emu.h"
+#include "connect.h"
#include "ftp.h"
-
-
/*}}}*/
unsigned long TimeOut = 120;
// ---------------------------------------------------------------------
/* Connect to the server using a non-blocking connection and perform a
login. */
-string LastHost;
-in_addr LastHostA;
bool FTPConn::Open(pkgAcqMethod *Owner)
{
// Use the already open connection if possible.
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)
{
Port = Proxy.Port;
Host = Proxy.Host;
}
-
- /* 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)
- {
- 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)
- return _error->Error("Could not resolve '%s'",Host.c_str());
- LastHost = Host;
- LastHostA = *(in_addr *)(Addr->h_addr_list[0]);
- }
-
- Owner->Status("Connecting to %s (%s)",Host.c_str(),inet_ntoa(LastHostA));
-
- // Get a socket
- if ((ServerFd = socket(AF_INET,SOCK_STREAM,0)) < 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 &&
- errno != EINPROGRESS)
- return _error->Errno("socket","Could not create a socket");
- Peer = server;
-
- /* This implements a timeout for connect by opening the connection
- nonblocking */
- if (WaitFd(ServerFd,true,TimeOut) == false)
- return _error->Error("Could not connect, connection timed out");
- unsigned int Err;
- unsigned int Len = sizeof(Err);
- if (getsockopt(ServerFd,SOL_SOCKET,SO_ERROR,&Err,&Len) != 0)
- return _error->Errno("getsockopt","Failed");
- if (Err != 0)
- return _error->Error("Could not connect.");
+ // Connect to the remote server
+ if (Connect(Host,Port,"ftp",21,ServerFd,TimeOut,Owner) == false)
+ return false;
+ socklen_t Len = sizeof(Peer);
+ if (getpeername(ServerFd,(sockaddr *)&Peer,&Len) != 0)
+ return _error->Errno("getpeername","Unable to determine the peer name");
+
Owner->Status("Logging in");
return Login();
}
int Res = read(ServerFd,Buffer + Len,sizeof(Buffer) - Len);
if (Res <= 0)
{
+ _error->Errno("read","Read error");
Close();
- return _error->Errno("read","Read error");
+ return false;
}
Len += Res;
}
int Res = write(ServerFd,S + Start,Len);
if (Res <= 0)
{
+ _error->Errno("write","Write Error");
Close();
- return _error->Errno("write","Write Error");
+ return false;
}
Len -= Res;
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;
void FtpMethod::SigTerm(int)
{
if (FailFd == -1)
- exit(100);
+ _exit(100);
close(FailFd);
// Timestamp
UBuf.modtime = FailTime;
utime(FailFile.c_str(),&UBuf);
- exit(100);
+ _exit(100);
}
/*}}}*/
// FtpMethod::Configuration - Handle a configuration message /*{{{*/
// Could not connect is a transient error..
if (Server->Open(this) == false)
{
+ Server->Close();
Fail(true);
return true;
}
bool Missing;
if (Server->Get(File,Fd,Res.ResumePoint,MD5,Missing) == false)
{
+ Fd.Close();
+
+ // Timestamp
+ struct utimbuf UBuf;
+ time(&UBuf.actime);
+ UBuf.actime = FailTime;
+ UBuf.modtime = FailTime;
+ utime(FailFile.c_str(),&UBuf);
+
// If the file is missing we hard fail otherwise transient fail
if (Missing == true)
return false;