]> git.saurik.com Git - apt.git/commitdiff
Wow it works
authorArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:53:02 +0000 (16:53 +0000)
committerArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:53:02 +0000 (16:53 +0000)
Author: jgg
Date: 1999-03-15 07:20:41 GMT
Wow it works

methods/ftp.cc
methods/ftp.h
methods/http.cc

index 1068a8fdef2edc6b73b8ce07047649e78e3b6aa1..b14e7dc4620e52e5175600a14210b33940a24239 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: ftp.cc,v 1.1 1999/03/15 06:00:59 jgg Exp $
+// $Id: ftp.cc,v 1.2 1999/03/15 07:20:41 jgg Exp $
 /* ######################################################################
 
    HTTP Aquire Method - This is the FTP aquire method for APT.
@@ -17,7 +17,6 @@
 #include <apt-pkg/acquire-method.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/md5.h>
-#include "ftp.h"
 
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 
+#include "ftp.h"
+
+
                                                                        /*}}}*/
 
 unsigned long TimeOut = 120;
 URI Proxy;
-bool Debug;
+string FtpMethod::FailFile;
+int FtpMethod::FailFd = -1;
+time_t FtpMethod::FailTime = 0;
 
 // FTPConn::FTPConn - Constructor                                      /*{{{*/
 // ---------------------------------------------------------------------
@@ -46,7 +50,7 @@ bool Debug;
 FTPConn::FTPConn(URI Srv) : Len(0), ServerFd(-1), DataFd(-1), 
                             DataListenFd(-1), ServerName(Srv)
 {
-   Debug = true;
+   Debug = _config->FindB("Debug::Acquire::Ftp",false);
    memset(&PasvAddr,0,sizeof(PasvAddr));
 }
                                                                        /*}}}*/
@@ -78,7 +82,7 @@ void FTPConn::Close()
    login. */
 string LastHost;
 in_addr LastHostA;
-bool FTPConn::Open()
+bool FTPConn::Open(pkgAcqMethod *Owner)
 {
    // Use the already open connection if possible.
    if (ServerFd != -1)
@@ -111,8 +115,6 @@ bool FTPConn::Open()
    {
       if (ServerName.Port != 0)
         Port = ServerName.Port;
-      else
-        ServerName.Port = Port;
       Host = ServerName.Host;
    }
    else
@@ -127,7 +129,7 @@ bool FTPConn::Open()
       sensible */
    if (LastHost != Host)
    {
-//      Owner->Status("Connecting to %s",Host.c_str());
+      Owner->Status("Connecting to %s",Host.c_str());
 
       // Lookup the host
       hostent *Addr = gethostbyname(Host.c_str());
@@ -137,7 +139,7 @@ bool FTPConn::Open()
       LastHostA = *(in_addr *)(Addr->h_addr_list[0]);
    }
    
-//   Owner->Status("Connecting to %s (%s)",Host.c_str(),inet_ntoa(LastHostA));
+   Owner->Status("Connecting to %s (%s)",Host.c_str(),inet_ntoa(LastHostA));
    
    // Get a socket
    if ((ServerFd = socket(AF_INET,SOCK_STREAM,0)) < 0)
@@ -165,6 +167,7 @@ bool FTPConn::Open()
    if (Err != 0)
       return _error->Error("Could not connect.");
 
+   Owner->Status("Logging in");
    return Login();
 }
                                                                        /*}}}*/
@@ -244,7 +247,10 @@ bool FTPConn::Login()
         
         // Substitute the variables into the command
         char SitePort[20];
-        sprintf(SitePort,"%u",ServerName.Port);
+        if (ServerName.Port != 0)
+           sprintf(SitePort,"%u",ServerName.Port);
+        else
+           strcat("21",SitePort);
         string Tmp = Opts->Value;
         Tmp = SubstVar(Tmp,"$(PROXY_USER)",Proxy.User);
         Tmp = SubstVar(Tmp,"$(PROXY_PASS)",Proxy.Password);
@@ -315,12 +321,18 @@ bool FTPConn::ReadLine(string &Text)
 
       // Wait for some data..
       if (WaitFd(ServerFd,false,TimeOut) == false)
+      {
+        Close();
         return _error->Error("Connection timeout");
+      }
       
       // Suck it back
       int Res = read(ServerFd,Buffer,sizeof(Buffer) - Len);
       if (Res <= 0)
+      {
+        Close();
         return _error->Errno("read","Read error");
+      }      
       Len += Res;
    }
 
@@ -348,7 +360,7 @@ bool FTPConn::ReadResp(unsigned int &Ret,string &Text)
    if (*End == ' ')
    {
       if (Debug == true)
-        cout << "<- '" << QuoteString(Text,"") << "'" << endl;
+        cerr << "<- '" << QuoteString(Text,"") << "'" << endl;
       return true;
    }
    
@@ -390,7 +402,7 @@ bool FTPConn::ReadResp(unsigned int &Ret,string &Text)
    }      
 
    if (Debug == true && _error->PendingError() == false)
-      cout << "<- '" << QuoteString(Text,"") << "'" << endl;
+      cerr << "<- '" << QuoteString(Text,"") << "'" << endl;
       
    return !_error->PendingError();
 }
@@ -409,7 +421,7 @@ bool FTPConn::WriteMsg(unsigned int &Ret,string &Text,const char *Fmt,...)
    strcat(S,"\r\n");
  
    if (Debug == true)
-      cout << "-> '" << QuoteString(S,"") << "'" << endl;
+      cerr << "-> '" << QuoteString(S,"") << "'" << endl;
 
    // Send it off
    unsigned long Len = strlen(S);
@@ -417,11 +429,18 @@ bool FTPConn::WriteMsg(unsigned int &Ret,string &Text,const char *Fmt,...)
    while (Len != 0)
    {
       if (WaitFd(ServerFd,true,TimeOut) == false)
+      {
+        Close();
         return _error->Error("Connection timeout");
+      }
       
       int Res = write(ServerFd,S + Start,Len);
       if (Res <= 0)
+      {
+        Close();
         return _error->Errno("write","Write Error");
+      }
+      
       Len -= Res;
       Start += Res;
    }
@@ -488,19 +507,20 @@ bool FTPConn::GoPasv()
 // FTPConn::Size - Return the size of a file                           /*{{{*/
 // ---------------------------------------------------------------------
 /* Grab the file size from the server, 0 means no size or empty file */
-unsigned long FTPConn::Size(const char *Path)
+bool FTPConn::Size(const char *Path,unsigned long &Size)
 {
    // Query the size
    unsigned int Tag;
    string Msg;
+   Size = 0;
    if (WriteMsg(Tag,Msg,"SIZE %s",Path) == false)
       return false;
    
    char *End;
-   unsigned long Size = strtol(Msg.c_str(),&End,10);
+   Size = strtol(Msg.c_str(),&End,10);
    if (Tag >= 400 || End == Msg.c_str())
-      return 0;
-   return Size;
+      Size = 0;
+   return true;
 }
                                                                        /*}}}*/
 // FTPConn::ModTime - Return the modification time of the file         /*{{{*/
@@ -659,13 +679,15 @@ bool FTPConn::Finalize()
 // ---------------------------------------------------------------------
 /* This opens a data connection, sends REST and RETR and then
    transfers the file over. */
-bool FTPConn::Get(const char *Path,FileFd &To,unsigned long Resume)
+bool FTPConn::Get(const char *Path,FileFd &To,unsigned long Resume,
+                 MD5Summation &MD5,bool &Missing)
 {
+   Missing = false;
    if (CreateDataFd() == false)
       return false;
 
    unsigned int Tag;
-   string Msg;
+   string Msg;   
    if (Resume != 0)
    {      
       if (WriteMsg(Tag,Msg,"REST %u",Resume) == false)
@@ -682,7 +704,11 @@ bool FTPConn::Get(const char *Path,FileFd &To,unsigned long Resume)
       return false;
    
    if (Tag >= 400)
+   {
+      if (Tag == 550)
+        Missing = true;
       return _error->Error("Unable to fetch file, server said '%s'",Msg.c_str());
+   }
    
    // Finish off the data connection
    if (Finalize() == false)
@@ -724,37 +750,156 @@ bool FTPConn::Get(const char *Path,FileFd &To,unsigned long Resume)
 }
                                                                        /*}}}*/
 
-int main()
+// FtpMethod::FtpMethod - Constructor                                  /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+FtpMethod::FtpMethod() : pkgAcqMethod("1.0",SendConfig)
 {
-   FTPConn Con(URI("ftp://va.debian.org/debian/README"));
-   string Msg;
-   _config->Set("Acquire::FTP::Passive","false");
+   signal(SIGTERM,SigTerm);
+   signal(SIGINT,SigTerm);
    
-   while (1)
+   Server = 0;
+   FailFd = -1;
+}
+                                                                       /*}}}*/
+// FtpMethod::SigTerm - Handle a fatal signal                          /*{{{*/
+// ---------------------------------------------------------------------
+/* This closes and timestamps the open file. This is neccessary to get 
+   resume behavoir on user abort */
+void FtpMethod::SigTerm(int)
+{
+   if (FailFd == -1)
+      exit(100);
+   close(FailFd);
+   
+   // Timestamp
+   struct utimbuf UBuf;
+   UBuf.actime = FailTime;
+   UBuf.modtime = FailTime;
+   utime(FailFile.c_str(),&UBuf);
+   
+   exit(100);
+}
+                                                                       /*}}}*/
+// FtpMethod::Configuration - Handle a configuration message           /*{{{*/
+// ---------------------------------------------------------------------
+/* We stash the desired pipeline depth */
+bool FtpMethod::Configuration(string Message)
+{
+   if (pkgAcqMethod::Configuration(Message) == false)
+      return false;
+   
+   TimeOut = _config->FindI("Acquire::Ftp::Timeout",TimeOut);
+   return true;
+}
+                                                                       /*}}}*/
+// FtpMethod::Fetch - Fetch a file                                     /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool FtpMethod::Fetch(FetchItem *Itm)
+{
+   URI Get = Itm->Uri;
+   const char *File = Get.Path.c_str();
+   FetchResult Res;
+   Res.Filename = Itm->DestFile;
+   Res.IMSHit = false;
+   
+   // Connect to the server
+   if (Server == 0 || Server->Comp(Get) == false)
    {
-      if (Con.Open() == false)
-        break;
-      cout << "Size: " << Con.Size("/debian/README") << endl;
-      
-      time_t Time;
-      Con.ModTime("/debian/README",Time);      
-      cout << "Time: " << TimeRFC1123(Time) << endl;
+      delete Server;
+      Server = new FTPConn(Get);
+   }
+  
+   // Could not connect is a transient error..
+   if (Server->Open(this) == false)
+   {
+      Fail(true);
+      return true;
+   }
    
+   // Get the files information
+   unsigned long Size;
+   if (Server->Size(File,Size) == false ||
+       Server->ModTime(File,FailTime) == false)
+   {
+      Fail(true);
+      return true;
+   }
+   Res.Size = Size;
+
+   // See if it is an IMS hit
+   if (Itm->LastModified == FailTime)
+   {
+      Res.Size = 0;
+      Res.IMSHit = true;
+      URIDone(Res);
+      return true;
+   }
+   
+   // See if the file exists
+   struct stat Buf;
+   if (stat(Itm->DestFile.c_str(),&Buf) == 0)
+   {
+      if (Size == (unsigned)Buf.st_size && FailTime == Buf.st_mtime)
       {
-        
-      FileFd F("t",FileFd::WriteEmpty);
-      Con.Get("/debian/README",F);
+        Res.Size = Buf.st_size;
+        Res.LastModified = Buf.st_mtime;
+        URIDone(Res);
+        return true;
       }
       
+      // Resume?
+      if (FailTime == Buf.st_mtime && Size < (unsigned)Buf.st_size)
+        Res.ResumePoint = Buf.st_size;
+   }
+   
+   // Open the file
+   MD5Summation MD5;
+   {
+      FileFd Fd(Itm->DestFile,FileFd::WriteAny);
+      if (_error->PendingError() == true)
+        return false;
+      
+      URIStart(Res);
+      
+      FailFile = Itm->DestFile;
+      FailFile.c_str();   // Make sure we dont do a malloc in the signal handler
+      FailFd = Fd.Fd();
+      
+      bool Missing;
+      if (Server->Get(File,Fd,Res.ResumePoint,MD5,Missing) == false)
       {
-        
-      FileFd F("t3",FileFd::WriteEmpty);
-      Con.Get("/debian/README.pgp",F);
+        // If the file is missing we hard fail otherwise transient fail
+        if (Missing == true)
+           return false;
+        Fail(true);
+        return true;
       }
-      
-      break;
+
+      Res.Size = Fd.Size();
    }
    
-   _error->DumpErrors();
-   return 0;
+   Res.LastModified = FailTime;
+   Res.MD5Sum = MD5.Result();
+   
+   // Timestamp
+   struct utimbuf UBuf;
+   time(&UBuf.actime);
+   UBuf.actime = FailTime;
+   UBuf.modtime = FailTime;
+   utime(Queue->DestFile.c_str(),&UBuf);
+   FailFd = -1;
+
+   URIDone(Res);
+   
+   return true;
+}
+                                                                       /*}}}*/
+
+int main()
+{ 
+   FtpMethod Mth;
+   
+   return Mth.Run();
 }
index 1b2e147d0efb95bc728f1c9a6b85dda52c3df868..7416589a0c9dc11f937eac3783a6574c0ba38aff 100644 (file)
@@ -1,5 +1,5 @@
 // -*- mode: cpp; mode: fold -*-
-// Description                                                         /*{{{*/// $Id: ftp.h,v 1.1 1999/03/15 06:01:00 jgg Exp $
+// Description                                                         /*{{{*/// $Id: ftp.h,v 1.2 1999/03/15 07:20:41 jgg Exp $
 /* ######################################################################
 
    FTP Aquire Method - This is the FTP aquire method for APT.
@@ -18,6 +18,7 @@ class FTPConn
    int DataListenFd;
    URI ServerName;
    bool TryPassive;
+   bool Debug;
    
    struct sockaddr_in PasvAddr;
    struct sockaddr_in Peer;
@@ -30,22 +31,42 @@ class FTPConn
    
    public:
 
+   bool Comp(URI Other) {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;};
+   
    // Raw connection IO
    bool ReadResp(unsigned int &Ret,string &Text);
    bool WriteMsg(unsigned int &Ret,string &Text,const char *Fmt,...);
    
    // Connection control
-   bool Open();
+   bool Open(pkgAcqMethod *Owner);
    void Close();   
    bool GoPasv();
    
    // Query
-   unsigned long Size(const char *Path);
+   bool Size(const char *Path,unsigned long &Size);
    bool ModTime(const char *Path, time_t &Time);
-   bool Get(const char *Path,FileFd &To,unsigned long Resume = 0);
+   bool Get(const char *Path,FileFd &To,unsigned long Resume,
+           MD5Summation &MD5,bool &Missing);
    
    FTPConn(URI Srv);
    ~FTPConn();
 };
 
+class FtpMethod : public pkgAcqMethod
+{
+   virtual bool Fetch(FetchItem *Itm);
+   virtual bool Configuration(string Message);
+   
+   FTPConn *Server;
+   
+   static string FailFile;
+   static int FailFd;
+   static time_t FailTime;
+   static void SigTerm(int);
+   
+   public:
+   
+   FtpMethod();
+};
+
 #endif
index da15cec3297bf082c6345788abbcf6d78067d398..0d84a9dc70b4ec1a022f7e6a3e8dd89f800918f1 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: http.cc,v 1.28 1999/03/15 06:01:00 jgg Exp $
+// $Id: http.cc,v 1.29 1999/03/15 07:20:41 jgg Exp $
 /* ######################################################################
 
    HTTP Aquire Method - This is the HTTP aquire method for APT.
@@ -916,7 +916,6 @@ void HttpMethod::SigTerm(int)
    
    // Timestamp
    struct utimbuf UBuf;
-   time(&UBuf.actime);
    UBuf.actime = FailTime;
    UBuf.modtime = FailTime;
    utime(FailFile.c_str(),&UBuf);