]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/acquire-item.cc
support .deb files in upgrade operations as well
[apt.git] / apt-pkg / acquire-item.cc
index 1b76f1b7acb2de624fca6ae8b3dc409f0058091e..98739f7a6a4b73e8561463e98d2ec71eaef8a43b 100644 (file)
@@ -999,6 +999,10 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify)                       /*{{{*/
    // at this point the real Items are loaded in the fetcher
    ExpectedAdditionalItems = 0;
 
+  bool metaBaseSupportsByHash = false;
+  if (TransactionManager != NULL && TransactionManager->MetaIndexParser != NULL)
+     metaBaseSupportsByHash = TransactionManager->MetaIndexParser->GetSupportsAcquireByHash();
+
    for (std::vector <IndexTarget>::iterator Target = IndexTargets.begin();
         Target != IndexTargets.end();
         ++Target)
@@ -1028,6 +1032,15 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify)                     /*{{{*/
         if (types.empty() == false)
         {
            std::ostringstream os;
+           // add the special compressiontype byhash first if supported
+           std::string const useByHashConf = Target->Option(IndexTarget::BY_HASH);
+           bool useByHash = false;
+           if(useByHashConf == "force")
+              useByHash = true;
+           else
+              useByHash = StringToBool(useByHashConf) == true && metaBaseSupportsByHash;
+           if (useByHash == true)
+              os << "by-hash ";
            std::copy(types.begin(), types.end()-1, std::ostream_iterator<std::string>(os, " "));
            os << *types.rbegin();
            Target->Options["COMPRESSIONTYPES"] = os.str();
@@ -2437,29 +2450,58 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire * const Owner,
 }
                                                                        /*}}}*/
 // AcqIndex::Init - defered Constructor                                        /*{{{*/
-void pkgAcqIndex::Init(string const &URI, string const &URIDesc,
-                       string const &ShortDesc)
+static void NextCompressionExtension(std::string &CurrentCompressionExtension, std::string &CompressionExtensions, bool const preview)
 {
-   Stage = STAGE_DOWNLOAD;
-
-   DestFile = GetPartialFileNameFromURI(URI);
-
    size_t const nextExt = CompressionExtensions.find(' ');
    if (nextExt == std::string::npos)
    {
       CurrentCompressionExtension = CompressionExtensions;
-      CompressionExtensions.clear();
+      if (preview == false)
+        CompressionExtensions.clear();
    }
    else
    {
       CurrentCompressionExtension = CompressionExtensions.substr(0, nextExt);
-      CompressionExtensions = CompressionExtensions.substr(nextExt+1);
+      if (preview == false)
+        CompressionExtensions = CompressionExtensions.substr(nextExt+1);
    }
+}
+void pkgAcqIndex::Init(string const &URI, string const &URIDesc,
+                       string const &ShortDesc)
+{
+   Stage = STAGE_DOWNLOAD;
+
+   DestFile = GetPartialFileNameFromURI(URI);
+   NextCompressionExtension(CurrentCompressionExtension, CompressionExtensions, false);
 
    if (CurrentCompressionExtension == "uncompressed")
    {
       Desc.URI = URI;
    }
+   else if (CurrentCompressionExtension == "by-hash")
+   {
+      NextCompressionExtension(CurrentCompressionExtension, CompressionExtensions, true);
+      if(unlikely(TransactionManager->MetaIndexParser == NULL || CurrentCompressionExtension.empty()))
+        return;
+      if (CurrentCompressionExtension != "uncompressed")
+      {
+        Desc.URI = URI + '.' + CurrentCompressionExtension;
+        DestFile = DestFile + '.' + CurrentCompressionExtension;
+      }
+
+      HashStringList const Hashes = GetExpectedHashes();
+      HashString const * const TargetHash = Hashes.find(NULL);
+      if (unlikely(TargetHash == nullptr))
+        return;
+      std::string const ByHash = "/by-hash/" + TargetHash->HashType() + "/" + TargetHash->HashValue();
+      size_t const trailing_slash = Desc.URI.find_last_of("/");
+      if (unlikely(trailing_slash == std::string::npos))
+        return;
+      Desc.URI = Desc.URI.replace(
+           trailing_slash,
+           Desc.URI.substr(trailing_slash+1).size()+1,
+           ByHash);
+   }
    else if (unlikely(CurrentCompressionExtension.empty()))
       return;
    else
@@ -2468,8 +2510,6 @@ void pkgAcqIndex::Init(string const &URI, string const &URIDesc,
       DestFile = DestFile + '.' + CurrentCompressionExtension;
    }
 
-   if(TransactionManager->MetaIndexParser != NULL)
-      InitByHashIfNeeded();
 
    Desc.Description = URIDesc;
    Desc.Owner = this;
@@ -2478,32 +2518,6 @@ void pkgAcqIndex::Init(string const &URI, string const &URIDesc,
    QueueURI(Desc);
 }
                                                                        /*}}}*/
-// AcqIndex::AdjustForByHash - modify URI for by-hash support          /*{{{*/
-void pkgAcqIndex::InitByHashIfNeeded()
-{
-   std::string const useByHash = Target.Option(IndexTarget::BY_HASH);
-   if(useByHash == "force" || (StringToBool(useByHash) == true &&
-           TransactionManager->MetaIndexParser->GetSupportsAcquireByHash()))
-   {
-      HashStringList const Hashes = GetExpectedHashes();
-      if(Hashes.usable())
-      {
-         // FIXME: should we really use the best hash here? or a fixed one?
-         HashString const * const TargetHash = Hashes.find("");
-         std::string const ByHash = "/by-hash/" + TargetHash->HashType() + "/" + TargetHash->HashValue();
-         size_t const trailing_slash = Desc.URI.find_last_of("/");
-         Desc.URI = Desc.URI.replace(
-            trailing_slash,
-            Desc.URI.substr(trailing_slash+1).size()+1,
-            ByHash);
-      } else {
-         _error->Warning(
-            "Fetching ByHash requested but can not find record for %s",
-            GetMetaKey().c_str());
-      }
-   }
-}
-                                                                       /*}}}*/
 // AcqIndex::Custom600Headers - Insert custom request headers          /*{{{*/
 // ---------------------------------------------------------------------
 /* The only header we use is the last-modified header. */
@@ -2605,7 +2619,18 @@ void pkgAcqIndex::StageDownloadDone(string const &Message, HashStringList const
    // 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 && RealFileExists(DestFile) == false)
+   {
       Local = true;
+      if (Target.KeepCompressed == true)
+      {
+        // but if we don't keep the uncompress we copy the compressed file first
+        Stage = STAGE_DOWNLOAD;
+        Desc.URI = "copy:" + FileName;
+        QueueURI(Desc);
+        SetActiveSubprocess("copy");
+        return;
+      }
+   }
    else
       EraseFileName = FileName;
 
@@ -2619,18 +2644,6 @@ void pkgAcqIndex::StageDownloadDone(string const &Message, HashStringList const
       return;
    }
 
-   // If we want compressed indexes, just copy in place for hash verification
-   if (Target.KeepCompressed == true)
-   {
-      DestFile = GetPartialFileNameFromURI(Target.URI + '.' + CurrentCompressionExtension);
-      EraseFileName = "";
-      Stage = STAGE_DECOMPRESS_AND_VERIFY;
-      Desc.URI = "copy:" + FileName;
-      QueueURI(Desc);
-      SetActiveSubprocess("copy");
-      return;
-    }
-
    // get the binary name for your used compression type
    string decompProg;
    if(CurrentCompressionExtension == "uncompressed")
@@ -2643,9 +2656,16 @@ void pkgAcqIndex::StageDownloadDone(string const &Message, HashStringList const
       return;
    }
 
+   if (Target.KeepCompressed == true)
+   {
+      DestFile = "/dev/null";
+      EraseFileName.clear();
+   }
+   else
+      DestFile += ".decomp";
+
    // queue uri for the next stage
    Stage = STAGE_DECOMPRESS_AND_VERIFY;
-   DestFile += ".decomp";
    Desc.URI = decompProg + ":" + FileName;
    QueueURI(Desc);
    SetActiveSubprocess(decompProg);
@@ -2656,6 +2676,9 @@ void pkgAcqIndex::StageDecompressDone(string const &,
                                       HashStringList const &,
                                       pkgAcquire::MethodConfig const * const)
 {
+   if (Target.KeepCompressed == true && DestFile == "/dev/null")
+      DestFile = GetPartialFileNameFromURI(Target.URI + '.' + CurrentCompressionExtension);
+
    // Done, queue for rename on transaction finished
    TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename());
    return;