]> git.saurik.com Git - apt.git/blobdiff - methods/ftp.cc
Reorderd error handling
[apt.git] / methods / ftp.cc
index ff9dac2212d9d3a5f46c9c20c8827e09706c388a..a7fa8323303bb924608b8f29fe7ff4bff610877c 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: ftp.cc,v 1.11 1999/05/27 05:51:18 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.
@@ -36,6 +36,7 @@
 #include <netdb.h>
 
 #include "rfc2553emu.h"
+#include "connect.h"
 #include "ftp.h"
                                                                        /*}}}*/
 
@@ -81,9 +82,6 @@ void FTPConn::Close()
 // ---------------------------------------------------------------------
 /* Connect to the server using a non-blocking connection and perform a 
    login. */
-string LastHost;
-int LastPort = 0;
-struct addrinfo *LastHostAddr = 0;
 bool FTPConn::Open(pkgAcqMethod *Owner)
 {
    // Use the already open connection if possible.
@@ -125,68 +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 || LastPort != Port)
-   {
-      Owner->Status("Connecting to %s",Host.c_str());
-
-      // Lookup the host
-      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;
-      LastPort = Port;
-   }
 
-   // 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);
+   // 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");
    
-   // Get a socket
-   if ((ServerFd = socket(LastHostAddr->ai_family,LastHostAddr->ai_socktype,
-                         LastHostAddr->ai_protocol)) < 0)
-      return _error->Errno("socket","Could not create a socket");
-   SetNonBlock(ServerFd,true);
-   if (connect(ServerFd,LastHostAddr->ai_addr,LastHostAddr->ai_addrlen) < 0 &&
-       errno != EINPROGRESS)
-      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)
-      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.");
-
    Owner->Status("Logging in");
    return Login();
 }
@@ -341,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;
    }
@@ -448,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;
@@ -801,7 +747,7 @@ FtpMethod::FtpMethod() : pkgAcqMethod("1.0",SendConfig)
 void FtpMethod::SigTerm(int)
 {
    if (FailFd == -1)
-      exit(100);
+      _exit(100);
    close(FailFd);
    
    // Timestamp
@@ -810,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           /*{{{*/
@@ -846,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;
    }
@@ -903,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;