ソースを参照

Cleanup pkgAcqIndex

Michael Vogt 12 年 前
コミット
651bddadd0
共有2 個のファイルを変更した171 個の追加135 個の削除を含む
  1. 138 110
      apt-pkg/acquire-item.cc
  2. 33 25
      apt-pkg/acquire-item.h

+ 138 - 110
apt-pkg/acquire-item.cc

@@ -933,6 +933,23 @@ void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,HashStri
    }
    }
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+// AcqBaseIndex::VerifyHashByMetaKey - verify hash for the given metakey /*{{{*/
+bool pkgAcqBaseIndex::VerifyHashByMetaKey(HashStringList const &Hashes)
+{
+   if(MetaKey != "" && Hashes.size() > 0)
+   {
+      indexRecords::checkSum *Record = MetaIndexParser->Lookup(MetaKey);
+      if(Record && Record->Hashes.usable() && Hashes != Record->Hashes)
+      {
+         printHashSumComparision(RealURI, Record->Hashes, Hashes);
+         return false;
+      }
+   }
+   return true;
+}
+
+
 // AcqIndex::AcqIndex - Constructor					/*{{{*/
 // AcqIndex::AcqIndex - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The package file is added to the queue and a second class is 
 /* The package file is added to the queue and a second class is 
@@ -940,8 +957,10 @@ void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,HashStri
 pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
 pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
 			 string URI,string URIDesc,string ShortDesc,
 			 string URI,string URIDesc,string ShortDesc,
 			 HashStringList const  &ExpectedHash)
 			 HashStringList const  &ExpectedHash)
-   : pkgAcqBaseIndex(Owner, 0, NULL, ExpectedHash, NULL), RealURI(URI)
+   : pkgAcqBaseIndex(Owner, 0, NULL, ExpectedHash, NULL)
 {
 {
+   RealURI = URI;
+
    AutoSelectCompression();
    AutoSelectCompression();
    Init(URI, URIDesc, ShortDesc);
    Init(URI, URIDesc, ShortDesc);
 
 
@@ -958,8 +977,10 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
 			 HashStringList const &ExpectedHash, 
 			 HashStringList const &ExpectedHash, 
                          indexRecords *MetaIndexParser)
                          indexRecords *MetaIndexParser)
    : pkgAcqBaseIndex(Owner, TransactionManager, Target, ExpectedHash, 
    : pkgAcqBaseIndex(Owner, TransactionManager, Target, ExpectedHash, 
-                     MetaIndexParser), RealURI(Target->URI)
+                     MetaIndexParser)
 {
 {
+   RealURI = Target->URI;
+
    // autoselect the compression method
    // autoselect the compression method
    AutoSelectCompression();
    AutoSelectCompression();
    Init(Target->URI, Target->Description, Target->ShortDesc);
    Init(Target->URI, Target->Description, Target->ShortDesc);
@@ -974,34 +995,38 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
 void pkgAcqIndex::AutoSelectCompression()
 void pkgAcqIndex::AutoSelectCompression()
 {
 {
    std::vector<std::string> types = APT::Configuration::getCompressionTypes();
    std::vector<std::string> types = APT::Configuration::getCompressionTypes();
-   CompressionExtension = "";
+   CompressionExtensions = "";
    if (ExpectedHashes.usable())
    if (ExpectedHashes.usable())
    {
    {
-      for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
-	 if (*t == "uncompressed" || MetaIndexParser->Exists(string(Target->MetaKey).append(".").append(*t)) == true)
-	    CompressionExtension.append(*t).append(" ");
+      for (std::vector<std::string>::const_iterator t = types.begin();
+           t != types.end(); ++t)
+      {
+         std::string CompressedMetaKey = string(Target->MetaKey).append(".").append(*t);
+         if (*t == "uncompressed" || 
+             MetaIndexParser->Exists(CompressedMetaKey) == true)
+            CompressionExtensions.append(*t).append(" ");
+      }
    }
    }
    else
    else
    {
    {
       for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
       for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
-	 CompressionExtension.append(*t).append(" ");
+	 CompressionExtensions.append(*t).append(" ");
    }
    }
-   if (CompressionExtension.empty() == false)
-      CompressionExtension.erase(CompressionExtension.end()-1);
+   if (CompressionExtensions.empty() == false)
+      CompressionExtensions.erase(CompressionExtensions.end()-1);
 }
 }
 // AcqIndex::Init - defered Constructor					/*{{{*/
 // AcqIndex::Init - defered Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 void pkgAcqIndex::Init(string const &URI, string const &URIDesc, 
 void pkgAcqIndex::Init(string const &URI, string const &URIDesc, 
                        string const &ShortDesc)
                        string const &ShortDesc)
 {
 {
-   Decompression = false;
-   Erase = false;
+   Stage = STAGE_DOWNLOAD;
 
 
    DestFile = _config->FindDir("Dir::State::lists") + "partial/";
    DestFile = _config->FindDir("Dir::State::lists") + "partial/";
    DestFile += URItoFileName(URI);
    DestFile += URItoFileName(URI);
 
 
-   std::string const comprExt = CompressionExtension.substr(0, CompressionExtension.find(' '));
-   if (comprExt == "uncompressed")
+   ComprExt = CompressionExtensions.substr(0, CompressionExtensions.find(' '));
+   if (ComprExt == "uncompressed")
    {
    {
       Desc.URI = URI;
       Desc.URI = URI;
       if(Target)
       if(Target)
@@ -1009,10 +1034,10 @@ void pkgAcqIndex::Init(string const &URI, string const &URIDesc,
    }
    }
    else
    else
    {
    {
-      Desc.URI = URI + '.' + comprExt;
-      DestFile = DestFile + '.' + comprExt;
+      Desc.URI = URI + '.' + ComprExt;
+      DestFile = DestFile + '.' + ComprExt;
       if(Target)
       if(Target)
-         MetaKey = string(Target->MetaKey) + '.' + comprExt;
+         MetaKey = string(Target->MetaKey) + '.' + ComprExt;
    }
    }
 
 
    // load the filesize
    // load the filesize
@@ -1084,18 +1109,19 @@ string pkgAcqIndex::Custom600Headers() const
 /* */
 /* */
 void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)	/*{{{*/
 void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)	/*{{{*/
 {
 {
-   size_t const nextExt = CompressionExtension.find(' ');
+   size_t const nextExt = CompressionExtensions.find(' ');
    if (nextExt != std::string::npos)
    if (nextExt != std::string::npos)
    {
    {
-      CompressionExtension = CompressionExtension.substr(nextExt+1);
+      CompressionExtensions = CompressionExtensions.substr(nextExt+1);
       Init(RealURI, Desc.Description, Desc.ShortDesc);
       Init(RealURI, Desc.Description, Desc.ShortDesc);
       return;
       return;
    }
    }
 
 
    // on decompression failure, remove bad versions in partial/
    // on decompression failure, remove bad versions in partial/
-   if (Decompression && Erase) {
+   if (Stage == STAGE_DECOMPRESS_AND_VERIFY)
+   {
       string s = _config->FindDir("Dir::State::lists") + "partial/";
       string s = _config->FindDir("Dir::State::lists") + "partial/";
-      s.append(URItoFileName(RealURI));
+      s += URItoFileName(RealURI)  + '.' + ComprExt;
       unlink(s.c_str());
       unlink(s.c_str());
    }
    }
 
 
@@ -1110,11 +1136,10 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)	/*{{{*/
 /* */
 /* */
 std::string pkgAcqIndex::GetFinalFilename() const
 std::string pkgAcqIndex::GetFinalFilename() const
 {
 {
-   std::string const compExt = CompressionExtension.substr(0, CompressionExtension.find(' '));
    std::string FinalFile = _config->FindDir("Dir::State::lists");
    std::string FinalFile = _config->FindDir("Dir::State::lists");
    FinalFile += URItoFileName(RealURI);
    FinalFile += URItoFileName(RealURI);
    if (_config->FindB("Acquire::GzipIndexes",false) == true)
    if (_config->FindB("Acquire::GzipIndexes",false) == true)
-      FinalFile += '.' + compExt;
+      FinalFile += '.' + ComprExt;
    return FinalFile;
    return FinalFile;
 }
 }
                                                                        /*}}}*/
                                                                        /*}}}*/
@@ -1123,8 +1148,6 @@ std::string pkgAcqIndex::GetFinalFilename() const
 /* */
 /* */
 void pkgAcqIndex::ReverifyAfterIMS()
 void pkgAcqIndex::ReverifyAfterIMS()
 {
 {
-   std::string const compExt = CompressionExtension.substr(0, CompressionExtension.find(' '));
-
    // update destfile to *not* include the compression extension when doing
    // update destfile to *not* include the compression extension when doing
    // a reverify (as its uncompressed on disk already)
    // a reverify (as its uncompressed on disk already)
    DestFile =  _config->FindDir("Dir::State::lists") + "partial/";
    DestFile =  _config->FindDir("Dir::State::lists") + "partial/";
@@ -1132,18 +1155,18 @@ void pkgAcqIndex::ReverifyAfterIMS()
 
 
    // adjust DestFile if its compressed on disk
    // adjust DestFile if its compressed on disk
    if (_config->FindB("Acquire::GzipIndexes",false) == true)
    if (_config->FindB("Acquire::GzipIndexes",false) == true)
-      DestFile += '.' + compExt;
+      DestFile += '.' + ComprExt;
 
 
    // copy FinalFile into partial/ so that we check the hash again
    // copy FinalFile into partial/ so that we check the hash again
    string FinalFile = GetFinalFilename();
    string FinalFile = GetFinalFilename();
-   Decompression = true;
+   Stage = STAGE_DECOMPRESS_AND_VERIFY;
    Desc.URI = "copy:" + FinalFile;
    Desc.URI = "copy:" + FinalFile;
    QueueURI(Desc);
    QueueURI(Desc);
 }
 }
                                                                        /*}}}*/
                                                                        /*}}}*/
 
 
-// pkgAcqIndex::ValidateFile - Validate the downloaded file     	/*{{{*/
-// ---------------------------------------------------------------------
+// AcqIndex::ValidateFile - Validate the content of the downloaded file  /*{{{*/
+// --------------------------------------------------------------------------
 bool pkgAcqIndex::ValidateFile(const std::string &FileName)
 bool pkgAcqIndex::ValidateFile(const std::string &FileName)
 {
 {
    // FIXME: this can go away once we only ever download stuff that
    // FIXME: this can go away once we only ever download stuff that
@@ -1153,7 +1176,7 @@ bool pkgAcqIndex::ValidateFile(const std::string &FileName)
    /* Always validate the index file for correctness (all indexes must
    /* Always validate the index file for correctness (all indexes must
     * have a Package field) (LP: #346386) (Closes: #627642) 
     * have a Package field) (LP: #346386) (Closes: #627642) 
     */
     */
-   FileFd fd(DestFile, FileFd::ReadOnly, FileFd::Extension);
+   FileFd fd(FileName, FileFd::ReadOnly, FileFd::Extension);
    // Only test for correctness if the content of the file is not empty
    // Only test for correctness if the content of the file is not empty
    // (empty is ok)
    // (empty is ok)
    if (fd.Size() > 0)
    if (fd.Size() > 0)
@@ -1177,69 +1200,45 @@ bool pkgAcqIndex::ValidateFile(const std::string &FileName)
    to the uncompressed version of the file. If this is so the file
    to the uncompressed version of the file. If this is so the file
    is copied into the partial directory. In all other cases the file
    is copied into the partial directory. In all other cases the file
    is decompressed with a compressed uri. */
    is decompressed with a compressed uri. */
-void pkgAcqIndex::Done(string Message, unsigned long long Size,
+void pkgAcqIndex::Done(string Message,
+                       unsigned long long Size,
                        HashStringList const &Hashes,
                        HashStringList const &Hashes,
 		       pkgAcquire::MethodConfig *Cfg)
 		       pkgAcquire::MethodConfig *Cfg)
 {
 {
    Item::Done(Message,Size,Hashes,Cfg);
    Item::Done(Message,Size,Hashes,Cfg);
-   std::string const compExt = CompressionExtension.substr(0, CompressionExtension.find(' '));
 
 
-   if (Decompression == true)
+   switch(Stage) 
    {
    {
-      if (ExpectedHashes.usable() && ExpectedHashes != Hashes)
-      {
-         Desc.URI = RealURI;
-	 RenameOnError(HashSumMismatch);
-	 printHashSumComparision(RealURI, ExpectedHashes, Hashes);
-         Failed(Message, Cfg);
-         return;
-      }
-
-      if(!ValidateFile(DestFile))
-      {
-         RenameOnError(InvalidFormat);
-         Failed(Message, Cfg);
-         return;
-      }
-
-      // FIXME: can we void the "Erase" bool here as its very non-local?
-      std::string CompressedFile = _config->FindDir("Dir::State::lists") + "partial/";
-      CompressedFile += URItoFileName(RealURI);
-      if(_config->FindB("Acquire::GzipIndexes",false) == false)
-         CompressedFile += '.' + compExt;
-
-      // Remove the compressed version.
-      if (Erase == true)
-	 unlink(CompressedFile.c_str());
-
-      // Done, queue for rename on transaction finished
-      TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename());
-
-      return;
+      case STAGE_DOWNLOAD:
+         StageDownloadDone(Message, Hashes, Cfg);
+         break;
+      case STAGE_DECOMPRESS_AND_VERIFY:
+         StageDecompressDone(Message, Hashes, Cfg);
+         break;
    }
    }
-   
-   // FIXME: use the same method to find 
-   // check the compressed hash too
-   if(MetaKey != "" && Hashes.size() > 0)
+}
+
+// AcqIndex::StageDownloadDone - Queue for decompress and verify        /*{{{*/
+void pkgAcqIndex::StageDownloadDone(string Message,
+                                    HashStringList const &Hashes,
+                                    pkgAcquire::MethodConfig *Cfg)
+{
+   // First check if the calculcated Hash of the (compressed) downloaded
+   // file matches the hash we have in the MetaIndexRecords for this file
+   if(VerifyHashByMetaKey(Hashes) == false)
    {
    {
-      indexRecords::checkSum *Record = MetaIndexParser->Lookup(MetaKey);
-      if(Record && Record->Hashes.usable() && Hashes != Record->Hashes)
-      {
-         RenameOnError(HashSumMismatch);
-         printHashSumComparision(RealURI, Record->Hashes, Hashes);
-         Failed(Message, Cfg);
-         return;
-      }
+      RenameOnError(HashSumMismatch);
+      Failed(Message, Cfg);
+      return;
    }
    }
 
 
-   Erase = false;
    Complete = true;
    Complete = true;
    
    
    // Handle the unzipd case
    // Handle the unzipd case
    string FileName = LookupTag(Message,"Alt-Filename");
    string FileName = LookupTag(Message,"Alt-Filename");
    if (FileName.empty() == false)
    if (FileName.empty() == false)
    {
    {
-      Decompression = true;
+      Stage = STAGE_DECOMPRESS_AND_VERIFY;
       Local = true;
       Local = true;
       DestFile += ".decomp";
       DestFile += ".decomp";
       Desc.URI = "copy:" + FileName;
       Desc.URI = "copy:" + FileName;
@@ -1263,43 +1262,32 @@ void pkgAcqIndex::Done(string Message, unsigned long long Size,
       ErrorText = "Method gave a blank filename";
       ErrorText = "Method gave a blank filename";
    }
    }
 
 
-   if (FileName == DestFile)
-      Erase = true;
-   else
+   // Methods like e.g. "file:" will give us a (compressed) FileName that is
+   // not the "DestFile" we set, in this case we uncompress from the local file
+   if (FileName != DestFile)
       Local = true;
       Local = true;
 
 
-   // do not reverify cdrom sources as apt-cdrom may rewrite the Packages
-   // file when its doing the indexcopy
-   if (RealURI.substr(0,6) == "cdrom:" &&
-       StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
-      return;
-
-   // The files timestamp matches, reverify by copy into partial/
-   if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
+   // we need to verify the file against the current Release file again
+   // on if-modfied-since hit to avoid a stale attack against us
+   if(StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
    {
    {
-      Erase = false;
-      ReverifyAfterIMS();
-#if 0 // ???
-      // set destfile to the final destfile
-      if(_config->FindB("Acquire::GzipIndexes",false) == false)
-      {
-         DestFile = _config->FindDir("Dir::State::lists") + "partial/";
-         DestFile += URItoFileName(RealURI);
-      }
+      // do not reverify cdrom sources as apt-cdrom may rewrite the Packages
+      // file when its doing the indexcopy
+      if (RealURI.substr(0,6) == "cdrom:")
+         return;
 
 
-      ReverifyAfterIMS(FileName);
-#endif
+      // The files timestamp matches, reverify by copy into partial/
+      ReverifyAfterIMS();
       return;
       return;
    }
    }
-   string decompProg;
 
 
-   // If we enable compressed indexes, queue for hash verification
+   // If we have compressed indexes enabled, queue for hash verification
    if (_config->FindB("Acquire::GzipIndexes",false))
    if (_config->FindB("Acquire::GzipIndexes",false))
    {
    {
       DestFile = _config->FindDir("Dir::State::lists") + "partial/";
       DestFile = _config->FindDir("Dir::State::lists") + "partial/";
-      DestFile += URItoFileName(RealURI) + '.' + compExt;
+      DestFile += URItoFileName(RealURI) + '.' + ComprExt;
 
 
-      Decompression = true;
+      Stage = STAGE_DECOMPRESS_AND_VERIFY;
       Desc.URI = "copy:" + FileName;
       Desc.URI = "copy:" + FileName;
       QueueURI(Desc);
       QueueURI(Desc);
 
 
@@ -1307,16 +1295,19 @@ void pkgAcqIndex::Done(string Message, unsigned long long Size,
     }
     }
 
 
    // get the binary name for your used compression type
    // get the binary name for your used compression type
-   decompProg = _config->Find(string("Acquire::CompressionTypes::").append(compExt),"");
-   if(decompProg.empty() == false);
-   else if(compExt == "uncompressed")
+   string decompProg;
+   if(ComprExt == "uncompressed")
       decompProg = "copy";
       decompProg = "copy";
-   else {
-      _error->Error("Unsupported extension: %s", compExt.c_str());
+   else
+      decompProg = _config->Find(string("Acquire::CompressionTypes::").append(ComprExt),"");
+   if(decompProg.empty() == true)
+   {
+      _error->Error("Unsupported extension: %s", ComprExt.c_str());
       return;
       return;
    }
    }
 
 
-   Decompression = true;
+   // queue uri for the next stage
+   Stage = STAGE_DECOMPRESS_AND_VERIFY;
    DestFile += ".decomp";
    DestFile += ".decomp";
    Desc.URI = decompProg + ":" + FileName;
    Desc.URI = decompProg + ":" + FileName;
    QueueURI(Desc);
    QueueURI(Desc);
@@ -1331,6 +1322,43 @@ void pkgAcqIndex::Done(string Message, unsigned long long Size,
 	#pragma GCC diagnostic pop
 	#pragma GCC diagnostic pop
 #endif
 #endif
 }
 }
+                                                                        /*}}}*/
+// pkgAcqIndex::StageDecompressDone - Final verification               /*{{{*/
+void pkgAcqIndex::StageDecompressDone(string Message,
+                                      HashStringList const &Hashes,
+                                      pkgAcquire::MethodConfig *Cfg)
+{
+   if (ExpectedHashes.usable() && ExpectedHashes != Hashes)
+   {
+      Desc.URI = RealURI;
+      RenameOnError(HashSumMismatch);
+      printHashSumComparision(RealURI, ExpectedHashes, Hashes);
+      Failed(Message, Cfg);
+      return;
+   }
+
+   if(!ValidateFile(DestFile))
+   {
+      RenameOnError(InvalidFormat);
+      Failed(Message, Cfg);
+      return;
+   }
+   
+   // remove the compressed version of the file (if the file got uncompressed)
+   URI Get = LookupTag(Message, "URI");
+   if (Get.Access != "copy")
+   {
+      // To account for relative paths
+      std::string CompressedFile = Get.Host + Get.Path;
+      unlink(CompressedFile.c_str());
+   }
+   
+   // Done, queue for rename on transaction finished
+   TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename());
+   
+   return;
+}
+                                                                        /*}}}*/
 									/*}}}*/
 									/*}}}*/
 // AcqIndexTrans::pkgAcqIndexTrans - Constructor			/*{{{*/
 // AcqIndexTrans::pkgAcqIndexTrans - Constructor			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
@@ -1371,10 +1399,10 @@ string pkgAcqIndexTrans::Custom600Headers() const
 /* */
 /* */
 void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 {
 {
-   size_t const nextExt = CompressionExtension.find(' ');
+   size_t const nextExt = CompressionExtensions.find(' ');
    if (nextExt != std::string::npos)
    if (nextExt != std::string::npos)
    {
    {
-      CompressionExtension = CompressionExtension.substr(nextExt+1);
+      CompressionExtensions = CompressionExtensions.substr(nextExt+1);
       Init(RealURI, Desc.Description, Desc.ShortDesc);
       Init(RealURI, Desc.Description, Desc.ShortDesc);
       Status = StatIdle;
       Status = StatIdle;
       return;
       return;

+ 33 - 25
apt-pkg/acquire-item.h

@@ -601,10 +601,20 @@ class pkgAcqBaseIndex : public pkgAcquire::Item
    /** \brief Pointer to the IndexTarget data
    /** \brief Pointer to the IndexTarget data
     */
     */
    const struct IndexTarget * Target;
    const struct IndexTarget * Target;
+
+   /** \brief Pointer to the indexRecords parser */
    indexRecords *MetaIndexParser;
    indexRecords *MetaIndexParser;
+
    /** \brief The MetaIndex Key */
    /** \brief The MetaIndex Key */
    std::string MetaKey;
    std::string MetaKey;
 
 
+   /** \brief The URI of the index file to recreate at our end (either
+    *  by downloading it or by applying partial patches).
+    */
+   std::string RealURI;
+
+   bool VerifyHashByMetaKey(HashStringList const &Hashes);
+
    pkgAcqBaseIndex(pkgAcquire *Owner,
    pkgAcqBaseIndex(pkgAcquire *Owner,
                    pkgAcqMetaBase *TransactionManager,
                    pkgAcqMetaBase *TransactionManager,
                    struct IndexTarget const * const Target,
                    struct IndexTarget const * const Target,
@@ -631,11 +641,6 @@ class pkgAcqDiffIndex : public pkgAcqBaseIndex
    /** \brief If \b true, debugging information will be written to std::clog. */
    /** \brief If \b true, debugging information will be written to std::clog. */
    bool Debug;
    bool Debug;
 
 
-   /** \brief The URI of the index file to recreate at our end (either
-    *  by downloading it or by applying partial patches).
-    */
-   std::string RealURI;
-
    /** \brief The index file which will be patched to generate the new
    /** \brief The index file which will be patched to generate the new
     *  file.
     *  file.
     */
     */
@@ -712,11 +717,6 @@ class pkgAcqIndexMergeDiffs : public pkgAcqBaseIndex
     */
     */
    bool Debug;
    bool Debug;
 
 
-   /** \brief URI of the package index file that is being
-    *  reconstructed.
-    */
-   std::string RealURI;
-
    /** \brief description of the file being downloaded. */
    /** \brief description of the file being downloaded. */
    std::string Description;
    std::string Description;
 
 
@@ -831,11 +831,6 @@ class pkgAcqIndexDiffs : public pkgAcqBaseIndex
     */
     */
    bool Debug;
    bool Debug;
 
 
-   /** \brief The URI of the package index file that is being
-    *  reconstructed.
-    */
-   std::string RealURI;
-
    /** A description of the file being downloaded. */
    /** A description of the file being downloaded. */
    std::string Description;
    std::string Description;
 
 
@@ -927,23 +922,36 @@ class pkgAcqIndex : public pkgAcqBaseIndex
 
 
    protected:
    protected:
 
 
-   /** \brief If \b true, the index file has been decompressed. */
-   bool Decompression;
-
-   /** \brief If \b true, the partially downloaded file will be
-    *  removed when the download completes.
+   /** \brief The stages the method goes through
+    *
+    *  The method first downloads the indexfile, then its decompressed (or
+    *  copied) and verified
     */
     */
-   bool Erase;
+   enum AllStages {
+      STAGE_DOWNLOAD,
+      STAGE_DECOMPRESS_AND_VERIFY,
+   };
+   AllStages Stage;
 
 
-   /** \brief The object that is actually being fetched (minus any
-    *  compression-related extensions).
+   /** \brief Handle what needs to be done when the download is done */
+   void StageDownloadDone(std::string Message,
+                          HashStringList const &Hashes,
+                          pkgAcquire::MethodConfig *Cfg);
+
+   /** \brief Handle what needs to be done when the decompression/copy is
+    *         done 
     */
     */
-   std::string RealURI;
+   void StageDecompressDone(std::string Message,
+                            HashStringList const &Hashes,
+                            pkgAcquire::MethodConfig *Cfg);
 
 
    /** \brief The compression-related file extensions that are being
    /** \brief The compression-related file extensions that are being
     *  added to the downloaded file one by one if first fails (e.g., "gz bz2").
     *  added to the downloaded file one by one if first fails (e.g., "gz bz2").
     */
     */
-   std::string CompressionExtension;
+   std::string CompressionExtensions;
+
+   /** \brief The actual compression extension currently used */
+   std::string ComprExt;
 
 
    /** \brief Do the changes needed to fetch via AptByHash (if needed) */
    /** \brief Do the changes needed to fetch via AptByHash (if needed) */
    void InitByHashIfNeeded(const std::string MetaKey);
    void InitByHashIfNeeded(const std::string MetaKey);