]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/acquire-worker.cc
Merge branch 'debian/sid' of ssh://git.debian.org/git/apt/apt into debian/sid
[apt.git] / apt-pkg / acquire-worker.cc
index d79b2b16dfb22c3021ebda26ecbbcf4de204420c..de62080da954420796d5983d04d177beaa7106e9 100644 (file)
@@ -109,7 +109,12 @@ bool pkgAcquire::Worker::Start()
    // Get the method path
    string Method = _config->FindDir("Dir::Bin::Methods") + Access;
    if (FileExists(Method) == false)
-      return _error->Error(_("The method driver %s could not be found."),Method.c_str());
+   {
+      _error->Error(_("The method driver %s could not be found."),Method.c_str());
+      if (Access == "https")
+        _error->Notice(_("Is the package %s installed?"), "apt-transport-https");
+      return false;
+   }
 
    if (Debug == true)
       clog << "Starting method '" << Method << '\'' << endl;
@@ -244,6 +249,21 @@ bool pkgAcquire::Worker::RunMessages()
  
             string NewURI = LookupTag(Message,"New-URI",URI.c_str());
             Itm->URI = NewURI;
+
+           ItemDone();
+
+           pkgAcquire::Item *Owner = Itm->Owner;
+           pkgAcquire::ItemDesc Desc = *Itm;
+
+           // Change the status so that it can be dequeued
+           Owner->Status = pkgAcquire::Item::StatIdle;
+           // Mark the item as done (taking care of all queues)
+           // and then put it in the main queue again
+           OwnerQ->ItemDone(Itm);
+           OwnerQ->Owner->Enqueue(Desc);
+
+           if (Log != 0)
+              Log->Done(Desc);
             break;
          }
    
@@ -290,7 +310,15 @@ bool pkgAcquire::Worker::RunMessages()
            
            OwnerQ->ItemDone(Itm);
            unsigned long long const ServerSize = strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10);
-           if (TotalSize != 0 && ServerSize != TotalSize)
+            bool isHit = StringToBool(LookupTag(Message,"IMS-Hit"),false) ||
+                         StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false);
+            // Using the https method the server might return 200, but the
+            // If-Modified-Since condition is not satsified, libcurl will
+            // discard the download. In this case, however, TotalSize will be
+            // set to the actual size of the file, while ServerSize will be set
+            // to 0. Therefore, if the item is marked as a hit and the
+            // downloaded size (ServerSize) is 0, we ignore TotalSize.
+           if (TotalSize != 0 && (!isHit || ServerSize != 0) && ServerSize != TotalSize)
               _error->Warning("Size of file %s is not what the server reported %s %llu",
                               Owner->DestFile.c_str(), LookupTag(Message,"Size","0").c_str(),TotalSize);
 
@@ -317,8 +345,7 @@ bool pkgAcquire::Worker::RunMessages()
            // Log that we are done
            if (Log != 0)
            {
-              if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true ||
-                  StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false) == true)
+              if (isHit)
               {
                  /* Hide 'hits' for local only sources - we also manage to
                     hide gets */
@@ -433,21 +460,7 @@ bool pkgAcquire::Worker::MediaChange(string Message)
             << endl;
 
       std::string const dlstatus = status.str();
-      size_t done = 0;
-      size_t todo = dlstatus.size();
-      errno = 0;
-      int res = 0;
-      do
-      {
-        res = write(status_fd, dlstatus.c_str() + done, todo);
-        if (res < 0 && errno == EINTR)
-           continue;
-        if (res < 0)
-           break;
-        done += res;
-        todo -= res;
-      }
-      while (res > 0 && todo > 0);
+      FileFd::Write(status_fd, dlstatus.c_str(), dlstatus.size());
    }
 
    if (Log == 0 || Log->MediaChange(LookupTag(Message,"Media"),
@@ -481,40 +494,19 @@ bool pkgAcquire::Worker::SendConfiguration()
 
    if (OutFd == -1)
       return false;
-   
-   string Message = "601 Configuration\n";
-   Message.reserve(2000);
 
-   /* Write out all of the configuration directives by walking the 
+   /* Write out all of the configuration directives by walking the
       configuration tree */
-   const Configuration::Item *Top = _config->Tree(0);
-   for (; Top != 0;)
-   {
-      if (Top->Value.empty() == false)
-      {
-        string Line = "Config-Item: " + QuoteString(Top->FullTag(),"=\"\n") + "=";
-        Line += QuoteString(Top->Value,"\n") + '\n';
-        Message += Line;
-      }
-      
-      if (Top->Child != 0)
-      {
-        Top = Top->Child;
-        continue;
-      }
-      
-      while (Top != 0 && Top->Next == 0)
-        Top = Top->Parent;
-      if (Top != 0)
-        Top = Top->Next;
-   }   
-   Message += '\n';
+   std::ostringstream Message;
+   Message << "601 Configuration\n";
+   _config->Dump(Message, NULL, "Config-Item: %F=%V\n", false);
+   Message << '\n';
 
    if (Debug == true)
-      clog << " -> " << Access << ':' << QuoteString(Message,"\n") << endl;
-   OutQueue += Message;
-   OutReady = true; 
-   
+      clog << " -> " << Access << ':' << QuoteString(Message.str(),"\n") << endl;
+   OutQueue += Message.str();
+   OutReady = true;
+
    return true;
 }
                                                                        /*}}}*/
@@ -552,10 +544,10 @@ bool pkgAcquire::Worker::OutFdReady()
       Res = write(OutFd,OutQueue.c_str(),OutQueue.length());
    }
    while (Res < 0 && errno == EINTR);
-   
+
    if (Res <= 0)
       return MethodFailure();
-   
+
    OutQueue.erase(0,Res);
    if (OutQueue.empty() == true)
       OutReady = false;
@@ -576,7 +568,7 @@ bool pkgAcquire::Worker::InFdReady()
                                                                        /*}}}*/
 // Worker::MethodFailure - Called when the method fails                        /*{{{*/
 // ---------------------------------------------------------------------
-/* This is called when the method is belived to have failed, probably because
+/* This is called when the method is believed to have failed, probably because
    read returned -1. */
 bool pkgAcquire::Worker::MethodFailure()
 {