X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/9b8034a9fd40b4d05075fda719e61f6eb4c45678..a6f8c07f83e4e5a8155c04feab543dc0c82ed495:/apt-pkg/acquire-item.cc diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 317db65b8..8c45acddd 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -190,14 +190,14 @@ static bool MessageInsecureRepository(bool const isError, std::string const &msg _error->Notice("%s", _("See apt-secure(8) manpage for repository creation and user configuration details.")); return false; } -static bool MessageInsecureRepository(bool const isError, char const * const msg, std::string const &repo) +static bool APT_NONNULL(2) MessageInsecureRepository(bool const isError, char const * const msg, std::string const &repo) { std::string m; strprintf(m, msg, repo.c_str()); return MessageInsecureRepository(isError, m); } /*}}}*/ -static bool AllowInsecureRepositories(char const * const msg, std::string const &repo,/*{{{*/ +static bool APT_NONNULL(1, 3, 4, 5) AllowInsecureRepositories(char const * const msg, std::string const &repo,/*{{{*/ metaIndex const * const MetaIndexParser, pkgAcqMetaClearSig * const TransactionManager, pkgAcquire::Item * const I) { if(MetaIndexParser->GetTrusted() == metaIndex::TRI_YES) @@ -239,8 +239,7 @@ APT_CONST bool pkgAcqTransactionItem::HashesRequired() const we can at least trust them for integrity of the download itself. Only repositories without a Release file can (obviously) not have hashes – and they are very uncommon and strongly discouraged */ - return TransactionManager->MetaIndexParser != NULL && - TransactionManager->MetaIndexParser->GetLoadedSuccessfully() == metaIndex::TRI_YES; + return TransactionManager->MetaIndexParser->GetLoadedSuccessfully() == metaIndex::TRI_YES; } HashStringList pkgAcqTransactionItem::GetExpectedHashes() const { @@ -331,20 +330,19 @@ bool pkgAcqTransactionItem::QueueURI(pkgAcquire::ItemDesc &Item) return false; } std::string const FinalFile = GetFinalFilename(); - if (TransactionManager != NULL && TransactionManager->IMSHit == true && - FileExists(FinalFile) == true) + if (TransactionManager->IMSHit == true && FileExists(FinalFile) == true) { PartialFile = DestFile = FinalFile; Status = StatDone; return false; } // If we got the InRelease file via a mirror, pick all indexes directly from this mirror, too - if (TransactionManager != nullptr && TransactionManager->BaseURI.empty() == false && + if (TransactionManager->BaseURI.empty() == false && URI::SiteOnly(Item.URI) != URI::SiteOnly(TransactionManager->BaseURI)) { // this ensures we rewrite only once and only the first step auto const OldBaseURI = Target.Option(IndexTarget::BASE_URI); - if (APT::String::Startswith(Item.URI, OldBaseURI)) + if (OldBaseURI.empty() == false && APT::String::Startswith(Item.URI, OldBaseURI)) { auto const ExtraPath = Item.URI.substr(OldBaseURI.length()); Item.URI = flCombine(TransactionManager->BaseURI, ExtraPath); @@ -936,10 +934,8 @@ static void LoadLastMetaIndexParser(pkgAcqMetaClearSig * const TransactionManage // AcqMetaBase - Constructor /*{{{*/ pkgAcqMetaBase::pkgAcqMetaBase(pkgAcquire * const Owner, pkgAcqMetaClearSig * const TransactionManager, - std::vector const &IndexTargets, IndexTarget const &DataTarget) : pkgAcqTransactionItem(Owner, TransactionManager, DataTarget), d(NULL), - IndexTargets(IndexTargets), AuthPass(false), IMSHit(false), State(TransactionStarted) { } @@ -1107,7 +1103,7 @@ bool pkgAcqMetaBase::CheckDownloadDone(pkgAcqTransactionItem * const I, const st { if (APT::String::Endswith(I->Desc.URI, "InRelease")) TransactionManager->BaseURI = I->Desc.URI.substr(0, I->Desc.URI.length() - strlen("InRelease")); - else + else if (APT::String::Endswith(I->Desc.URI, "Release")) TransactionManager->BaseURI = I->Desc.URI.substr(0, I->Desc.URI.length() - strlen("Release")); } @@ -1137,8 +1133,7 @@ bool pkgAcqMetaBase::CheckDownloadDone(pkgAcqTransactionItem * const I, const st { // for simplicity, the transaction manager is always InRelease // even if it doesn't exist. - if (TransactionManager != NULL) - TransactionManager->IMSHit = true; + TransactionManager->IMSHit = true; I->PartialFile = I->DestFile = I->GetFinalFilename(); } @@ -1191,60 +1186,64 @@ bool pkgAcqMetaBase::CheckAuthDone(string const &Message) /*{{{*/ << DestFile << std::endl; // Download further indexes with verification - QueueIndexes(true); + TransactionManager->QueueIndexes(true); return true; } /*}}}*/ -void pkgAcqMetaBase::QueueIndexes(bool const verify) /*{{{*/ +void pkgAcqMetaClearSig::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 ::iterator Target = IndexTargets.begin(); - Target != IndexTargets.end(); - ++Target) + std::set targetsSeen; + bool const metaBaseSupportsByHash = TransactionManager->MetaIndexParser->GetSupportsAcquireByHash(); + for (auto &Target: TransactionManager->MetaIndexParser->GetIndexTargets()) { + // if we have seen a target which is created-by a target this one here is declared a + // fallback to, we skip acquiring the fallback (but we make sure we clean up) + if (targetsSeen.find(Target.Option(IndexTarget::FALLBACK_OF)) != targetsSeen.end()) + { + targetsSeen.emplace(Target.Option(IndexTarget::CREATED_BY)); + new CleanupItem(Owner, TransactionManager, Target); + continue; + } // all is an implementation detail. Users shouldn't use this as arch // We need this support trickery here as e.g. Debian has binary-all files already, // but arch:all packages are still in the arch:any files, so we would waste precious // download time, bandwidth and diskspace for nothing, BUT Debian doesn't feature all // in the set of supported architectures, so we can filter based on this property rather // than invent an entirely new flag we would need to carry for all of eternity. - if (Target->Option(IndexTarget::ARCHITECTURE) == "all") + if (Target.Option(IndexTarget::ARCHITECTURE) == "all") { if (TransactionManager->MetaIndexParser->IsArchitectureSupported("all") == false || - TransactionManager->MetaIndexParser->IsArchitectureAllSupportedFor(*Target) == false) + TransactionManager->MetaIndexParser->IsArchitectureAllSupportedFor(Target) == false) { - new CleanupItem(Owner, TransactionManager, *Target); + new CleanupItem(Owner, TransactionManager, Target); continue; } } - bool trypdiff = Target->OptionBool(IndexTarget::PDIFFS); + bool trypdiff = Target.OptionBool(IndexTarget::PDIFFS); if (verify == true) { - if (TransactionManager->MetaIndexParser->Exists(Target->MetaKey) == false) + if (TransactionManager->MetaIndexParser->Exists(Target.MetaKey) == false) { // optional targets that we do not have in the Release file are skipped - if (Target->IsOptional) + if (Target.IsOptional) { - new CleanupItem(Owner, TransactionManager, *Target); + new CleanupItem(Owner, TransactionManager, Target); continue; } - std::string const &arch = Target->Option(IndexTarget::ARCHITECTURE); + std::string const &arch = Target.Option(IndexTarget::ARCHITECTURE); if (arch.empty() == false) { if (TransactionManager->MetaIndexParser->IsArchitectureSupported(arch) == false) { - new CleanupItem(Owner, TransactionManager, *Target); + new CleanupItem(Owner, TransactionManager, Target); _error->Notice(_("Skipping acquire of configured file '%s' as repository '%s' doesn't support architecture '%s'"), - Target->MetaKey.c_str(), TransactionManager->Target.Description.c_str(), arch.c_str()); + Target.MetaKey.c_str(), TransactionManager->Target.Description.c_str(), arch.c_str()); continue; } // if the architecture is officially supported but currently no packages for it available, @@ -1252,49 +1251,50 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify) /*{{{*/ // if we don't know which architectures are supported, we do NOT ignore it to notify user about this if (TransactionManager->MetaIndexParser->IsArchitectureSupported("*undefined*") == false) { - new CleanupItem(Owner, TransactionManager, *Target); + new CleanupItem(Owner, TransactionManager, Target); continue; } } Status = StatAuthError; - strprintf(ErrorText, _("Unable to find expected entry '%s' in Release file (Wrong sources.list entry or malformed file)"), Target->MetaKey.c_str()); + strprintf(ErrorText, _("Unable to find expected entry '%s' in Release file (Wrong sources.list entry or malformed file)"), Target.MetaKey.c_str()); return; } else { - auto const hashes = GetExpectedHashesFor(Target->MetaKey); + auto const hashes = GetExpectedHashesFor(Target.MetaKey); if (hashes.empty() == false) { if (hashes.usable() == false) { - new CleanupItem(Owner, TransactionManager, *Target); + new CleanupItem(Owner, TransactionManager, Target); _error->Warning(_("Skipping acquire of configured file '%s' as repository '%s' provides only weak security information for it"), - Target->MetaKey.c_str(), TransactionManager->Target.Description.c_str()); + Target.MetaKey.c_str(), TransactionManager->Target.Description.c_str()); continue; } // empty files are skipped as acquiring the very small compressed files is a waste of time else if (hashes.FileSize() == 0) { - new CleanupItem(Owner, TransactionManager, *Target); + new CleanupItem(Owner, TransactionManager, Target); + targetsSeen.emplace(Target.Option(IndexTarget::CREATED_BY)); continue; } } } // autoselect the compression method - std::vector types = VectorizeString(Target->Option(IndexTarget::COMPRESSIONTYPES), ' '); + std::vector types = VectorizeString(Target.Option(IndexTarget::COMPRESSIONTYPES), ' '); types.erase(std::remove_if(types.begin(), types.end(), [&](std::string const &t) { if (t == "uncompressed") - return TransactionManager->MetaIndexParser->Exists(Target->MetaKey) == false; - std::string const MetaKey = Target->MetaKey + "." + t; + return TransactionManager->MetaIndexParser->Exists(Target.MetaKey) == false; + std::string const MetaKey = Target.MetaKey + "." + t; return TransactionManager->MetaIndexParser->Exists(MetaKey) == false; }), types.end()); if (types.empty() == false) { std::ostringstream os; // add the special compressiontype byhash first if supported - std::string const useByHashConf = Target->Option(IndexTarget::BY_HASH); + std::string const useByHashConf = Target.Option(IndexTarget::BY_HASH); bool useByHash = false; if(useByHashConf == "force") useByHash = true; @@ -1304,12 +1304,12 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify) /*{{{*/ os << "by-hash "; std::copy(types.begin(), types.end()-1, std::ostream_iterator(os, " ")); os << *types.rbegin(); - Target->Options["COMPRESSIONTYPES"] = os.str(); + Target.Options["COMPRESSIONTYPES"] = os.str(); } else - Target->Options["COMPRESSIONTYPES"].clear(); + Target.Options["COMPRESSIONTYPES"].clear(); - std::string filename = GetExistingFilename(GetFinalFileNameFromURI(Target->URI)); + std::string filename = GetExistingFilename(GetFinalFileNameFromURI(Target.URI)); if (filename.empty() == false) { // if the Release file is a hit and we have an index it must be the current one @@ -1320,8 +1320,8 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify) /*{{{*/ // see if the file changed since the last Release file // we use the uncompressed files as we might compress differently compared to the server, // so the hashes might not match, even if they contain the same data. - HashStringList const newFile = GetExpectedHashesFromFor(TransactionManager->MetaIndexParser, Target->MetaKey); - HashStringList const oldFile = GetExpectedHashesFromFor(TransactionManager->LastMetaIndexParser, Target->MetaKey); + HashStringList const newFile = GetExpectedHashesFromFor(TransactionManager->MetaIndexParser, Target.MetaKey); + HashStringList const oldFile = GetExpectedHashesFromFor(TransactionManager->LastMetaIndexParser, Target.MetaKey); if (newFile != oldFile) filename.clear(); } @@ -1333,57 +1333,42 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify) /*{{{*/ if (filename.empty() == false) { - new NoActionItem(Owner, *Target, filename); - std::string const idxfilename = GetFinalFileNameFromURI(GetDiffIndexURI(*Target)); + new NoActionItem(Owner, Target, filename); + std::string const idxfilename = GetFinalFileNameFromURI(GetDiffIndexURI(Target)); if (FileExists(idxfilename)) - new NoActionItem(Owner, *Target, idxfilename); + new NoActionItem(Owner, Target, idxfilename); + targetsSeen.emplace(Target.Option(IndexTarget::CREATED_BY)); continue; } // check if we have patches available - trypdiff &= TransactionManager->MetaIndexParser->Exists(GetDiffIndexFileName(Target->MetaKey)); + trypdiff &= TransactionManager->MetaIndexParser->Exists(GetDiffIndexFileName(Target.MetaKey)); } else { // if we have no file to patch, no point in trying - trypdiff &= (GetExistingFilename(GetFinalFileNameFromURI(Target->URI)).empty() == false); + trypdiff &= (GetExistingFilename(GetFinalFileNameFromURI(Target.URI)).empty() == false); } // no point in patching from local sources if (trypdiff) { - std::string const proto = Target->URI.substr(0, strlen("file:/")); + std::string const proto = Target.URI.substr(0, strlen("file:/")); if (proto == "file:/" || proto == "copy:/" || proto == "cdrom:") trypdiff = false; } // Queue the Index file (Packages, Sources, Translation-$foo, …) + targetsSeen.emplace(Target.Option(IndexTarget::CREATED_BY)); if (trypdiff) - new pkgAcqDiffIndex(Owner, TransactionManager, *Target); + new pkgAcqDiffIndex(Owner, TransactionManager, Target); else - new pkgAcqIndex(Owner, TransactionManager, *Target); + new pkgAcqIndex(Owner, TransactionManager, Target); } } /*}}}*/ -bool pkgAcqMetaBase::VerifyVendor(string const &Message) /*{{{*/ +bool pkgAcqMetaBase::VerifyVendor(string const &) /*{{{*/ { - string::size_type pos; - - // check for missing sigs (that where not fatal because otherwise we had - // bombed earlier) - string missingkeys; - string msg = _("There is no public key available for the " - "following key IDs:\n"); - pos = Message.find("NO_PUBKEY "); - if (pos != std::string::npos) - { - string::size_type start = pos+strlen("NO_PUBKEY "); - string Fingerprint = Message.substr(start, Message.find("\n")-start); - missingkeys += (Fingerprint); - } - if(!missingkeys.empty()) - _error->Warning("%s", (msg + missingkeys).c_str()); - string Transformed = TransactionManager->MetaIndexParser->GetExpectedDist(); if (Transformed == "../project/experimental") @@ -1391,7 +1376,7 @@ bool pkgAcqMetaBase::VerifyVendor(string const &Message) /*{{{*/ Transformed = "experimental"; } - pos = Transformed.rfind('/'); + auto pos = Transformed.rfind('/'); if (pos != string::npos) { Transformed = Transformed.substr(0, pos); @@ -1470,15 +1455,14 @@ pkgAcqMetaBase::~pkgAcqMetaBase() pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire * const Owner, /*{{{*/ IndexTarget const &ClearsignedTarget, IndexTarget const &DetachedDataTarget, IndexTarget const &DetachedSigTarget, - std::vector const &IndexTargets, metaIndex * const MetaIndexParser) : - pkgAcqMetaIndex(Owner, this, ClearsignedTarget, DetachedSigTarget, IndexTargets), + pkgAcqMetaIndex(Owner, this, ClearsignedTarget, DetachedSigTarget), d(NULL), ClearsignedTarget(ClearsignedTarget), DetachedDataTarget(DetachedDataTarget), MetaIndexParser(MetaIndexParser), LastMetaIndexParser(NULL) { // index targets + (worst case:) Release/Release.gpg - ExpectedAdditionalItems = IndexTargets.size() + 2; + ExpectedAdditionalItems = std::numeric_limits::max(); TransactionManager->Add(this); } /*}}}*/ @@ -1504,7 +1488,7 @@ void pkgAcqMetaClearSig::Finished() /*{{{*/ { if(_config->FindB("Debug::Acquire::Transaction", false) == true) std::clog << "Finished: " << DestFile <State == TransactionStarted && + if(TransactionManager->State == TransactionStarted && TransactionManager->TransactionHasError() == false) TransactionManager->CommitTransaction(); } @@ -1552,9 +1536,6 @@ void pkgAcqMetaClearSig::Failed(string const &Message,pkgAcquire::MethodConfig c { Item::Failed(Message, Cnf); - // we failed, we will not get additional items from this method - ExpectedAdditionalItems = 0; - if (AuthPass == false) { if (Status == StatAuthError || Status == StatTransientNetworkError) @@ -1573,7 +1554,7 @@ void pkgAcqMetaClearSig::Failed(string const &Message,pkgAcquire::MethodConfig c TransactionManager->TransactionStageRemoval(this, GetFinalFilename()); Status = StatDone; - new pkgAcqMetaIndex(Owner, TransactionManager, DetachedDataTarget, DetachedSigTarget, IndexTargets); + new pkgAcqMetaIndex(Owner, TransactionManager, DetachedDataTarget, DetachedSigTarget); } else { @@ -1602,7 +1583,7 @@ void pkgAcqMetaClearSig::Failed(string const &Message,pkgAcquire::MethodConfig c if (TransactionManager->MetaIndexParser->Load(PartialRelease, &ErrorText) == false || VerifyVendor(Message) == false) /* expired Release files are still a problem you need extra force for */; else - QueueIndexes(true); + TransactionManager->QueueIndexes(true); } } } @@ -1611,9 +1592,8 @@ void pkgAcqMetaClearSig::Failed(string const &Message,pkgAcquire::MethodConfig c pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire * const Owner, /*{{{*/ pkgAcqMetaClearSig * const TransactionManager, IndexTarget const &DataTarget, - IndexTarget const &DetachedSigTarget, - vector const &IndexTargets) : - pkgAcqMetaBase(Owner, TransactionManager, IndexTargets, DataTarget), d(NULL), + IndexTarget const &DetachedSigTarget) : + pkgAcqMetaBase(Owner, TransactionManager, DataTarget), d(NULL), DetachedSigTarget(DetachedSigTarget) { if(_config->FindB("Debug::Acquire::Transaction", false) == true) @@ -1627,9 +1607,6 @@ pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire * const Owner, /*{{{*/ Desc.Owner = this; Desc.ShortDesc = DataTarget.ShortDesc; Desc.URI = DataTarget.URI; - - // we expect more item - ExpectedAdditionalItems = IndexTargets.size(); QueueURI(Desc); } /*}}}*/ @@ -1664,7 +1641,7 @@ void pkgAcqMetaIndex::Failed(string const &Message, TransactionManager->TransactionStageRemoval(this, GetFinalFilename()); // queue without any kind of hashsum support - QueueIndexes(false); + TransactionManager->QueueIndexes(false); } } /*}}}*/ @@ -1810,7 +1787,7 @@ void pkgAcqMetaSig::Failed(string const &Message,pkgAcquire::MethodConfig const if (MetaIndex->VerifyVendor(Message) == false) /* expired Release files are still a problem you need extra force for */; else - MetaIndex->QueueIndexes(GoodLoad); + TransactionManager->QueueIndexes(GoodLoad); TransactionManager->TransactionStageCopy(MetaIndex, MetaIndex->DestFile, MetaIndex->GetFinalFilename()); } @@ -1837,8 +1814,7 @@ pkgAcqBaseIndex::pkgAcqBaseIndex(pkgAcquire * const Owner, void pkgAcqBaseIndex::Failed(std::string const &Message,pkgAcquire::MethodConfig const * const Cnf)/*{{{*/ { pkgAcquire::Item::Failed(Message, Cnf); - if (TransactionManager == nullptr || TransactionManager->MetaIndexParser == nullptr || - Status != StatAuthError) + if (Status != StatAuthError) return; ErrorText.append("Release file created at: "); @@ -1864,6 +1840,9 @@ pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire * const Owner, IndexTarget const &Target) : pkgAcqBaseIndex(Owner, TransactionManager, Target), d(NULL), diffs(NULL) { + // FIXME: Magic number as an upper bound on pdiffs we will reasonably acquire + ExpectedAdditionalItems = 40; + Debug = _config->FindB("Debug::pkgAcquire::Diffs",false); Desc.Owner = this; @@ -1908,6 +1887,7 @@ void pkgAcqDiffIndex::QueueOnIMSHit() const /*{{{*/ /*}}}*/ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/ { + ExpectedAdditionalItems = 0; // failing here is fine: our caller will take care of trying to // get the complete file if patching fails if(Debug) @@ -2184,7 +2164,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/ // calculate the size of all patches we have to get unsigned short const sizeLimitPercent = _config->FindI("Acquire::PDiffs::SizeLimit", 100); - if (sizeLimitPercent > 0 && TransactionManager->MetaIndexParser != nullptr) + if (sizeLimitPercent > 0) { unsigned long long downloadSize = std::accumulate(available_patches.begin(), available_patches.end(), 0llu, [](unsigned long long const T, DiffInfo const &I) { @@ -2291,6 +2271,7 @@ void pkgAcqDiffIndex::Failed(string const &Message,pkgAcquire::MethodConfig cons { pkgAcqBaseIndex::Failed(Message,Cnf); Status = StatDone; + ExpectedAdditionalItems = 0; if(Debug) std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << " with " << Message << std::endl @@ -2750,7 +2731,7 @@ void pkgAcqIndex::Init(string const &URI, string const &URIDesc, else if (CurrentCompressionExtension == "by-hash") { NextCompressionExtension(CurrentCompressionExtension, CompressionExtensions, true); - if(unlikely(TransactionManager->MetaIndexParser == NULL || CurrentCompressionExtension.empty())) + if(unlikely(CurrentCompressionExtension.empty())) return; if (CurrentCompressionExtension != "uncompressed") {