]> git.saurik.com Git - apt.git/blobdiff - methods/ftp.cc
Reorderd error handling
[apt.git] / methods / ftp.cc
index b567875e1780470cbd9406b467e104974821e3d4..a7fa8323303bb924608b8f29fe7ff4bff610877c 100644 (file)
@@ -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.17 1999/12/09 03:45:56 jgg Exp $
 /* ######################################################################
 
    HTTP Aquire Method - This is the FTP aquire method for APT.
@@ -35,9 +35,9 @@
 #include <arpa/inet.h>
 #include <netdb.h>
 
+#include "rfc2553emu.h"
+#include "connect.h"
 #include "ftp.h"
-
-
                                                                        /*}}}*/
 
 unsigned long TimeOut = 120;
@@ -82,8 +82,6 @@ void FTPConn::Close()
 // ---------------------------------------------------------------------
 /* 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.
@@ -111,7 +109,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)
    {
@@ -125,50 +123,14 @@ bool FTPConn::Open(pkgAcqMethod *Owner)
         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();
 }
@@ -323,8 +285,9 @@ bool FTPConn::ReadLine(string &Text)
       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;
    }
@@ -430,8 +393,9 @@ bool FTPConn::WriteMsg(unsigned int &Ret,string &Text,const char *Fmt,...)
       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;
@@ -582,7 +546,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;
@@ -783,7 +747,7 @@ FtpMethod::FtpMethod() : pkgAcqMethod("1.0",SendConfig)
 void FtpMethod::SigTerm(int)
 {
    if (FailFd == -1)
-      exit(100);
+      _exit(100);
    close(FailFd);
    
    // Timestamp
@@ -792,7 +756,7 @@ void FtpMethod::SigTerm(int)
    UBuf.modtime = FailTime;
    utime(FailFile.c_str(),&UBuf);
    
-   exit(100);
+   _exit(100);
 }
                                                                        /*}}}*/
 // FtpMethod::Configuration - Handle a configuration message           /*{{{*/
@@ -828,6 +792,7 @@ bool FtpMethod::Fetch(FetchItem *Itm)
    // Could not connect is a transient error..
    if (Server->Open(this) == false)
    {
+      Server->Close();
       Fail(true);
       return true;
    }
@@ -885,6 +850,15 @@ bool FtpMethod::Fetch(FetchItem *Itm)
       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;