]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/acquire-item.cc
Fix an infinite loop in pkgAcquire::UriIterator::operator++() (Closes: #335615).
[apt.git] / apt-pkg / acquire-item.cc
index c48502bb9437c3d552ed0108b85d4b705997e439..09ea5da02c667deff6070e884c8fa409715e772c 100644 (file)
@@ -345,7 +345,7 @@ void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,
  */
 pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
                                   string URI,string URIDesc,string ShortDesc,
-                                  HashString ExpectedMD5
+                                  HashString ExpectedHash
                                   vector<DiffInfo> diffs)
    : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash), 
      available_patches(diffs)
@@ -568,9 +568,9 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
       else 
         CompressionExtension = ".gz";
    } else {
-      CompressionExtension = comprExt;
+      CompressionExtension = (comprExt == "plain" ? "" : comprExt);
    }
-   Desc.URI = URI + CompressionExtension; 
+   Desc.URI = URI + CompressionExtension;
 
    Desc.Description = URIDesc;
    Desc.Owner = this;
@@ -597,19 +597,30 @@ string pkgAcqIndex::Custom600Headers()
 
 void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 {
+   bool descChanged = false;
    // no .bz2 found, retry with .gz
    if(Desc.URI.substr(Desc.URI.size()-3) == "bz2") {
-      Desc.URI = Desc.URI.substr(0,Desc.URI.size()-3) + "gz"; 
+      Desc.URI = Desc.URI.substr(0,Desc.URI.size()-3) + "gz";
 
-      // retry with a gzip one 
-      new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc, 
+      new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc,
                      ExpectedHash, string(".gz"));
+         descChanged = true;
+   }
+   // no .gz found, retry with uncompressed
+   else if(Desc.URI.substr(Desc.URI.size()-2) == "gz") {
+      Desc.URI = Desc.URI.substr(0,Desc.URI.size()-2);
+
+      new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc,
+                     ExpectedHash, string("plain"));
+         descChanged = true;
+   }
+   if (descChanged) {
       Status = StatDone;
       Complete = false;
       Dequeue();
       return;
-   } 
-   
+   }
+
    // on decompression failure, remove bad versions in partial/
    if(Decompression && Erase) {
       string s = _config->FindDir("Dir::State::lists") + "partial/";
@@ -675,7 +686,6 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
       // The files timestamp matches
       if (StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false) == true)
         return;
-
       Decompression = true;
       Local = true;
       DestFile += ".decomp";
@@ -701,12 +711,19 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
    else
       Local = true;
    
-   string compExt = Desc.URI.substr(Desc.URI.size()-3);
-   char *decompProg;
+   string compExt = flExtension(flNotDir(URI(Desc.URI).Path));
+   const char *decompProg;
    if(compExt == "bz2") 
       decompProg = "bzip2";
-   else if(compExt == ".gz") 
+   else if(compExt == "gz") 
       decompProg = "gzip";
+   // flExtensions returns the full name if no extension is found
+   // this is why we have this complicated compare operation here
+   // FIMXE: add a new flJustExtension() that return "" if no
+   //        extension is found and use that above so that it can
+   //        be tested against ""
+   else if(compExt == flNotDir(URI(Desc.URI).Path))
+      decompProg = "copy";
    else {
       _error->Error("Unsupported extension: %s", compExt.c_str());
       return;
@@ -771,16 +788,19 @@ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,
    Desc.Owner = this;
    Desc.ShortDesc = ShortDesc;
    Desc.URI = URI;
-   
       
    string Final = _config->FindDir("Dir::State::lists");
    Final += URItoFileName(RealURI);
    struct stat Buf;
    if (stat(Final.c_str(),&Buf) == 0)
    {
-      // File was already in place.  It needs to be re-verified
-      // because Release might have changed, so Move it into partial
-      Rename(Final,DestFile);
+      // File was already in place.  It needs to be re-downloaded/verified
+      // because Release might have changed, we do give it a differnt
+      // name than DestFile because otherwise the http method will
+      // send If-Range requests and there are too many broken servers
+      // out there that do not understand them
+      LastGoodSig = DestFile+".reverify";
+      Rename(Final,LastGoodSig);
    }
 
    QueueURI(Desc);
@@ -792,7 +812,7 @@ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,
 string pkgAcqMetaSig::Custom600Headers()
 {
    struct stat Buf;
-   if (stat(DestFile.c_str(),&Buf) != 0)
+   if (stat(LastGoodSig.c_str(),&Buf) != 0)
       return "\nIndex-File: true";
 
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
@@ -822,6 +842,12 @@ void pkgAcqMetaSig::Done(string Message,unsigned long Size,string MD5,
 
    Complete = true;
 
+   // put the last known good file back on i-m-s hit (it will
+   // be re-verified again)
+   // Else do nothing, we have the new file in DestFile then
+   if(StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
+      Rename(LastGoodSig, DestFile);
+
    // queue a pkgAcqMetaIndex to be verified against the sig we just retrieved
    new pkgAcqMetaIndex(Owner, MetaIndexURI, MetaIndexURIDesc, MetaIndexShortDesc,
                       DestFile, IndexTargets, MetaIndexParser);
@@ -838,7 +864,7 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
       Item::Failed(Message,Cnf);
       // move the sigfile back on transient network failures 
       if(FileExists(DestFile))
-        Rename(DestFile,Final);
+        Rename(LastGoodSig,Final);
 
       // set the status back to , Item::Failed likes to reset it
       Status = pkgAcquire::Item::StatTransientNetworkError;
@@ -966,18 +992,18 @@ void pkgAcqMetaIndex::RetrievalDone(string Message)
 
    // see if the download was a IMSHit
    IMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false);
-
    Complete = true;
 
    string FinalFile = _config->FindDir("Dir::State::lists");
    FinalFile += URItoFileName(RealURI);
 
-   // The files timestamp matches
-   if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == false)
-   {
-      // Move it into position
+   // If we get a IMS hit we can remove the empty file in partial
+   // othersie we move the file in place
+   if (IMSHit)
+      unlink(DestFile.c_str());
+   else
       Rename(DestFile,FinalFile);
-   }
+
    chmod(FinalFile.c_str(),0644);
    DestFile = FinalFile;
 }
@@ -1538,7 +1564,7 @@ void pkgAcqFile::Done(string Message,unsigned long Size,string CalcHash,
    Item::Done(Message,Size,CalcHash,Cnf);
 
    // Check the hash
-   if(ExpectedHash.toStr() != CalcHash)
+   if(!ExpectedHash.empty() && ExpectedHash.toStr() != CalcHash)
    {
       Status = StatError;
       ErrorText = "Hash Sum mismatch";