]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/acquire-item.cc
add pkgAcquire::TransactionHasError()
[apt.git] / apt-pkg / acquire-item.cc
index 1f3d839418aa6114f96d701a91c282f006bd7ecd..81afdf4b17f3b53b8506812048ba2ec25bdc9679 100644 (file)
@@ -66,7 +66,7 @@ static void printHashSumComparision(std::string const &URI, HashStringList const
 // Acquire::Item::Item - Constructor                                   /*{{{*/
 pkgAcquire::Item::Item(pkgAcquire *Owner, HashStringList const &ExpectedHashes) :
    Owner(Owner), FileSize(0), PartialSize(0), Mode(0), ID(0), Complete(false),
-   Local(false), QueueCounter(0), ExpectedAdditionalItems(0),
+   Local(false), QueueCounter(0), TransactionID(0), ExpectedAdditionalItems(0),
    ExpectedHashes(ExpectedHashes)
 {
    Owner->Add(this);
@@ -353,11 +353,12 @@ bool pkgAcqSubIndex::ParseIndex(string const &IndexFile)          /*{{{*/
  * patches. If anything goes wrong in that process, it will fall back to
  * the original packages file
  */
-pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
+pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcqMetaIndex *MetaOwner,
                                  IndexTarget const * const Target,
                                 HashStringList const &ExpectedHashes,
                                  indexRecords *MetaIndexParser)
-   : pkgAcqBaseIndex(Owner, Target, ExpectedHashes, MetaIndexParser)
+   : pkgAcqBaseIndex(MetaOwner, Target, ExpectedHashes, 
+                     MetaIndexParser)
 {
    
    Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
@@ -455,7 +456,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, Target, ExpectedHashes, MetaIndexParser, 
+        new pkgAcqIndexDiffs(MetaOwner, Target, ExpectedHashes, MetaIndexParser, 
                               ServerSha1, available_patches);
         return true;
       }
@@ -542,14 +543,14 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)                /*{{{*/
 
         if (pdiff_merge == false)
          {
-           new pkgAcqIndexDiffs(Owner, Target, ExpectedHashes, MetaIndexParser,
+           new pkgAcqIndexDiffs(MetaOwner, Target, ExpectedHashes, MetaIndexParser,
                                  ServerSha1, available_patches);
          }
          else
         {
            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, Target,
+              (*diffs)[i] = new pkgAcqIndexMergeDiffs(MetaOwner, Target,
                                                        ExpectedHashes,
                                                        MetaIndexParser,
                                                        available_patches[i],
@@ -577,7 +578,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, Target, ExpectedHashes, MetaIndexParser);
+   new pkgAcqIndex(MetaOwner, Target, ExpectedHashes, MetaIndexParser);
 
    Complete = false;
    Status = StatDone;
@@ -619,13 +620,13 @@ void pkgAcqDiffIndex::Done(string Message,unsigned long long Size,HashStringList
 /* The package diff is added to the queue. one object is constructed
  * for each diff and the index
  */
-pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
+pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcqMetaIndex *MetaOwner,
                                    struct IndexTarget const * const Target,
                                    HashStringList const &ExpectedHashes,
                                    indexRecords *MetaIndexParser,
                                   string ServerSha1,
                                   vector<DiffInfo> diffs)
-   : pkgAcqBaseIndex(Owner, Target, ExpectedHashes, MetaIndexParser),
+   : pkgAcqBaseIndex(MetaOwner, Target, ExpectedHashes, MetaIndexParser),
      available_patches(diffs), ServerSha1(ServerSha1)
 {
    
@@ -657,7 +658,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, Target, ExpectedHashes, MetaIndexParser);
+   new pkgAcqIndex(MetaOwner, Target, ExpectedHashes, MetaIndexParser);
    Finish();
 }
                                                                        /*}}}*/
@@ -797,7 +798,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, Target,
+        new pkgAcqIndexDiffs(MetaOwner, Target,
                              ExpectedHashes, MetaIndexParser,
                               ServerSha1, available_patches);
         return Finish();
@@ -807,13 +808,13 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long long Size, HashStringLi
 }
                                                                        /*}}}*/
 // AcqIndexMergeDiffs::AcqIndexMergeDiffs - Constructor                        /*{{{*/
-pkgAcqIndexMergeDiffs::pkgAcqIndexMergeDiffs(pkgAcquire *Owner,
+pkgAcqIndexMergeDiffs::pkgAcqIndexMergeDiffs(pkgAcqMetaIndex *MetaOwner,
                                              struct IndexTarget const * const Target,
                                              HashStringList const &ExpectedHashes,
                                              indexRecords *MetaIndexParser,
                                              DiffInfo const &patch,
                                              std::vector<pkgAcqIndexMergeDiffs*> const * const allPatches)
-   : pkgAcqBaseIndex(Owner, Target, ExpectedHashes, MetaIndexParser),
+   : pkgAcqBaseIndex(MetaOwner, Target, ExpectedHashes, MetaIndexParser),
      patch(patch), allPatches(allPatches), State(StateFetchDiff)
 {
 
@@ -856,7 +857,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, Target, ExpectedHashes, MetaIndexParser);
+   new pkgAcqIndex(MetaOwner, Target, ExpectedHashes, MetaIndexParser);
 }
                                                                        /*}}}*/
 void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,HashStringList const &Hashes,  /*{{{*/
@@ -952,10 +953,9 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
    }
    CompressionExtension = comprExt;
 
-   Verify = true;
-
    Init(URI, URIDesc, ShortDesc);
 }
+#if 0
 pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, IndexTarget const *Target,
                         HashStringList const &ExpectedHash, 
                          indexRecords *MetaIndexParser)
@@ -963,6 +963,27 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, IndexTarget const *Target,
      RealURI(Target->URI)
 {
    // autoselect the compression method
+   AutoSelectCompression();
+   Init(Target->URI, Target->Description, Target->ShortDesc);
+}
+#endif
+                                                                       /*}}}*/
+pkgAcqIndex::pkgAcqIndex(pkgAcqMetaIndex *MetaOwner,
+                         IndexTarget const *Target,
+                        HashStringList const &ExpectedHash, 
+                         indexRecords *MetaIndexParser)
+   : pkgAcqBaseIndex(MetaOwner->GetOwner(), Target, ExpectedHash, 
+                     MetaIndexParser), RealURI(Target->URI)
+{
+   // autoselect the compression method
+   AutoSelectCompression();
+   Init(Target->URI, Target->Description, Target->ShortDesc);
+
+   TransactionID = (unsigned long)MetaOwner;
+}
+                                                                       /*}}}*/
+void pkgAcqIndex::AutoSelectCompression()
+{
    std::vector<std::string> types = APT::Configuration::getCompressionTypes();
    CompressionExtension = "";
    if (ExpectedHashes.usable())
@@ -978,17 +999,7 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, IndexTarget const *Target,
    }
    if (CompressionExtension.empty() == false)
       CompressionExtension.erase(CompressionExtension.end()-1);
-
-   // only verify non-optional targets, see acquire-item.h for a FIXME
-   // to make this more flexible
-   if (Target->IsOptional())
-     Verify = false;
-   else
-     Verify = true;
-
-   Init(Target->URI, Target->Description, Target->ShortDesc);
 }
-                                                                       /*}}}*/
 // AcqIndex::Init - defered Constructor                                        /*{{{*/
 void pkgAcqIndex::Init(string const &URI, string const &URIDesc, string const &ShortDesc) {
    Decompression = false;
@@ -1018,34 +1029,47 @@ void pkgAcqIndex::Init(string const &URI, string const &URIDesc, string const &S
       indexRecords::checkSum *Record = MetaIndexParser->Lookup(MetaKey);
       if(Record)
          FileSize = Record->Size;
+      
+      InitByHashIfNeeded(MetaKey);
    }
 
-   // do the request by-hash
-   if(_config->FindB("APT::Acquire::By-Hash", false) == true &&
-      MetaIndexParser)
+   Desc.Description = URIDesc;
+   Desc.Owner = this;
+   Desc.ShortDesc = ShortDesc;
+
+   QueueURI(Desc);
+}
+                                                                       /*}}}*/
+// AcqIndex::AdjustForByHash - modify URI for by-hash support          /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void pkgAcqIndex::InitByHashIfNeeded(const std::string MetaKey)
+{
+   // TODO:
+   //  - (maybe?) add support for by-hash into the sources.list as flag
+   //  - make apt-ftparchive generate the hashes (and expire?)
+   std::string HostKnob = "APT::Acquire::" + ::URI(Desc.URI).Host + "::By-Hash";
+   if(_config->FindB("APT::Acquire::By-Hash", false) == true ||
+      _config->FindB(HostKnob, false) == true ||
+      MetaIndexParser->GetSupportsAcquireByHash())
    {
       indexRecords::checkSum *Record = MetaIndexParser->Lookup(MetaKey);
       if(Record)
       {
-         // FIXME: make the hash used a config option or read from release file
-         const HashString *TargetHash = Record->Hashes.find("SHA256");
-         std::string ByHash = "/by-hash/" + TargetHash->HashValue();
+         // FIXME: should we really use the best hash here? or a fixed one?
+         const HashString *TargetHash = Record->Hashes.find("");
+         std::string ByHash = "/by-hash/" + TargetHash->HashType() + "/" + TargetHash->HashValue();
          size_t trailing_slash = Desc.URI.find_last_of("/");
-         Desc.URI = Desc.URI.replace(trailing_slash,
-                                     Desc.URI.substr(trailing_slash+1).size()+1,
-                                     ByHash);
-         std::cerr << Desc.URI << std::endl;
+         Desc.URI = Desc.URI.replace(
+            trailing_slash,
+            Desc.URI.substr(trailing_slash+1).size()+1,
+            ByHash);
       } else {
-         _error->Warning("By-Hash requested but can not find record for %s",
-                         MetaKey.c_str());
+         _error->Warning(
+            "Fetching ByHash requested but can not find record for %s",
+            MetaKey.c_str());
       }
    }
-
-   Desc.Description = URIDesc;
-   Desc.Owner = this;
-   Desc.ShortDesc = ShortDesc;
-
-   QueueURI(Desc);
 }
                                                                        /*}}}*/
 // AcqIndex::Custom600Headers - Insert custom request headers          /*{{{*/
@@ -1088,6 +1112,9 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)    /*{{{*/
    }
 
    Item::Failed(Message,Cnf);
+
+   /// cancel the entire transaction
+   Owner->AbortTransaction(TransactionID);
 }
                                                                        /*}}}*/
 // AcqIndex::Done - Finished a fetch                                   /*{{{*/
@@ -1108,35 +1135,39 @@ void pkgAcqIndex::Done(string Message,unsigned long long Size,HashStringList con
       {
         RenameOnError(HashSumMismatch);
         printHashSumComparision(RealURI, ExpectedHashes, Hashes);
+         Failed(Message, Cfg);
          return;
       }
 
-      /* Verify the index file for correctness (all indexes must
-       * have a Package field) (LP: #346386) (Closes: #627642) */
-      if (Verify == true)
+      // FIXME: this can go away once we only ever download stuff that
+      //        has a valid hash and we never do GET based probing
+      //
+      /* Always verify the index file for correctness (all indexes must
+       * have a Package field) (LP: #346386) (Closes: #627642) 
+       */
+      FileFd fd(DestFile, FileFd::ReadOnly);
+      // Only test for correctness if the file is not empty (empty is ok)
+      if (fd.FileSize() > 0)
       {
-        FileFd fd(DestFile, FileFd::ReadOnly);
-        // Only test for correctness if the file is not empty (empty is ok)
-        if (fd.FileSize() > 0)
-        {
-           pkgTagSection sec;
-           pkgTagFile tag(&fd);
-
-           // all our current indexes have a field 'Package' in each section
-           if (_error->PendingError() == true || tag.Step(sec) == false || sec.Exists("Package") == false)
-           {
-              RenameOnError(InvalidFormat);
-              return;
-           }
+         pkgTagSection sec;
+         pkgTagFile tag(&fd);
+         
+         // all our current indexes have a field 'Package' in each section
+         if (_error->PendingError() == true || tag.Step(sec) == false || sec.Exists("Package") == false)
+         {
+            RenameOnError(InvalidFormat);
+            Failed(Message, Cfg);
+            return;
          }
       }
        
-      // Done, move it into position
+      // Done, queue for rename on transaction finished
+      PartialFile = DestFile;
+
       string FinalFile = _config->FindDir("Dir::State::lists");
       FinalFile += URItoFileName(RealURI);
-      Rename(DestFile,FinalFile);
-      chmod(FinalFile.c_str(),0644);
-
+      DestFile = FinalFile;
+#if 0
       /* We restore the original name to DestFile so that the clean operation
          will work OK */
       DestFile = _config->FindDir("Dir::State::lists") + "partial/";
@@ -1145,7 +1176,7 @@ void pkgAcqIndex::Done(string Message,unsigned long long Size,HashStringList con
       // Remove the compressed version.
       if (Erase == true)
         unlink(DestFile.c_str());
-
+#endif
       return;
    }
 
@@ -1232,9 +1263,10 @@ pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
   : pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashStringList(), "")
 {
 }
-pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner, IndexTarget const * const Target,
+                                                                       /*}}}*/
+pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcqMetaIndex *MetaOwner, IndexTarget const * const Target,
                         HashStringList const &ExpectedHashes, indexRecords *MetaIndexParser)
-  : pkgAcqIndex(Owner, Target, ExpectedHashes, MetaIndexParser)
+  : pkgAcqIndex(MetaOwner, Target, ExpectedHashes, MetaIndexParser)
 {
    // load the filesize
    indexRecords::checkSum *Record = MetaIndexParser->Lookup(string(Target->MetaKey));
@@ -1383,11 +1415,18 @@ void pkgAcqMetaSig::Done(string Message,unsigned long long Size, HashStringList
    if(StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
       Rename(LastGoodSig, DestFile);
 
+   // queue for copy
+   PartialFile = DestFile;
+   DestFile = _config->FindDir("Dir::State::lists");
+   DestFile += URItoFileName(RealURI);
+
    // queue a pkgAcqMetaIndex to be verified against the sig we just retrieved
-   new pkgAcqMetaIndex(Owner, MetaIndexURI, MetaIndexURIDesc, 
-                      MetaIndexShortDesc,  DestFile, IndexTargets, 
-                      MetaIndexParser);
+   pkgAcqMetaIndex *metaindex = new pkgAcqMetaIndex(
+      Owner, MetaIndexURI, MetaIndexURIDesc, 
+      MetaIndexShortDesc,  DestFile, IndexTargets, 
+      MetaIndexParser);
 
+   TransactionID = (unsigned long)metaindex;
 }
                                                                        /*}}}*/
 void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/
@@ -1441,6 +1480,8 @@ pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner,                       /*{{{*/
    DestFile = _config->FindDir("Dir::State::lists") + "partial/";
    DestFile += URItoFileName(URI);
 
+   TransactionID = (unsigned long)this;
+
    // Create the item
    Desc.Description = URIDesc;
    Desc.Owner = this;
@@ -1531,8 +1572,7 @@ void pkgAcqMetaIndex::Done(string Message,unsigned long long Size,HashStringList
       FinalFile += URItoFileName(RealURI);
       if (SigFile == DestFile)
         SigFile = FinalFile;
-      Rename(DestFile,FinalFile);
-      chmod(FinalFile.c_str(),0644);
+      PartialFile = DestFile;
       DestFile = FinalFile;
    }
 }
@@ -1604,6 +1644,7 @@ void pkgAcqMetaIndex::AuthDone(string Message)                            /*{{{*/
    // Download further indexes with verification
    QueueIndexes(true);
 
+#if 0
    // is it a clearsigned MetaIndex file?
    if (DestFile == SigFile)
       return;
@@ -1613,6 +1654,7 @@ void pkgAcqMetaIndex::AuthDone(string Message)                            /*{{{*/
       URItoFileName(RealURI) + ".gpg";
    Rename(SigFile,VerifiedSigFile);
    chmod(VerifiedSigFile.c_str(),0644);
+#endif
 }
                                                                        /*}}}*/
 void pkgAcqMetaIndex::QueueIndexes(bool verify)                                /*{{{*/
@@ -1641,7 +1683,6 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)                           /*{{{*/
 
    // at this point the real Items are loaded in the fetcher
    ExpectedAdditionalItems = 0;
-
    for (vector <IndexTarget*>::const_iterator Target = IndexTargets->begin();
         Target != IndexTargets->end();
         ++Target)
@@ -1696,9 +1737,9 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)                           /*{{{*/
         {
            if (_config->FindB("Acquire::PDiffs",true) == true && transInRelease == true &&
                MetaIndexParser->Exists((*Target)->MetaKey + ".diff/Index") == true)
-              new pkgAcqDiffIndex(Owner, *Target, ExpectedIndexHashes, MetaIndexParser);
+              new pkgAcqDiffIndex(this, *Target, ExpectedIndexHashes, MetaIndexParser);
            else
-              new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHashes, MetaIndexParser);
+              new pkgAcqIndexTrans(this, *Target, ExpectedIndexHashes, MetaIndexParser);
         }
         continue;
       }
@@ -1709,9 +1750,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, *Target, ExpectedIndexHashes, MetaIndexParser);
+        new pkgAcqDiffIndex(this, *Target, ExpectedIndexHashes, MetaIndexParser);
       else
-        new pkgAcqIndex(Owner, *Target, ExpectedIndexHashes, MetaIndexParser);
+        new pkgAcqIndex(this, *Target, ExpectedIndexHashes, MetaIndexParser);
    }
 }
                                                                        /*}}}*/
@@ -1795,8 +1836,10 @@ bool pkgAcqMetaIndex::VerifyVendor(string Message)                       /*{{{*/
 // pkgAcqMetaIndex::Failed - no Release file present or no signature file present      /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig * /*Cnf*/)
+void pkgAcqMetaIndex::Failed(string /*Message*/,
+                             pkgAcquire::MethodConfig * /*Cnf*/)
 {
+#if 0
    if (AuthPass == true)
    {
       // gpgv method failed, if we have a good signature 
@@ -1834,7 +1877,7 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig * /*Cnf*/)
       // gpgv method failed 
       ReportMirrorFailure("GPGFailure");
    }
-
+#endif
    /* Always move the meta index, even if gpgv failed. This ensures
     * that PackageFile objects are correctly filled in */
    if (FileExists(DestFile)) {
@@ -1860,6 +1903,16 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig * /*Cnf*/)
    QueueIndexes(false);
 }
                                                                        /*}}}*/
+
+void pkgAcqMetaIndex::Finished()
+{
+   if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+      std::clog << "Finished: " << DestFile <<std::endl;
+   if(Owner->TransactionHasError((unsigned long)this) == false)
+      Owner->CommitTransaction((unsigned long)this);
+}
+
+
 pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire *Owner,              /*{{{*/
                string const &URI, string const &URIDesc, string const &ShortDesc,
                string const &MetaIndexURI, string const &MetaIndexURIDesc, string const &MetaIndexShortDesc,