X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/076cc664137ec4b8983a1d9fe69eaaec6a9d4788..0a64ecd792b4caca519d597a69b8baeda6a1bf77:/methods/ftp.cc diff --git a/methods/ftp.cc b/methods/ftp.cc index bbc4a3f22..eb7fedd85 100644 --- a/methods/ftp.cc +++ b/methods/ftp.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: ftp.cc,v 1.28 2001/05/22 04:02:00 jgg Exp $ +// $Id: ftp.cc,v 1.31.2.1 2004/01/16 18:58:50 mdz Exp $ /* ###################################################################### FTP Aquire Method - This is the FTP aquire method for APT. @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include // Internet stuff #include @@ -67,7 +69,8 @@ time_t FtpMethod::FailTime = 0; // --------------------------------------------------------------------- /* */ FTPConn::FTPConn(URI Srv) : Len(0), ServerFd(-1), DataFd(-1), - DataListenFd(-1), ServerName(Srv) + DataListenFd(-1), ServerName(Srv), + ForceExtended(false), TryPassive(true) { Debug = _config->FindB("Debug::Acquire::Ftp",false); PasvAddr = 0; @@ -111,23 +114,28 @@ bool FTPConn::Open(pkgAcqMethod *Owner) Close(); // Determine the proxy setting - if (getenv("ftp_proxy") == 0) + string SpecificProxy = _config->Find("Acquire::ftp::Proxy::" + ServerName.Host); + if (!SpecificProxy.empty()) { - string DefProxy = _config->Find("Acquire::ftp::Proxy"); - string SpecificProxy = _config->Find("Acquire::ftp::Proxy::" + ServerName.Host); - if (SpecificProxy.empty() == false) - { - if (SpecificProxy == "DIRECT") - Proxy = ""; - else - Proxy = SpecificProxy; - } - else - Proxy = DefProxy; + if (SpecificProxy == "DIRECT") + Proxy = ""; + else + Proxy = SpecificProxy; } else - Proxy = getenv("ftp_proxy"); - + { + string DefProxy = _config->Find("Acquire::ftp::Proxy"); + if (!DefProxy.empty()) + { + Proxy = DefProxy; + } + else + { + char* result = getenv("ftp_proxy"); + Proxy = result ? result : ""; + } + } + // Parse no_proxy, a , separated list of domains if (getenv("no_proxy") != 0) { @@ -158,18 +166,18 @@ bool FTPConn::Open(pkgAcqMethod *Owner) return false; // Login must be before getpeername otherwise dante won't work. - Owner->Status("Logging in"); + Owner->Status(_("Logging in")); bool Res = Login(); // Get the remote server's address PeerAddrLen = sizeof(PeerAddr); if (getpeername(ServerFd,(sockaddr *)&PeerAddr,&PeerAddrLen) != 0) - return _error->Errno("getpeername","Unable to determine the peer name"); + return _error->Errno("getpeername",_("Unable to determine the peer name")); // Get the local machine's address ServerAddrLen = sizeof(ServerAddr); if (getsockname(ServerFd,(sockaddr *)&ServerAddr,&ServerAddrLen) != 0) - return _error->Errno("getsockname","Unable to determine the local name"); + return _error->Errno("getsockname",_("Unable to determine the local name")); return Res; } @@ -200,19 +208,21 @@ bool FTPConn::Login() if (ReadResp(Tag,Msg) == false) return false; if (Tag >= 400) - return _error->Error("Server refused our connection and said: %s",Msg.c_str()); + return _error->Error(_("The server refused the connection and said: %s"),Msg.c_str()); // Send the user if (WriteMsg(Tag,Msg,"USER %s",User.c_str()) == false) return false; if (Tag >= 400) - return _error->Error("USER failed, server said: %s",Msg.c_str()); + return _error->Error(_("USER failed, server said: %s"),Msg.c_str()); - // Send the Password - if (WriteMsg(Tag,Msg,"PASS %s",Pass.c_str()) == false) - return false; - if (Tag >= 400) - return _error->Error("PASS failed, server said: %s",Msg.c_str()); + if (Tag == 331) { // 331 User name okay, need password. + // Send the Password + if (WriteMsg(Tag,Msg,"PASS %s",Pass.c_str()) == false) + return false; + if (Tag >= 400) + return _error->Error(_("PASS failed, server said: %s"),Msg.c_str()); + } // Enter passive mode if (_config->Exists("Acquire::FTP::Passive::" + ServerName.Host) == true) @@ -226,13 +236,13 @@ bool FTPConn::Login() if (ReadResp(Tag,Msg) == false) return false; if (Tag >= 400) - return _error->Error("Server refused our connection and said: %s",Msg.c_str()); + return _error->Error(_("The server refused the connection and said: %s"),Msg.c_str()); // Perform proxy script execution Configuration::Item const *Opts = _config->Tree("Acquire::ftp::ProxyLogin"); if (Opts == 0 || Opts->Child == 0) - return _error->Error("A proxy server was specified but no login " - "script, Acquire::ftp::ProxyLogin is empty."); + return _error->Error(_("A proxy server was specified but no login " + "script, Acquire::ftp::ProxyLogin is empty.")); Opts = Opts->Child; // Iterate over the entire login script @@ -259,7 +269,7 @@ bool FTPConn::Login() if (WriteMsg(Tag,Msg,"%s",Tmp.c_str()) == false) return false; if (Tag >= 400) - return _error->Error("Login script command '%s' failed, server said: %s",Tmp.c_str(),Msg.c_str()); + return _error->Error(_("Login script command '%s' failed, server said: %s"),Tmp.c_str(),Msg.c_str()); } // Enter passive mode @@ -285,7 +295,7 @@ bool FTPConn::Login() if (WriteMsg(Tag,Msg,"TYPE I") == false) return false; if (Tag >= 400) - return _error->Error("TYPE failed, server said: %s",Msg.c_str()); + return _error->Error(_("TYPE failed, server said: %s"),Msg.c_str()); return true; } @@ -323,23 +333,23 @@ bool FTPConn::ReadLine(string &Text) if (WaitFd(ServerFd,false,TimeOut) == false) { Close(); - return _error->Error("Connection timeout"); + return _error->Error(_("Connection timeout")); } // Suck it back int Res = read(ServerFd,Buffer + Len,sizeof(Buffer) - Len); if (Res == 0) - _error->Error("Server closed the connection"); + _error->Error(_("Server closed the connection")); if (Res <= 0) { - _error->Errno("read","Read error"); + _error->Errno("read",_("Read error")); Close(); return false; } Len += Res; } - return _error->Error("A response overflowed the buffer."); + return _error->Error(_("A response overflowed the buffer.")); } /*}}}*/ // FTPConn::ReadResp - Read a full response from the server /*{{{*/ @@ -356,7 +366,7 @@ bool FTPConn::ReadResp(unsigned int &Ret,string &Text) char *End; Ret = strtol(Msg.c_str(),&End,10); if (End - Msg.c_str() != 3) - return _error->Error("Protocol corruption"); + return _error->Error(_("Protocol corruption")); // All done ? Text = Msg.c_str()+4; @@ -368,7 +378,7 @@ bool FTPConn::ReadResp(unsigned int &Ret,string &Text) } if (*End != '-') - return _error->Error("Protocol corruption"); + return _error->Error(_("Protocol corruption")); /* Okay, here we do the continued message trick. This is foolish, but proftpd follows the protocol as specified and wu-ftpd doesn't, so @@ -434,13 +444,13 @@ bool FTPConn::WriteMsg(unsigned int &Ret,string &Text,const char *Fmt,...) if (WaitFd(ServerFd,true,TimeOut) == false) { Close(); - return _error->Error("Connection timeout"); + return _error->Error(_("Connection timeout")); } int Res = write(ServerFd,S + Start,Len); if (Res <= 0) { - _error->Errno("write","Write Error"); + _error->Errno("write",_("Write error")); Close(); return false; } @@ -550,7 +560,7 @@ bool FTPConn::ExtGoPasv() string::const_iterator List[4]; unsigned Count = 0; Pos++; - for (string::const_iterator I = Msg.begin() + Pos; I < Msg.end(); I++) + for (string::const_iterator I = Msg.begin() + Pos; I < Msg.end(); ++I) { if (*I != Msg[Pos]) continue; @@ -652,8 +662,7 @@ bool FTPConn::ModTime(const char *Path, time_t &Time) return true; // Parse it - StrToTime(Msg,Time); - return true; + return FTPMDTMStrToTime(Msg.c_str(), Time); } /*}}}*/ // FTPConn::CreateDataFd - Get a data connection /*{{{*/ @@ -681,24 +690,24 @@ bool FTPConn::CreateDataFd() // Get a socket if ((DataFd = socket(PasvAddr->ai_family,PasvAddr->ai_socktype, PasvAddr->ai_protocol)) < 0) - return _error->Errno("socket","Could not create a socket"); + return _error->Errno("socket",_("Could not create a socket")); // Connect to the server SetNonBlock(DataFd,true); if (connect(DataFd,PasvAddr->ai_addr,PasvAddr->ai_addrlen) < 0 && errno != EINPROGRESS) - return _error->Errno("socket","Could not create a socket"); + return _error->Errno("socket",_("Could not create a socket")); /* This implements a timeout for connect by opening the connection nonblocking */ if (WaitFd(DataFd,true,TimeOut) == false) - return _error->Error("Could not connect data socket, connection timed out"); + return _error->Error(_("Could not connect data socket, connection timed out")); unsigned int Err; unsigned int Len = sizeof(Err); if (getsockopt(DataFd,SOL_SOCKET,SO_ERROR,&Err,&Len) != 0) - return _error->Errno("getsockopt","Failed"); + return _error->Errno("getsockopt",_("Failed")); if (Err != 0) - return _error->Error("Could not connect passive socket."); + return _error->Error(_("Could not connect passive socket.")); return true; } @@ -716,32 +725,33 @@ bool FTPConn::CreateDataFd() Hints.ai_family = ((struct sockaddr *)&ServerAddr)->sa_family; int Res; if ((Res = getaddrinfo(0,"0",&Hints,&BindAddr)) != 0) - return _error->Error("getaddrinfo was unable to get a listening socket"); + return _error->Error(_("getaddrinfo was unable to get a listening socket")); // Construct the socket if ((DataListenFd = socket(BindAddr->ai_family,BindAddr->ai_socktype, BindAddr->ai_protocol)) < 0) { freeaddrinfo(BindAddr); - return _error->Errno("socket","Could not create a socket"); + return _error->Errno("socket",_("Could not create a socket")); } // Bind and listen if (bind(DataListenFd,BindAddr->ai_addr,BindAddr->ai_addrlen) < 0) { freeaddrinfo(BindAddr); - return _error->Errno("bind","Could not bind a socket"); + return _error->Errno("bind",_("Could not bind a socket")); } freeaddrinfo(BindAddr); if (listen(DataListenFd,1) < 0) - return _error->Errno("listen","Could not listen on the socket"); + return _error->Errno("listen",_("Could not listen on the socket")); SetNonBlock(DataListenFd,true); // Determine the name to send to the remote struct sockaddr_storage Addr; socklen_t AddrLen = sizeof(Addr); if (getsockname(DataListenFd,(sockaddr *)&Addr,&AddrLen) < 0) - return _error->Errno("getsockname","Could not determine the socket's name"); + return _error->Errno("getsockname",_("Could not determine the socket's name")); + // Reverse the address. We need the server address and the data port. char Name[NI_MAXHOST]; @@ -772,7 +782,7 @@ bool FTPConn::CreateDataFd() (int)(Port >> 8) & 0xff, (int)(Port & 0xff)) == false) return false; if (Tag >= 400) - return _error->Error("Unable to send PORT command"); + return _error->Error(_("Unable to send PORT command")); return true; } @@ -782,7 +792,7 @@ bool FTPConn::CreateDataFd() if (AFMap[J].Family == ((struct sockaddr *)&Addr)->sa_family) Proto = AFMap[J].IETFFamily; if (Proto == 0) - return _error->Error("Unkonwn address family %u (AF_*)", + return _error->Error(_("Unknown address family %u (AF_*)"), ((struct sockaddr *)&Addr)->sa_family); // Send the EPRT command @@ -791,7 +801,7 @@ bool FTPConn::CreateDataFd() if (WriteMsg(Tag,Msg,"EPRT |%u|%s|%s|",Proto,Name,Service) == false) return false; if (Tag >= 400) - return _error->Error("EPRT failed, server said: %s",Msg.c_str()); + return _error->Error(_("EPRT failed, server said: %s"),Msg.c_str()); return true; } /*}}}*/ @@ -811,14 +821,14 @@ bool FTPConn::Finalize() // Wait for someone to connect.. if (WaitFd(DataListenFd,false,TimeOut) == false) - return _error->Error("Data socket connect timed out"); + return _error->Error(_("Data socket connect timed out")); // Accept the connection struct sockaddr_in Addr; socklen_t Len = sizeof(Addr); DataFd = accept(DataListenFd,(struct sockaddr *)&Addr,&Len); if (DataFd < 0) - return _error->Errno("accept","Unable to accept connection"); + return _error->Errno("accept",_("Unable to accept connection")); close(DataListenFd); DataListenFd = -1; @@ -857,7 +867,7 @@ bool FTPConn::Get(const char *Path,FileFd &To,unsigned long Resume, { if (Hash.AddFD(To.Fd(),Resume) == false) { - _error->Errno("read","Problem hashing file"); + _error->Errno("read",_("Problem hashing file")); return false; } } @@ -870,7 +880,7 @@ bool FTPConn::Get(const char *Path,FileFd &To,unsigned long Resume, { if (Tag == 550) Missing = true; - return _error->Error("Unable to fetch file, server said '%s'",Msg.c_str()); + return _error->Error(_("Unable to fetch file, server said '%s'"),Msg.c_str()); } // Finish off the data connection @@ -885,7 +895,7 @@ bool FTPConn::Get(const char *Path,FileFd &To,unsigned long Resume, if (WaitFd(DataFd,false,TimeOut) == false) { Close(); - return _error->Error("Data socket timed out"); + return _error->Error(_("Data socket timed out")); } // Read the data.. @@ -915,7 +925,7 @@ bool FTPConn::Get(const char *Path,FileFd &To,unsigned long Resume, if (ReadResp(Tag,Msg) == false) return false; if (Tag >= 400) - return _error->Error("Data transfer failed, server said '%s'",Msg.c_str()); + return _error->Error(_("Data transfer failed, server said '%s'"),Msg.c_str()); return true; } /*}}}*/ @@ -973,7 +983,9 @@ bool FtpMethod::Fetch(FetchItem *Itm) FetchResult Res; Res.Filename = Itm->DestFile; Res.IMSHit = false; - + + maybe_add_auth (Get, _config->FindFile("Dir::Etc::netrc")); + // Connect to the server if (Server == 0 || Server->Comp(Get) == false) { @@ -990,7 +1002,7 @@ bool FtpMethod::Fetch(FetchItem *Itm) } // Get the files information - Status("Query"); + Status(_("Query")); unsigned long Size; if (Server->Size(File,Size) == false || Server->ModTime(File,FailTime) == false) @@ -1051,9 +1063,12 @@ bool FtpMethod::Fetch(FetchItem *Itm) UBuf.modtime = FailTime; utime(FailFile.c_str(),&UBuf); - // If the file is missing we hard fail otherwise transient fail - if (Missing == true) + // If the file is missing we hard fail and delete the destfile + // otherwise transient fail + if (Missing == true) { + unlink(FailFile.c_str()); return false; + } Fail(true); return true; } @@ -1079,6 +1094,8 @@ bool FtpMethod::Fetch(FetchItem *Itm) int main(int argc,const char *argv[]) { + setlocale(LC_ALL, ""); + /* See if we should be come the http client - we do this for http proxy urls */ if (getenv("ftp_proxy") != 0) @@ -1092,12 +1109,12 @@ int main(int argc,const char *argv[]) char S[300]; snprintf(S,sizeof(S),"http_proxy=%s",getenv("ftp_proxy")); putenv(S); - putenv("no_proxy="); + putenv((char *)"no_proxy="); // Run the http method - string Path = flNotFile(argv[0]) + "/http"; - execl(Path.c_str(),Path.c_str(),0); - cerr << "Unable to invoke " << Path << endl; + string Path = flNotFile(argv[0]) + "http"; + execl(Path.c_str(),Path.c_str(),(char *)NULL); + cerr << _("Unable to invoke ") << Path << endl; exit(100); } }