]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/acquire-item.cc
fix gcc warnings
[apt.git] / apt-pkg / acquire-item.cc
index c3b6f0e6ad51727e4c8c460ef510705c75dd8335..1fa7971c54cba862d32de53e23c39fc2a848aff4 100644 (file)
@@ -66,13 +66,15 @@ static void printHashSumComparision(std::string const &URI, HashStringList const
 // Acquire::Item::Item - Constructor                                   /*{{{*/
 pkgAcquire::Item::Item(pkgAcquire *Owner,
                        HashStringList const &ExpectedHashes,
-                       unsigned long TransactionID)
+                       pkgAcqMetaBase *TransactionManager)
    : Owner(Owner), FileSize(0), PartialSize(0), Mode(0), ID(0), Complete(false),
-     Local(false), QueueCounter(0), TransactionID(TransactionID),
+     Local(false), QueueCounter(0), TransactionManager(TransactionManager),
      ExpectedAdditionalItems(0), ExpectedHashes(ExpectedHashes)
 {
    Owner->Add(this);
    Status = StatIdle;
+   if(TransactionManager != NULL)
+      TransactionManager->Add(this);
 }
                                                                        /*}}}*/
 // Acquire::Item::~Item - Destructor                                   /*{{{*/
@@ -237,120 +239,6 @@ void pkgAcquire::Item::ReportMirrorFailure(string FailCode)
    }
 }
                                                                        /*}}}*/
-// AcqSubIndex::AcqSubIndex - Constructor                              /*{{{*/
-// ---------------------------------------------------------------------
-/* Get a sub-index file based on checksums from a 'master' file and
-   possibly query additional files */
-pkgAcqSubIndex::pkgAcqSubIndex(pkgAcquire *Owner, 
-                               unsigned long TransactionID,
-                               string const &URI,
-                               string const &URIDesc, string const &ShortDesc,
-                               HashStringList const &ExpectedHashes)
-   : Item(Owner, ExpectedHashes, TransactionID)
-{
-   /* XXX: Beware: Currently this class does nothing (of value) anymore ! */
-   Debug = _config->FindB("Debug::pkgAcquire::SubIndex",false);
-
-   DestFile = _config->FindDir("Dir::State::lists") + "partial/";
-   DestFile += URItoFileName(URI);
-
-   Desc.URI = URI;
-   Desc.Description = URIDesc;
-   Desc.Owner = this;
-   Desc.ShortDesc = ShortDesc;
-
-   QueueURI(Desc);
-
-   if(Debug)
-      std::clog << "pkgAcqSubIndex: " << Desc.URI << std::endl;
-}
-                                                                       /*}}}*/
-// AcqSubIndex::Custom600Headers - Insert custom request headers       /*{{{*/
-// ---------------------------------------------------------------------
-/* The only header we use is the last-modified header. */
-string pkgAcqSubIndex::Custom600Headers() const
-{
-   string Final = _config->FindDir("Dir::State::lists");
-   Final += URItoFileName(Desc.URI);
-
-   struct stat Buf;
-   if (stat(Final.c_str(),&Buf) != 0)
-      return "\nIndex-File: true\nFail-Ignore: true\n";
-   return "\nIndex-File: true\nFail-Ignore: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
-}
-                                                                       /*}}}*/
-void pkgAcqSubIndex::Failed(string Message,pkgAcquire::MethodConfig * /*Cnf*/)/*{{{*/
-{
-   if(Debug)
-      std::clog << "pkgAcqSubIndex failed: " << Desc.URI << " with " << Message << std::endl;
-
-   Complete = false;
-   Status = StatDone;
-   Dequeue();
-
-   // No good Index is provided
-}
-                                                                       /*}}}*/
-void pkgAcqSubIndex::Done(string Message,unsigned long long Size,HashStringList const &Hashes, /*{{{*/
-                          pkgAcquire::MethodConfig *Cnf)
-{
-   if(Debug)
-      std::clog << "pkgAcqSubIndex::Done(): " << Desc.URI << std::endl;
-
-   string FileName = LookupTag(Message,"Filename");
-   if (FileName.empty() == true)
-   {
-      Status = StatError;
-      ErrorText = "Method gave a blank filename";
-      return;
-   }
-
-   if (FileName != DestFile)
-   {
-      Local = true;
-      Desc.URI = "copy:" + FileName;
-      QueueURI(Desc);
-      return;
-   }
-
-   Item::Done(Message, Size, Hashes, Cnf);
-
-   string FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(Desc.URI);
-
-   /* Downloaded invalid transindex => Error (LP: #346386) (Closes: #627642) */
-   indexRecords SubIndexParser;
-   if (FileExists(DestFile) == true && !SubIndexParser.Load(DestFile)) {
-      Status = StatError;
-      ErrorText = SubIndexParser.ErrorText;
-      return;
-   }
-
-   // success in downloading the index
-   // rename the index
-   if(Debug)
-      std::clog << "Renaming: " << DestFile << " -> " << FinalFile << std::endl;
-   Rename(DestFile,FinalFile);
-   chmod(FinalFile.c_str(),0644);
-   DestFile = FinalFile;
-
-   if(ParseIndex(DestFile) == false)
-      return Failed("", NULL);
-
-   Complete = true;
-   Status = StatDone;
-   Dequeue();
-   return;
-}
-                                                                       /*}}}*/
-bool pkgAcqSubIndex::ParseIndex(string const &IndexFile)               /*{{{*/
-{
-   indexRecords SubIndexParser;
-   if (FileExists(IndexFile) == false || SubIndexParser.Load(IndexFile) == false)
-      return false;
-   // so something with the downloaded index
-   return true;
-}
-                                                                       /*}}}*/
 // AcqDiffIndex::AcqDiffIndex - Constructor                            /*{{{*/
 // ---------------------------------------------------------------------
 /* Get the DiffIndex file first and see if there are patches available
@@ -359,11 +247,11 @@ bool pkgAcqSubIndex::ParseIndex(string const &IndexFile)          /*{{{*/
  * the original packages file
  */
 pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
-                                 unsigned long TransactionID,
+                                 pkgAcqMetaBase *TransactionManager,
                                  IndexTarget const * const Target,
                                 HashStringList const &ExpectedHashes,
                                  indexRecords *MetaIndexParser)
-   : pkgAcqBaseIndex(Owner, TransactionID, Target, ExpectedHashes, 
+   : pkgAcqBaseIndex(Owner, TransactionManager, Target, ExpectedHashes, 
                      MetaIndexParser)
 {
    
@@ -376,7 +264,7 @@ pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
    Desc.URI = Target->URI + ".diff/Index";
 
    DestFile = _config->FindDir("Dir::State::lists") + "partial/";
-   DestFile += URItoFileName(Target->URI) + string(".DiffIndex");
+   DestFile += URItoFileName(Desc.URI);
 
    if(Debug)
       std::clog << "pkgAcqDiffIndex: " << Desc.URI << std::endl;
@@ -412,7 +300,7 @@ pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
 string pkgAcqDiffIndex::Custom600Headers() const
 {
    string Final = _config->FindDir("Dir::State::lists");
-   Final += URItoFileName(RealURI) + string(".IndexDiff");
+   Final += URItoFileName(Desc.URI);
    
    if(Debug)
       std::clog << "Custom600Header-IMS: " << Final << std::endl;
@@ -462,7 +350,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)          /*{{{*/
            std::clog << "Package file is up-to-date" << std::endl;
         // list cleanup needs to know that this file as well as the already
         // present index is ours, so we create an empty diff to save it for us
-        new pkgAcqIndexDiffs(Owner, TransactionID, Target, 
+        new pkgAcqIndexDiffs(Owner, TransactionManager, Target, 
                               ExpectedHashes, MetaIndexParser, 
                               ServerSha1, available_patches);
         return true;
@@ -550,7 +438,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)          /*{{{*/
 
         if (pdiff_merge == false)
          {
-           new pkgAcqIndexDiffs(Owner, TransactionID, Target, ExpectedHashes, 
+           new pkgAcqIndexDiffs(Owner, TransactionManager, Target, ExpectedHashes, 
                                  MetaIndexParser,
                                  ServerSha1, available_patches);
          }
@@ -559,7 +447,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)          /*{{{*/
            std::vector<pkgAcqIndexMergeDiffs*> *diffs = new std::vector<pkgAcqIndexMergeDiffs*>(available_patches.size());
            for(size_t i = 0; i < available_patches.size(); ++i)
               (*diffs)[i] = new pkgAcqIndexMergeDiffs(Owner,
-                                                       TransactionID,
+                                                       TransactionManager,
                                                        Target,
                                                        ExpectedHashes,
                                                        MetaIndexParser,
@@ -588,7 +476,7 @@ void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig * /*Cnf*/)/
       std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << " with " << Message << std::endl
                << "Falling back to normal index file acquire" << std::endl;
 
-   new pkgAcqIndex(Owner, TransactionID, Target, ExpectedHashes, MetaIndexParser);
+   new pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser);
 
    Complete = false;
    Status = StatDone;
@@ -631,13 +519,13 @@ void pkgAcqDiffIndex::Done(string Message,unsigned long long Size,HashStringList
  * for each diff and the index
  */
 pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
-                                   unsigned long TransactionID,
+                                   pkgAcqMetaBase *TransactionManager,
                                    struct IndexTarget const * const Target,
                                    HashStringList const &ExpectedHashes,
                                    indexRecords *MetaIndexParser,
                                   string ServerSha1,
                                   vector<DiffInfo> diffs)
-   : pkgAcqBaseIndex(Owner, TransactionID, Target, ExpectedHashes, MetaIndexParser),
+   : pkgAcqBaseIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser),
      available_patches(diffs), ServerSha1(ServerSha1)
 {
    
@@ -669,7 +557,7 @@ void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig * /*Cnf*/)
    if(Debug)
       std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << " with " << Message << std::endl
                << "Falling back to normal index file acquire" << std::endl;
-   new pkgAcqIndex(Owner, TransactionID, Target, ExpectedHashes, MetaIndexParser);
+   new pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser);
    Finish();
 }
                                                                        /*}}}*/
@@ -818,7 +706,7 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long long Size, HashStringLi
 
       // see if there is more to download
       if(available_patches.empty() == false) {
-        new pkgAcqIndexDiffs(Owner, TransactionID, Target,
+        new pkgAcqIndexDiffs(Owner, TransactionManager, Target,
                              ExpectedHashes, MetaIndexParser,
                               ServerSha1, available_patches);
         return Finish();
@@ -829,13 +717,13 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long long Size, HashStringLi
                                                                        /*}}}*/
 // AcqIndexMergeDiffs::AcqIndexMergeDiffs - Constructor                        /*{{{*/
 pkgAcqIndexMergeDiffs::pkgAcqIndexMergeDiffs(pkgAcquire *Owner,
-                                             unsigned long TransactionID,
+                                             pkgAcqMetaBase *TransactionManager,
                                              struct IndexTarget const * const Target,
                                              HashStringList const &ExpectedHashes,
                                              indexRecords *MetaIndexParser,
                                              DiffInfo const &patch,
                                              std::vector<pkgAcqIndexMergeDiffs*> const * const allPatches)
-  : pkgAcqBaseIndex(Owner, TransactionID, Target, ExpectedHashes, MetaIndexParser),
+  : pkgAcqBaseIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser),
      patch(patch), allPatches(allPatches), State(StateFetchDiff)
 {
 
@@ -878,7 +766,7 @@ void pkgAcqIndexMergeDiffs::Failed(string Message,pkgAcquire::MethodConfig * /*C
    // first failure means we should fallback
    State = StateErrorDiff;
    std::clog << "Falling back to normal index file acquire" << std::endl;
-   new pkgAcqIndex(Owner, TransactionID, Target, ExpectedHashes, MetaIndexParser);
+   new pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser);
 }
                                                                        /*}}}*/
 void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,HashStringList const &Hashes,  /*{{{*/
@@ -962,25 +850,25 @@ void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,HashStri
    instantiated to fetch the revision file */   
 pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
                         string URI,string URIDesc,string ShortDesc,
-                        HashStringList const  &ExpectedHash, string comprExt)
+                        HashStringList const  &ExpectedHash)
    : pkgAcqBaseIndex(Owner, 0, NULL, ExpectedHash, NULL), RealURI(URI)
 {
    AutoSelectCompression();
    Init(URI, URIDesc, ShortDesc);
 
    if(_config->FindB("Debug::Acquire::Transaction", false) == true)
-      std::clog << "New pkgIndex with TransactionID "
-                << TransactionID << std::endl;
+      std::clog << "New pkgIndex with TransactionManager "
+                << TransactionManager << std::endl;
 }
                                                                        /*}}}*/
 // AcqIndex::AcqIndex - Constructor                                    /*{{{*/
 // ---------------------------------------------------------------------
 pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
-                         unsigned long TransactionID,
+                         pkgAcqMetaBase *TransactionManager,
                          IndexTarget const *Target,
                         HashStringList const &ExpectedHash, 
                          indexRecords *MetaIndexParser)
-   : pkgAcqBaseIndex(Owner, TransactionID, Target, ExpectedHash, 
+   : pkgAcqBaseIndex(Owner, TransactionManager, Target, ExpectedHash, 
                      MetaIndexParser), RealURI(Target->URI)
 {
    // autoselect the compression method
@@ -988,8 +876,8 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
    Init(Target->URI, Target->Description, Target->ShortDesc);
 
    if(_config->FindB("Debug::Acquire::Transaction", false) == true)
-      std::clog << "New pkgIndex with TransactionID "
-                << TransactionID << std::endl;
+      std::clog << "New pkgIndex with TransactionManager "
+                << TransactionManager << std::endl;
 }
                                                                        /*}}}*/
 // AcqIndex::AutoSelectCompression - Select compression                        /*{{{*/
@@ -1128,7 +1016,7 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)    /*{{{*/
    Item::Failed(Message,Cnf);
 
    /// cancel the entire transaction
-   Owner->AbortTransaction(TransactionID);
+   TransactionManager->AbortTransaction();
 }
                                                                        /*}}}*/
 // pkgAcqIndex::GetFinalFilename - Return the full final file path      /*{{{*/
@@ -1147,7 +1035,7 @@ std::string pkgAcqIndex::GetFinalFilename(std::string const &URI,
 // AcqIndex::ReverifyAfterIMS - Reverify index after an ims-hit        /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgAcqIndex::ReverifyAfterIMS(std::string const &FileName)
+void pkgAcqIndex::ReverifyAfterIMS()
 {
    std::string const compExt = CompressionExtension.substr(0, CompressionExtension.find(' '));
    if (_config->FindB("Acquire::GzipIndexes",false) && compExt == "gz")
@@ -1244,7 +1132,7 @@ void pkgAcqIndex::Done(string Message,unsigned long long Size,HashStringList con
       // The files timestamp matches
       if (StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false) == true)
       {
-         ReverifyAfterIMS(FileName);
+         ReverifyAfterIMS();
         return;
       }
       Decompression = true;
@@ -1266,7 +1154,7 @@ void pkgAcqIndex::Done(string Message,unsigned long long Size,HashStringList con
    // The files timestamp matches
    if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
    {
-      ReverifyAfterIMS(FileName);
+      ReverifyAfterIMS();
       return;
     }
 
@@ -1309,16 +1197,16 @@ void pkgAcqIndex::Done(string Message,unsigned long long Size,HashStringList con
 /* The Translation file is added to the queue */
 pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
                            string URI,string URIDesc,string ShortDesc) 
-  : pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashStringList(), "")
+  : pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashStringList())
 {
 }
                                                                        /*}}}*/
 pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner, 
-                                   unsigned long TransactionID
+                                   pkgAcqMetaBase *TransactionManager
                                    IndexTarget const * const Target,
                                    HashStringList const &ExpectedHashes, 
                                    indexRecords *MetaIndexParser)
-   : pkgAcqIndex(Owner, TransactionID, Target, ExpectedHashes, MetaIndexParser)
+   : pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser)
 {
    // load the filesize
    indexRecords::checkSum *Record = MetaIndexParser->Lookup(string(Target->MetaKey));
@@ -1367,13 +1255,111 @@ void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
    Item::Failed(Message,Cnf);
 }
                                                                        /*}}}*/
+
+void pkgAcqMetaBase::Add(Item *I)
+{
+   Transaction.push_back(I);
+}
+
+void pkgAcqMetaBase::AbortTransaction()
+{
+   if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+      std::clog << "AbortTransaction: " << TransactionManager << std::endl;
+
+   for (std::vector<Item*>::iterator I = Transaction.begin();
+        I != Transaction.end(); ++I)
+   {
+      if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+         std::clog << "  Cancel: " << (*I)->DestFile << std::endl;
+      // the transaction will abort, so stop anything that is idle
+      if ((*I)->Status == pkgAcquire::Item::StatIdle)
+         (*I)->Status = pkgAcquire::Item::StatDone;
+   }
+}
+                                                                       /*}}}*/
+bool pkgAcqMetaBase::TransactionHasError()
+{
+   for (pkgAcquire::ItemIterator I = Transaction.begin();
+        I != Transaction.end(); ++I)
+      if((*I)->Status != pkgAcquire::Item::StatDone &&
+         (*I)->Status != pkgAcquire::Item::StatIdle)
+         return true;
+
+   return false;
+}
+// Acquire::CommitTransaction - Commit a transaction                   /*{{{*/
+void pkgAcqMetaBase::CommitTransaction()
+{
+   if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+      std::clog << "CommitTransaction: " << this << std::endl;
+
+   // move new files into place *and* remove files that are not
+   // part of the transaction but are still on disk
+   for (std::vector<Item*>::iterator I = Transaction.begin();
+        I != Transaction.end(); ++I)
+   {
+      if((*I)->PartialFile != "")
+      {
+         if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+            std::clog << "mv " 
+                      << (*I)->PartialFile << " -> " 
+                      <<  (*I)->DestFile << std::endl;
+         Rename((*I)->PartialFile, (*I)->DestFile);
+         chmod((*I)->DestFile.c_str(),0644);
+      } else {
+         if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+            std::clog << "rm " 
+                      <<  (*I)->DestFile << std::endl;
+         unlink((*I)->DestFile.c_str());
+      }
+      // mark that this transaction is finished
+      (*I)->TransactionManager = 0;
+   }
+}
+
+                                                                       /*{{{*/
+bool pkgAcqMetaBase::GenerateAuthWarning(const std::string &RealURI,
+                                         const std::string &Message)
+{
+   string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
+   
+   if(FileExists(Final))
+   {
+      Status = StatTransientNetworkError;
+      _error->Warning(_("An error occurred during the signature "
+                        "verification. The repository is not updated "
+                        "and the previous index files will be used. "
+                        "GPG error: %s: %s\n"),
+                      Desc.Description.c_str(),
+                      LookupTag(Message,"Message").c_str());
+      RunScripts("APT::Update::Auth-Failure");
+      return true;
+   } else if (LookupTag(Message,"Message").find("NODATA") != string::npos) {
+      /* Invalid signature file, reject (LP: #346386) (Closes: #627642) */
+      _error->Error(_("GPG error: %s: %s"),
+                    Desc.Description.c_str(),
+                    LookupTag(Message,"Message").c_str());
+      Status = StatError;
+      return true;
+   } else {
+      _error->Warning(_("GPG error: %s: %s"),
+                      Desc.Description.c_str(),
+                      LookupTag(Message,"Message").c_str());
+   }
+   // gpgv method failed 
+   ReportMirrorFailure("GPGFailure");
+   return false;
+}
+                                                                       /*}}}*/
+
+
 pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,                        /*{{{*/
-                             unsigned long TransactionID,
+                             pkgAcqMetaBase *TransactionManager,
                             string URI,string URIDesc,string ShortDesc,
                              string MetaIndexFile,
                             const vector<IndexTarget*>* IndexTargets,
                             indexRecords* MetaIndexParser) :
-   Item(Owner, HashStringList(), TransactionID), RealURI(URI), 
+   pkgAcqMetaBase(Owner, HashStringList(), TransactionManager), RealURI(URI), 
    MetaIndexParser(MetaIndexParser), MetaIndexFile(MetaIndexFile),
    IndexTargets(IndexTargets), AuthPass(false), IMSHit(false)
 {
@@ -1385,10 +1371,10 @@ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,                         /*{{{*/
    // partial download anyway
    unlink(DestFile.c_str());
 
-   // set the TransactionID
+   // set the TransactionManager
    if(_config->FindB("Debug::Acquire::Transaction", false) == true)
-      std::clog << "New pkgAcqMetaSig with TransactionID "
-                << TransactionID << std::endl;
+      std::clog << "New pkgAcqMetaSig with TransactionManager "
+                << TransactionManager << std::endl;
 
    // Create the item
    Desc.Description = URIDesc;
@@ -1490,31 +1476,9 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/
    // FIXME: duplicated code from pkgAcqMetaIndex
    if (AuthPass == true)
    {
-      if(FileExists(Final))
-      {
-        Status = StatTransientNetworkError;
-        _error->Warning(_("An error occurred during the signature "
-                          "verification. The repository is not updated "
-                          "and the previous index files will be used. "
-                          "GPG error: %s: %s\n"),
-                        Desc.Description.c_str(),
-                        LookupTag(Message,"Message").c_str());
-        RunScripts("APT::Update::Auth-Failure");
-        return;
-      } else if (LookupTag(Message,"Message").find("NODATA") != string::npos) {
-        /* Invalid signature file, reject (LP: #346386) (Closes: #627642) */
-        _error->Error(_("GPG error: %s: %s"),
-                        Desc.Description.c_str(),
-                        LookupTag(Message,"Message").c_str());
-         Status = StatError;
-        return;
-      } else {
-        _error->Warning(_("GPG error: %s: %s"),
-                        Desc.Description.c_str(),
-                        LookupTag(Message,"Message").c_str());
-      }
-      // gpgv method failed 
-      ReportMirrorFailure("GPGFailure");
+      bool Stop = GenerateAuthWarning(RealURI, Message);
+      if(Stop)
+         return;
    }
 
    // FIXME: this is used often (e.g. in pkgAcqIndexTrans) so refactor
@@ -1531,22 +1495,26 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/
 }
                                                                        /*}}}*/
 pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner,                    /*{{{*/
-                                 unsigned long TransactionID,
+                                 pkgAcqMetaBase *TransactionManager,
                                 string URI,string URIDesc,string ShortDesc,
                                  string MetaIndexSigURI,string MetaIndexSigURIDesc, string MetaIndexSigShortDesc,
                                 const vector<IndexTarget*>* IndexTargets,
                                 indexRecords* MetaIndexParser) :
-   Item(Owner, HashStringList(), TransactionID), RealURI(URI), IndexTargets(IndexTargets),
+   pkgAcqMetaBase(Owner, HashStringList(), TransactionManager), RealURI(URI), IndexTargets(IndexTargets),
    MetaIndexParser(MetaIndexParser), AuthPass(false), IMSHit(false),
    MetaIndexSigURI(MetaIndexSigURI), MetaIndexSigURIDesc(MetaIndexSigURIDesc),
    MetaIndexSigShortDesc(MetaIndexSigShortDesc)
 {
-   if(TransactionID == 0)
-      this->TransactionID = (unsigned long)this;
+   if(TransactionManager == NULL)
+   {
+      this->TransactionManager = this;
+      this->TransactionManager->Add(this);
+   }
 
    if(_config->FindB("Debug::Acquire::Transaction", false) == true)
-      std::clog << "New pkgAcqMetaIndex with TransactionID "
-                << TransactionID << std::endl;
+      std::clog << "New pkgAcqMetaIndex with TransactionManager "
+                << this->TransactionManager << std::endl;
+
 
    Init(URIDesc, ShortDesc);
 }
@@ -1681,7 +1649,7 @@ void pkgAcqMetaIndex::RetrievalDone(string Message)                       /*{{{*/
 
    // queue a signature
    if(SigFile != DestFile)
-      new pkgAcqMetaSig(Owner, TransactionID
+      new pkgAcqMetaSig(Owner, TransactionManager
                         MetaIndexSigURI, MetaIndexSigURIDesc,
                         MetaIndexSigShortDesc, DestFile, IndexTargets, 
                         MetaIndexParser);
@@ -1791,17 +1759,13 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)                         /*{{{*/
 
       if ((*Target)->IsOptional() == true)
       {
-        if ((*Target)->IsSubIndex() == true)
-           new pkgAcqSubIndex(Owner, TransactionID, 
-                               (*Target)->URI, (*Target)->Description,
-                               (*Target)->ShortDesc, ExpectedIndexHashes);
-        else if (transInRelease == false || Record != NULL || compressedAvailable == true)
+        if (transInRelease == false || Record != NULL || compressedAvailable == true)
         {
            if (_config->FindB("Acquire::PDiffs",true) == true && transInRelease == true &&
                MetaIndexParser->Exists((*Target)->MetaKey + ".diff/Index") == true)
-              new pkgAcqDiffIndex(Owner, TransactionID, *Target, ExpectedIndexHashes, MetaIndexParser);
+              new pkgAcqDiffIndex(Owner, TransactionManager, *Target, ExpectedIndexHashes, MetaIndexParser);
            else
-              new pkgAcqIndexTrans(Owner, TransactionID, *Target, ExpectedIndexHashes, MetaIndexParser);
+              new pkgAcqIndexTrans(Owner, TransactionManager, *Target, ExpectedIndexHashes, MetaIndexParser);
         }
         continue;
       }
@@ -1812,9 +1776,9 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)                           /*{{{*/
          instead, but passing the required info to it is to much hassle */
       if(_config->FindB("Acquire::PDiffs",true) == true && (verify == false ||
          MetaIndexParser->Exists((*Target)->MetaKey + ".diff/Index") == true))
-        new pkgAcqDiffIndex(Owner, TransactionID, *Target, ExpectedIndexHashes, MetaIndexParser);
+        new pkgAcqDiffIndex(Owner, TransactionManager, *Target, ExpectedIndexHashes, MetaIndexParser);
       else
-        new pkgAcqIndex(Owner, TransactionID, *Target, ExpectedIndexHashes, MetaIndexParser);
+        new pkgAcqIndex(Owner, TransactionManager, *Target, ExpectedIndexHashes, MetaIndexParser);
    }
 }
                                                                        /*}}}*/
@@ -1905,31 +1869,9 @@ void pkgAcqMetaIndex::Failed(string Message,
 
    if (AuthPass == true)
    {
-      if(FileExists(Final))
-      {
-        Status = StatTransientNetworkError;
-        _error->Warning(_("An error occurred during the signature "
-                          "verification. The repository is not updated "
-                          "and the previous index files will be used. "
-                          "GPG error: %s: %s\n"),
-                        Desc.Description.c_str(),
-                        LookupTag(Message,"Message").c_str());
-        RunScripts("APT::Update::Auth-Failure");
-        return;
-      } else if (LookupTag(Message,"Message").find("NODATA") != string::npos) {
-        /* Invalid signature file, reject (LP: #346386) (Closes: #627642) */
-        _error->Error(_("GPG error: %s: %s"),
-                        Desc.Description.c_str(),
-                        LookupTag(Message,"Message").c_str());
-         Status = StatError;
-        return;
-      } else {
-        _error->Warning(_("GPG error: %s: %s"),
-                        Desc.Description.c_str(),
-                        LookupTag(Message,"Message").c_str());
-      }
-      // gpgv method failed 
-      ReportMirrorFailure("GPGFailure");
+      bool Stop = GenerateAuthWarning(RealURI, Message);
+      if(Stop)
+         return;
    }
 
    /* Always move the meta index, even if gpgv failed. This ensures
@@ -1962,9 +1904,9 @@ void pkgAcqMetaIndex::Finished()
 {
    if(_config->FindB("Debug::Acquire::Transaction", false) == true)
       std::clog << "Finished: " << DestFile <<std::endl;
-   if(Owner->TransactionHasError(TransactionID) == false && 
-      TransactionID > 0)
-      Owner->CommitTransaction(TransactionID);
+   if(TransactionManager != NULL &&
+      TransactionManager->TransactionHasError() == false)
+      TransactionManager->CommitTransaction();
 }
 
 
@@ -1974,7 +1916,7 @@ pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire *Owner,         /*{{{*/
                string const &MetaSigURI, string const &MetaSigURIDesc, string const &MetaSigShortDesc,
                const vector<IndexTarget*>* IndexTargets,
                indexRecords* MetaIndexParser) :
-   pkgAcqMetaIndex(Owner, (unsigned long)this, URI, URIDesc, ShortDesc, MetaSigURI, MetaSigURIDesc,MetaSigShortDesc, IndexTargets, MetaIndexParser),
+   pkgAcqMetaIndex(Owner, NULL, URI, URIDesc, ShortDesc, MetaSigURI, MetaSigURIDesc,MetaSigShortDesc, IndexTargets, MetaIndexParser),
        MetaIndexURI(MetaIndexURI), MetaIndexURIDesc(MetaIndexURIDesc), MetaIndexShortDesc(MetaIndexShortDesc),
        MetaSigURI(MetaSigURI), MetaSigURIDesc(MetaSigURIDesc), MetaSigShortDesc(MetaSigShortDesc)
 {
@@ -2059,7 +2001,7 @@ void pkgAcqMetaClearSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*
       PartialFile = "";
       DestFile = FinalFile;
 
-      new pkgAcqMetaIndex(Owner, TransactionID,
+      new pkgAcqMetaIndex(Owner, TransactionManager,
                        MetaIndexURI, MetaIndexURIDesc, MetaIndexShortDesc,
                        MetaSigURI, MetaSigURIDesc, MetaSigShortDesc,
                        IndexTargets, MetaIndexParser);