X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/6d13bbcacffbd3b6473616ab3ffce7b9a35af34a..f93d1355dd915fd5c197293ba0e62292ec15cb2d:/methods/ftp.cc diff --git a/methods/ftp.cc b/methods/ftp.cc index ff9dac221..a7fa83233 100644 --- a/methods/ftp.cc +++ b/methods/ftp.cc @@ -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 #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;