summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/acquire-item.cc150
-rw-r--r--apt-pkg/acquire-item.h46
-rw-r--r--apt-pkg/acquire-worker.cc19
-rw-r--r--apt-pkg/acquire.cc13
-rw-r--r--apt-pkg/contrib/configuration.cc74
-rw-r--r--apt-pkg/deb/debmetaindex.cc270
-rw-r--r--apt-pkg/deb/dpkgpm.cc7
-rw-r--r--apt-pkg/edsp.cc22
-rw-r--r--apt-pkg/indexfile.cc2
-rw-r--r--apt-pkg/indexfile.h2
10 files changed, 334 insertions, 271 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index fde45e1fe..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<IndexTarget> 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 <IndexTarget>::iterator Target = IndexTargets.begin();
- Target != IndexTargets.end();
- ++Target)
+ std::set<std::string> 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<std::string> types = VectorizeString(Target->Option(IndexTarget::COMPRESSIONTYPES), ' ');
+ std::vector<std::string> 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<std::string>(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,35 +1333,37 @@ 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);
}
}
/*}}}*/
@@ -1453,15 +1455,14 @@ pkgAcqMetaBase::~pkgAcqMetaBase()
pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire * const Owner, /*{{{*/
IndexTarget const &ClearsignedTarget,
IndexTarget const &DetachedDataTarget, IndexTarget const &DetachedSigTarget,
- std::vector<IndexTarget> 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<decltype(ExpectedAdditionalItems)>::max();
TransactionManager->Add(this);
}
/*}}}*/
@@ -1487,7 +1488,7 @@ void pkgAcqMetaClearSig::Finished() /*{{{*/
{
if(_config->FindB("Debug::Acquire::Transaction", false) == true)
std::clog << "Finished: " << DestFile <<std::endl;
- if(TransactionManager != NULL && TransactionManager->State == TransactionStarted &&
+ if(TransactionManager->State == TransactionStarted &&
TransactionManager->TransactionHasError() == false)
TransactionManager->CommitTransaction();
}
@@ -1535,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)
@@ -1556,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
{
@@ -1585,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);
}
}
}
@@ -1594,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<IndexTarget> 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)
@@ -1610,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);
}
/*}}}*/
@@ -1647,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);
}
}
/*}}}*/
@@ -1793,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());
}
@@ -1820,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: ");
@@ -1847,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;
@@ -1891,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)
@@ -2167,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) {
@@ -2274,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
@@ -2733,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")
{
diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h
index 41420a7c1..92f1ac215 100644
--- a/apt-pkg/acquire-item.h
+++ b/apt-pkg/acquire-item.h
@@ -393,7 +393,7 @@ class APT_HIDDEN pkgAcqTransactionItem: public pkgAcquire::Item /*{{{*/
virtual bool HashesRequired() const APT_OVERRIDE;
- pkgAcqTransactionItem(pkgAcquire * const Owner, pkgAcqMetaClearSig * const TransactionManager, IndexTarget const &Target);
+ pkgAcqTransactionItem(pkgAcquire * const Owner, pkgAcqMetaClearSig * const TransactionManager, IndexTarget const &Target) APT_NONNULL(2, 3);
virtual ~pkgAcqTransactionItem();
friend class pkgAcqMetaBase;
@@ -407,25 +407,10 @@ class APT_HIDDEN pkgAcqMetaBase : public pkgAcqTransactionItem /*{{{*/
protected:
std::vector<pkgAcqTransactionItem*> Transaction;
- /** \brief The index files which should be looked up in the meta-index
- * and then downloaded.
- */
- std::vector<IndexTarget> IndexTargets;
-
/** \brief If \b true, the index's signature is currently being verified.
*/
bool AuthPass;
- /** \brief Starts downloading the individual index files.
- *
- * \param verify If \b true, only indices whose expected hashsum
- * can be determined from the meta-index will be downloaded, and
- * the hashsums of indices will be checked (reporting
- * #StatAuthError if there is a mismatch). If verify is \b false,
- * no hashsum checking will be performed.
- */
- void QueueIndexes(bool const verify);
-
/** \brief Called when a file is finished being retrieved.
*
* If the file was not downloaded to DestFile, a copy process is
@@ -494,8 +479,7 @@ class APT_HIDDEN pkgAcqMetaBase : public pkgAcqTransactionItem /*{{{*/
virtual std::string GetFinalFilename() const APT_OVERRIDE;
pkgAcqMetaBase(pkgAcquire * const Owner, pkgAcqMetaClearSig * const TransactionManager,
- std::vector<IndexTarget> const &IndexTargets,
- IndexTarget const &DataTarget);
+ IndexTarget const &DataTarget) APT_NONNULL(2, 3);
virtual ~pkgAcqMetaBase();
};
/*}}}*/
@@ -528,8 +512,7 @@ class APT_HIDDEN pkgAcqMetaIndex : public pkgAcqMetaBase
/** \brief Create a new pkgAcqMetaIndex. */
pkgAcqMetaIndex(pkgAcquire * const Owner, pkgAcqMetaClearSig * const TransactionManager,
- IndexTarget const &DataTarget, IndexTarget const &DetachedSigTarget,
- std::vector<IndexTarget> const &IndexTargets);
+ IndexTarget const &DataTarget, IndexTarget const &DetachedSigTarget) APT_NONNULL(2, 3);
virtual ~pkgAcqMetaIndex();
friend class pkgAcqMetaSig;
@@ -568,7 +551,7 @@ class APT_HIDDEN pkgAcqMetaSig : public pkgAcqTransactionItem
/** \brief Create a new pkgAcqMetaSig. */
pkgAcqMetaSig(pkgAcquire * const Owner, pkgAcqMetaClearSig * const TransactionManager,
- IndexTarget const &Target, pkgAcqMetaIndex * const MetaIndex);
+ IndexTarget const &Target, pkgAcqMetaIndex * const MetaIndex) APT_NONNULL(2, 3, 5);
virtual ~pkgAcqMetaSig();
};
/*}}}*/
@@ -592,12 +575,21 @@ class APT_HIDDEN pkgAcqMetaClearSig : public pkgAcqMetaIndex
pkgAcquire::MethodConfig const * const Cnf) APT_OVERRIDE;
virtual void Finished() APT_OVERRIDE;
+ /** \brief Starts downloading the individual index files.
+ *
+ * \param verify If \b true, only indices whose expected hashsum
+ * can be determined from the meta-index will be downloaded, and
+ * the hashsums of indices will be checked (reporting
+ * #StatAuthError if there is a mismatch). If verify is \b false,
+ * no hashsum checking will be performed.
+ */
+ void QueueIndexes(bool const verify);
+
/** \brief Create a new pkgAcqMetaClearSig. */
pkgAcqMetaClearSig(pkgAcquire * const Owner,
IndexTarget const &ClearsignedTarget,
IndexTarget const &DetachedDataTarget,
IndexTarget const &DetachedSigTarget,
- std::vector<IndexTarget> const &IndexTargets,
metaIndex * const MetaIndexParser);
virtual ~pkgAcqMetaClearSig();
};
@@ -613,7 +605,7 @@ class APT_HIDDEN pkgAcqBaseIndex : public pkgAcqTransactionItem
virtual void Failed(std::string const &Message,pkgAcquire::MethodConfig const * const Cnf) APT_OVERRIDE;
pkgAcqBaseIndex(pkgAcquire * const Owner, pkgAcqMetaClearSig * const TransactionManager,
- IndexTarget const &Target);
+ IndexTarget const &Target) APT_NONNULL(2, 3);
virtual ~pkgAcqBaseIndex();
};
/*}}}*/
@@ -678,7 +670,7 @@ class APT_HIDDEN pkgAcqDiffIndex : public pkgAcqBaseIndex
* \param ShortDesc A short description of the list file to download.
*/
pkgAcqDiffIndex(pkgAcquire * const Owner, pkgAcqMetaClearSig * const TransactionManager,
- IndexTarget const &Target);
+ IndexTarget const &Target) APT_NONNULL(2, 3);
virtual ~pkgAcqDiffIndex();
private:
APT_HIDDEN void QueueOnIMSHit() const;
@@ -778,7 +770,7 @@ class APT_HIDDEN pkgAcqIndexMergeDiffs : public pkgAcqBaseIndex
*/
pkgAcqIndexMergeDiffs(pkgAcquire * const Owner, pkgAcqMetaClearSig * const TransactionManager,
IndexTarget const &Target, DiffInfo const &patch,
- std::vector<pkgAcqIndexMergeDiffs*> const * const allPatches);
+ std::vector<pkgAcqIndexMergeDiffs*> const * const allPatches) APT_NONNULL(2, 3, 6);
virtual ~pkgAcqIndexMergeDiffs();
};
/*}}}*/
@@ -889,7 +881,7 @@ class APT_HIDDEN pkgAcqIndexDiffs : public pkgAcqBaseIndex
*/
pkgAcqIndexDiffs(pkgAcquire * const Owner, pkgAcqMetaClearSig * const TransactionManager,
IndexTarget const &Target,
- std::vector<DiffInfo> const &diffs=std::vector<DiffInfo>());
+ std::vector<DiffInfo> const &diffs=std::vector<DiffInfo>()) APT_NONNULL(2, 3);
virtual ~pkgAcqIndexDiffs();
};
/*}}}*/
@@ -956,7 +948,7 @@ class APT_HIDDEN pkgAcqIndex : public pkgAcqBaseIndex
virtual std::string GetMetaKey() const APT_OVERRIDE;
pkgAcqIndex(pkgAcquire * const Owner, pkgAcqMetaClearSig * const TransactionManager,
- IndexTarget const &Target);
+ IndexTarget const &Target) APT_NONNULL(2, 3);
virtual ~pkgAcqIndex();
private:
diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc
index 69ca6a28e..2ad0eda7f 100644
--- a/apt-pkg/acquire-worker.cc
+++ b/apt-pkg/acquire-worker.cc
@@ -273,16 +273,19 @@ bool pkgAcquire::Worker::RunMessages()
// if we change site, treat it as a mirror change
if (URI::SiteOnly(NewURI) != URI::SiteOnly(desc.URI))
{
- std::string const OldSite = desc.Description.substr(0, desc.Description.find(" "));
- if (likely(APT::String::Startswith(desc.URI, OldSite)))
+ auto const firstSpace = desc.Description.find(" ");
+ if (firstSpace != std::string::npos)
{
- std::string const OldExtra = desc.URI.substr(OldSite.length() + 1);
- if (likely(APT::String::Endswith(NewURI, OldExtra)))
+ std::string const OldSite = desc.Description.substr(0, firstSpace);
+ if (likely(APT::String::Startswith(desc.URI, OldSite)))
{
- std::string const NewSite = NewURI.substr(0, NewURI.length() - OldExtra.length());
- Owner->UsedMirror = URI::ArchiveOnly(NewSite);
- if (desc.Description.find(" ") != string::npos)
- desc.Description.replace(0, desc.Description.find(" "), Owner->UsedMirror);
+ std::string const OldExtra = desc.URI.substr(OldSite.length() + 1);
+ if (likely(APT::String::Endswith(NewURI, OldExtra)))
+ {
+ std::string const NewSite = NewURI.substr(0, NewURI.length() - OldExtra.length());
+ Owner->UsedMirror = URI::ArchiveOnly(NewSite);
+ desc.Description.replace(0, firstSpace, Owner->UsedMirror);
+ }
}
}
}
diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc
index c65aef329..7a44d8599 100644
--- a/apt-pkg/acquire.cc
+++ b/apt-pkg/acquire.cc
@@ -1147,7 +1147,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
// Compute the total number of bytes to fetch
unsigned int Unknown = 0;
unsigned int Count = 0;
- bool UnfetchedReleaseFiles = false;
+ bool ExpectAdditionalItems = false;
for (pkgAcquire::ItemCIterator I = Owner->ItemsBegin();
I != Owner->ItemsEnd();
++I, ++Count)
@@ -1156,12 +1156,9 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
if ((*I)->Status == pkgAcquire::Item::StatDone)
++CurrentItems;
- // see if the method tells us to expect more
- TotalItems += (*I)->ExpectedAdditionalItems;
-
- // check if there are unfetched Release files
- if ((*I)->Status != pkgAcquire::Item::StatDone && (*I)->ExpectedAdditionalItems > 0)
- UnfetchedReleaseFiles = true;
+ // do we expect to acquire more files than we know of yet?
+ if ((*I)->ExpectedAdditionalItems > 0)
+ ExpectAdditionalItems = true;
TotalBytes += (*I)->FileSize;
if ((*I)->Complete == true)
@@ -1218,7 +1215,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
double const OldPercent = Percent;
// calculate the percentage, if we have too little data assume 1%
- if (TotalBytes > 0 && UnfetchedReleaseFiles)
+ if (ExpectAdditionalItems)
Percent = 0;
else
// use both files and bytes because bytes can be unreliable
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index d4bb72a8b..3cb7fde06 100644
--- a/apt-pkg/contrib/configuration.cc
+++ b/apt-pkg/contrib/configuration.cc
@@ -29,8 +29,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
#include <algorithm>
#include <string>
+#include <stack>
#include <vector>
#include <fstream>
@@ -674,6 +676,16 @@ string Configuration::Item::FullTag(const Item *Stop) const
sections like 'zone "foo.org" { .. };' This causes each section to be
added in with a tag like "zone::foo.org" instead of being split
tag/value. AsSectional enables Sectional parsing.*/
+static void leaveCurrentScope(std::stack<std::string> &Stack, std::string &ParentTag)
+{
+ if (Stack.empty())
+ ParentTag.clear();
+ else
+ {
+ ParentTag = Stack.top();
+ Stack.pop();
+ }
+}
bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectional,
unsigned const &Depth)
{
@@ -683,8 +695,7 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio
return _error->Errno("ifstream::ifstream",_("Opening configuration file %s"),FName.c_str());
string LineBuffer;
- string Stack[100];
- unsigned int StackPos = 0;
+ std::stack<std::string> Stack;
// Parser state
string ParentTag;
@@ -753,12 +764,12 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio
Start = I + 2;
InComment = false;
break;
- }
+ }
}
if (InComment == true)
continue;
}
-
+
// Discard single line comments
bool InQuote = false;
for (std::string::const_iterator I = Start;
@@ -803,9 +814,9 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio
I = J + 1;
InComment = false;
break;
- }
+ }
}
-
+
if (InComment == true)
break;
}
@@ -816,7 +827,7 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio
// Skip blank lines.
if (Fragment.empty())
continue;
-
+
// The line has actual content; interpret what it means.
InQuote = false;
Start = Fragment.begin();
@@ -826,7 +837,7 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio
{
if (*I == '"')
InQuote = !InQuote;
-
+
if (InQuote == false && (*I == '{' || *I == ';' || *I == '}'))
{
// Put the last fragment into the buffer
@@ -845,24 +856,19 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio
// brace or a semicolon)
char TermChar = *I;
Start = I + 1;
-
+
// Syntax Error
if (TermChar == '{' && LineBuffer.empty() == true)
return _error->Error(_("Syntax error %s:%u: Block starts with no name."),FName.c_str(),CurLine);
-
+
// No string on this line
if (LineBuffer.empty() == true)
{
if (TermChar == '}')
- {
- if (StackPos == 0)
- ParentTag = string();
- else
- ParentTag = Stack[--StackPos];
- }
+ leaveCurrentScope(Stack, ParentTag);
continue;
}
-
+
// Parse off the tag
string Tag;
const char *Pos = LineBuffer.c_str();
@@ -889,25 +895,23 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio
// Go down a level
if (TermChar == '{')
{
- if (StackPos < sizeof(Stack)/sizeof(std::string))
- Stack[StackPos++] = ParentTag;
-
+ Stack.push(ParentTag);
+
/* Make sectional tags incorperate the section into the
tag string */
if (AsSectional == true && Word.empty() == false)
{
- Tag += "::" ;
- Tag += Word;
- Word = "";
+ Tag.append("::").append(Word);
+ Word.clear();
}
-
+
if (ParentTag.empty() == true)
ParentTag = Tag;
else
- ParentTag += string("::") + Tag;
- Tag = string();
+ ParentTag.append("::").append(Tag);
+ Tag.clear();
}
-
+
// Generate the item name
string Item;
if (ParentTag.empty() == true)
@@ -919,7 +923,7 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio
else
Item = ParentTag;
}
-
+
// Specials
if (Tag.length() >= 1 && Tag[0] == '#')
{
@@ -941,7 +945,7 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio
{
if (ReadConfigFile(Conf,Word,AsSectional,Depth+1) == false)
return _error->Error(_("Syntax error %s:%u: Included from here"),FName.c_str(),CurLine);
- }
+ }
}
else
return _error->Error(_("Syntax error %s:%u: Unsupported directive '%s'"),FName.c_str(),CurLine,Tag.c_str());
@@ -954,19 +958,13 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio
if (NoWord == false)
Conf.Set(Item,Word);
}
-
+
// Empty the buffer
LineBuffer.clear();
-
+
// Move up a tag, but only if there is no bit to parse
if (TermChar == '}')
- {
- if (StackPos == 0)
- ParentTag.clear();
- else
- ParentTag = Stack[--StackPos];
- }
-
+ leaveCurrentScope(Stack, ParentTag);
}
}
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index d152eaf68..ead07a479 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -33,13 +33,13 @@ class APT_HIDDEN debReleaseIndexPrivate /*{{{*/
public:
struct APT_HIDDEN debSectionEntry
{
- std::string sourcesEntry;
- std::string Name;
- std::vector<std::string> Targets;
- std::vector<std::string> Architectures;
- std::vector<std::string> Languages;
- bool UsePDiffs;
- std::string UseByHash;
+ std::string const sourcesEntry;
+ std::string const Name;
+ std::vector<std::string> const Targets;
+ std::vector<std::string> const Architectures;
+ std::vector<std::string> const Languages;
+ bool const UsePDiffs;
+ std::string const UseByHash;
};
std::vector<debSectionEntry> DebEntries;
@@ -153,7 +153,8 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI,
}
DefKeepCompressedAs += "uncompressed";
}
- std::string const NativeArch = _config->Find("APT::Architecture");
+
+ std::vector<std::string> const NativeArchs = { _config->Find("APT::Architecture"), "all" };
bool const GzipIndex = _config->FindB("Acquire::GzipIndexes", false);
for (std::vector<debReleaseIndexPrivate::debSectionEntry>::const_iterator E = entries.begin(); E != entries.end(); ++E)
{
@@ -164,6 +165,7 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI,
std::string const tplMetaKey = APT_T_CONFIG_STR(flatArchive ? "flatMetaKey" : "MetaKey", "");
std::string const tplShortDesc = APT_T_CONFIG_STR("ShortDescription", "");
std::string const tplLongDesc = "$(SITE) " + APT_T_CONFIG_STR(flatArchive ? "flatDescription" : "Description", "");
+ std::string const tplIdentifier = APT_T_CONFIG_STR("Identifier", *T);
bool const IsOptional = APT_T_CONFIG_BOOL("Optional", true);
bool const KeepCompressed = APT_T_CONFIG_BOOL("KeepCompressed", GzipIndex);
bool const DefaultEnabled = APT_T_CONFIG_BOOL("DefaultEnabled", true);
@@ -171,6 +173,7 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI,
std::string const UseByHash = APT_T_CONFIG_STR("By-Hash", E->UseByHash);
std::string const CompressionTypes = APT_T_CONFIG_STR("CompressionTypes", DefCompressionTypes);
std::string KeepCompressedAs = APT_T_CONFIG_STR("KeepCompressedAs", "");
+ std::string const FallbackOf = APT_T_CONFIG_STR("Fallback-Of", "");
#undef APT_T_CONFIG_BOOL
#undef APT_T_CONFIG_STR
if (tplMetaKey.empty())
@@ -206,113 +209,125 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI,
for (std::vector<std::string>::const_iterator A = E->Architectures.begin(); A != E->Architectures.end(); ++A)
{
- // available in templates
- std::map<std::string, std::string> Options;
- Options.insert(std::make_pair("SITE", Site));
- Options.insert(std::make_pair("RELEASE", Release));
- if (tplMetaKey.find("$(COMPONENT)") != std::string::npos)
- Options.insert(std::make_pair("COMPONENT", E->Name));
- if (tplMetaKey.find("$(LANGUAGE)") != std::string::npos)
- Options.insert(std::make_pair("LANGUAGE", *L));
- if (tplMetaKey.find("$(ARCHITECTURE)") != std::string::npos)
- Options.insert(std::make_pair("ARCHITECTURE", *A));
- else if (tplMetaKey.find("$(NATIVE_ARCHITECTURE)") != std::string::npos)
- Options.insert(std::make_pair("ARCHITECTURE", NativeArch));
- if (tplMetaKey.find("$(NATIVE_ARCHITECTURE)") != std::string::npos)
- Options.insert(std::make_pair("NATIVE_ARCHITECTURE", NativeArch));
-
- std::string MetaKey = tplMetaKey;
- std::string ShortDesc = tplShortDesc;
- std::string LongDesc = tplLongDesc;
- for (std::map<std::string, std::string>::const_iterator O = Options.begin(); O != Options.end(); ++O)
+ for (auto const &NativeArch: NativeArchs)
{
- MetaKey = SubstVar(MetaKey, std::string("$(") + O->first + ")", O->second);
- ShortDesc = SubstVar(ShortDesc, std::string("$(") + O->first + ")", O->second);
- LongDesc = SubstVar(LongDesc, std::string("$(") + O->first + ")", O->second);
- }
+ constexpr static auto BreakPoint = "$(NATIVE_ARCHITECTURE)";
+ // available in templates
+ std::map<std::string, std::string> Options;
+ Options.insert(std::make_pair("SITE", Site));
+ Options.insert(std::make_pair("RELEASE", Release));
+ if (tplMetaKey.find("$(COMPONENT)") != std::string::npos)
+ Options.insert(std::make_pair("COMPONENT", E->Name));
+ if (tplMetaKey.find("$(LANGUAGE)") != std::string::npos)
+ Options.insert(std::make_pair("LANGUAGE", *L));
+ if (tplMetaKey.find("$(ARCHITECTURE)") != std::string::npos)
+ Options.insert(std::make_pair("ARCHITECTURE", *A));
+ else if (tplMetaKey.find("$(NATIVE_ARCHITECTURE)") != std::string::npos)
+ Options.insert(std::make_pair("ARCHITECTURE", NativeArch));
+ if (tplMetaKey.find("$(NATIVE_ARCHITECTURE)") != std::string::npos)
+ Options.insert(std::make_pair("NATIVE_ARCHITECTURE", NativeArch));
+
+ std::string MetaKey = tplMetaKey;
+ std::string ShortDesc = tplShortDesc;
+ std::string LongDesc = tplLongDesc;
+ std::string Identifier = tplIdentifier;
+ for (std::map<std::string, std::string>::const_iterator O = Options.begin(); O != Options.end(); ++O)
+ {
+ std::string const varname = "$(" + O->first + ")";
+ MetaKey = SubstVar(MetaKey, varname, O->second);
+ ShortDesc = SubstVar(ShortDesc, varname, O->second);
+ LongDesc = SubstVar(LongDesc, varname, O->second);
+ Identifier = SubstVar(Identifier, varname, O->second);
+ }
- {
- auto const dup = std::find_if(IndexTargets.begin(), IndexTargets.end(), [&](IndexTarget const &IT) {
- return MetaKey == IT.MetaKey && baseURI == IT.Option(IndexTarget::BASE_URI) &&
- E->sourcesEntry == IT.Option(IndexTarget::SOURCESENTRY) && *T == IT.Option(IndexTarget::CREATED_BY);
- });
- if (dup != IndexTargets.end())
{
- if (tplMetaKey.find("$(ARCHITECTURE)") == std::string::npos)
- break;
- continue;
+ auto const dup = std::find_if(IndexTargets.begin(), IndexTargets.end(), [&](IndexTarget const &IT) {
+ return MetaKey == IT.MetaKey && baseURI == IT.Option(IndexTarget::BASE_URI) &&
+ E->sourcesEntry == IT.Option(IndexTarget::SOURCESENTRY) && *T == IT.Option(IndexTarget::CREATED_BY);
+ });
+ if (dup != IndexTargets.end())
+ {
+ if (tplMetaKey.find(BreakPoint) == std::string::npos)
+ break;
+ continue;
+ }
}
- }
- {
- auto const dup = std::find_if(IndexTargets.begin(), IndexTargets.end(), [&](IndexTarget const &IT) {
- return MetaKey == IT.MetaKey && baseURI == IT.Option(IndexTarget::BASE_URI) &&
- E->sourcesEntry == IT.Option(IndexTarget::SOURCESENTRY) && *T != IT.Option(IndexTarget::CREATED_BY);
- });
- if (dup != IndexTargets.end())
{
- std::string const dupT = dup->Option(IndexTarget::CREATED_BY);
- std::string const dupEntry = dup->Option(IndexTarget::SOURCESENTRY);
- //TRANSLATOR: an identifier like Packages; Releasefile key indicating
- // a file like main/binary-amd64/Packages; another identifier like Contents;
- // filename and linenumber of the sources.list entry currently parsed
- _error->Warning(_("Target %s wants to acquire the same file (%s) as %s from source %s"),
- T->c_str(), MetaKey.c_str(), dupT.c_str(), dupEntry.c_str());
- if (tplMetaKey.find("$(ARCHITECTURE)") == std::string::npos)
- break;
- continue;
+ auto const dup = std::find_if(IndexTargets.begin(), IndexTargets.end(), [&](IndexTarget const &IT) {
+ return MetaKey == IT.MetaKey && baseURI == IT.Option(IndexTarget::BASE_URI) &&
+ E->sourcesEntry == IT.Option(IndexTarget::SOURCESENTRY) && *T != IT.Option(IndexTarget::CREATED_BY);
+ });
+ if (dup != IndexTargets.end())
+ {
+ std::string const dupT = dup->Option(IndexTarget::CREATED_BY);
+ std::string const dupEntry = dup->Option(IndexTarget::SOURCESENTRY);
+ //TRANSLATOR: an identifier like Packages; Releasefile key indicating
+ // a file like main/binary-amd64/Packages; another identifier like Contents;
+ // filename and linenumber of the sources.list entry currently parsed
+ _error->Warning(_("Target %s wants to acquire the same file (%s) as %s from source %s"),
+ T->c_str(), MetaKey.c_str(), dupT.c_str(), dupEntry.c_str());
+ if (tplMetaKey.find(BreakPoint) == std::string::npos)
+ break;
+ continue;
+ }
}
- }
- {
- auto const dup = std::find_if(IndexTargets.begin(), IndexTargets.end(), [&](IndexTarget const &T) {
- return MetaKey == T.MetaKey && baseURI == T.Option(IndexTarget::BASE_URI) &&
- E->sourcesEntry != T.Option(IndexTarget::SOURCESENTRY);
- });
- if (dup != IndexTargets.end())
{
- std::string const dupEntry = dup->Option(IndexTarget::SOURCESENTRY);
- //TRANSLATOR: an identifier like Packages; Releasefile key indicating
- // a file like main/binary-amd64/Packages; filename and linenumber of
- // two sources.list entries
- _error->Warning(_("Target %s (%s) is configured multiple times in %s and %s"),
- T->c_str(), MetaKey.c_str(), dupEntry.c_str(), E->sourcesEntry.c_str());
- if (tplMetaKey.find("$(ARCHITECTURE)") == std::string::npos)
- break;
- continue;
+ auto const dup = std::find_if(IndexTargets.begin(), IndexTargets.end(), [&](IndexTarget const &T) {
+ return MetaKey == T.MetaKey && baseURI == T.Option(IndexTarget::BASE_URI) &&
+ E->sourcesEntry != T.Option(IndexTarget::SOURCESENTRY);
+ });
+ if (dup != IndexTargets.end())
+ {
+ std::string const dupEntry = dup->Option(IndexTarget::SOURCESENTRY);
+ //TRANSLATOR: an identifier like Packages; Releasefile key indicating
+ // a file like main/binary-amd64/Packages; filename and linenumber of
+ // two sources.list entries
+ _error->Warning(_("Target %s (%s) is configured multiple times in %s and %s"),
+ T->c_str(), MetaKey.c_str(), dupEntry.c_str(), E->sourcesEntry.c_str());
+ if (tplMetaKey.find(BreakPoint) == std::string::npos)
+ break;
+ continue;
+ }
}
- }
- // not available in templates, but in the indextarget
- Options.insert(std::make_pair("BASE_URI", baseURI));
- Options.insert(std::make_pair("REPO_URI", URI));
- Options.insert(std::make_pair("TARGET_OF", Type));
- Options.insert(std::make_pair("CREATED_BY", *T));
- Options.insert(std::make_pair("PDIFFS", UsePDiffs ? "yes" : "no"));
- Options.insert(std::make_pair("BY_HASH", UseByHash));
- Options.insert(std::make_pair("DEFAULTENABLED", DefaultEnabled ? "yes" : "no"));
- Options.insert(std::make_pair("COMPRESSIONTYPES", CompressionTypes));
- Options.insert(std::make_pair("KEEPCOMPRESSEDAS", KeepCompressedAs));
- Options.insert(std::make_pair("SOURCESENTRY", E->sourcesEntry));
-
- bool IsOpt = IsOptional;
- if (IsOpt == false)
- {
- auto const arch = Options.find("ARCHITECTURE");
- if (arch != Options.end() && arch->second == "all")
- IsOpt = true;
- }
+ // not available in templates, but in the indextarget
+ Options.insert(std::make_pair("BASE_URI", baseURI));
+ Options.insert(std::make_pair("REPO_URI", URI));
+ Options.insert(std::make_pair("IDENTIFIER", Identifier));
+ Options.insert(std::make_pair("TARGET_OF", Type));
+ Options.insert(std::make_pair("CREATED_BY", *T));
+ Options.insert(std::make_pair("FALLBACK_OF", FallbackOf));
+ Options.insert(std::make_pair("PDIFFS", UsePDiffs ? "yes" : "no"));
+ Options.insert(std::make_pair("BY_HASH", UseByHash));
+ Options.insert(std::make_pair("DEFAULTENABLED", DefaultEnabled ? "yes" : "no"));
+ Options.insert(std::make_pair("COMPRESSIONTYPES", CompressionTypes));
+ Options.insert(std::make_pair("KEEPCOMPRESSEDAS", KeepCompressedAs));
+ Options.insert(std::make_pair("SOURCESENTRY", E->sourcesEntry));
+
+ bool IsOpt = IsOptional;
+ if (IsOpt == false)
+ {
+ auto const arch = Options.find("ARCHITECTURE");
+ if (arch != Options.end() && arch->second == "all")
+ IsOpt = true;
+ }
- IndexTarget Target(
- MetaKey,
- ShortDesc,
- LongDesc,
- Options.find("BASE_URI")->second + MetaKey,
- IsOpt,
- KeepCompressed,
- Options
- );
- IndexTargets.push_back(Target);
+ IndexTarget Target(
+ MetaKey,
+ ShortDesc,
+ LongDesc,
+ Options.find("BASE_URI")->second + MetaKey,
+ IsOpt,
+ KeepCompressed,
+ Options
+ );
+ IndexTargets.push_back(Target);
+
+ if (tplMetaKey.find(BreakPoint) == std::string::npos)
+ break;
+ }
if (tplMetaKey.find("$(ARCHITECTURE)") == std::string::npos)
break;
@@ -601,16 +616,15 @@ bool debReleaseIndex::parseSumData(const char *&Start, const char *End, /*{{{*/
bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll)/*{{{*/
{
- std::vector<IndexTarget> const targets = GetIndexTargets();
#define APT_TARGET(X) IndexTarget("", X, MetaIndexInfo(X), MetaIndexURI(X), false, false, std::map<std::string,std::string>())
pkgAcqMetaClearSig * const TransactionManager = new pkgAcqMetaClearSig(Owner,
- APT_TARGET("InRelease"), APT_TARGET("Release"), APT_TARGET("Release.gpg"),
- targets, this);
+ APT_TARGET("InRelease"), APT_TARGET("Release"), APT_TARGET("Release.gpg"), this);
#undef APT_TARGET
// special case for --print-uris
if (GetAll)
- for (auto const &Target: targets)
- new pkgAcqIndex(Owner, TransactionManager, Target);
+ for (auto const &Target: GetIndexTargets())
+ if (Target.Option(IndexTarget::FALLBACK_OF).empty())
+ new pkgAcqIndex(Owner, TransactionManager, Target);
return true;
}
@@ -936,12 +950,40 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/
std::map<std::string, std::string>::const_iterator const opt = Options.find(target);
if (opt == Options.end())
continue;
- auto const tarItr = std::find(mytargets.begin(), mytargets.end(), target);
- bool const optValue = StringToBool(opt->second);
- if (optValue == true && tarItr == mytargets.end())
- mytargets.push_back(target);
- else if (optValue == false && tarItr != mytargets.end())
- mytargets.erase(std::remove(mytargets.begin(), mytargets.end(), target), mytargets.end());
+ auto const idMatch = [&](std::string const &t) {
+ return target == _config->Find(std::string("Acquire::IndexTargets::") + Name + "::" + t + "::Identifier", t);
+ };
+ if (StringToBool(opt->second))
+ std::copy_if(alltargets.begin(), alltargets.end(), std::back_inserter(mytargets), idMatch);
+ else
+ mytargets.erase(std::remove_if(mytargets.begin(), mytargets.end(), idMatch), mytargets.end());
+ }
+ // if we can't order it in a 1000 steps we give up… probably a cycle
+ for (auto i = 0; i < 1000; ++i)
+ {
+ bool Changed = false;
+ for (auto t = mytargets.begin(); t != mytargets.end(); ++t)
+ {
+ std::string const fallback = _config->Find(std::string("Acquire::IndexTargets::") + Name + "::" + *t + "::Fallback-Of");
+ if (fallback.empty())
+ continue;
+ auto const faller = std::find(mytargets.begin(), mytargets.end(), fallback);
+ if (faller == mytargets.end() || faller < t)
+ continue;
+ Changed = true;
+ auto const tv = *t;
+ mytargets.erase(t);
+ mytargets.emplace_back(tv);
+ }
+ if (Changed == false)
+ break;
+ }
+ // remove duplicates without changing the order (in first appearance)
+ {
+ std::set<std::string> seenOnce;
+ mytargets.erase(std::remove_if(mytargets.begin(), mytargets.end(), [&](std::string const &t) {
+ return seenOnce.insert(t).second == false;
+ }), mytargets.end());
}
bool UsePDiffs = _config->FindB("Acquire::PDiffs", true);
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index 834cb0e25..76a81bb33 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -1501,6 +1501,13 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
_exit(100);
}
+ // if color support isn't enabled/disabled explicitly tell
+ // dpkg to use the same state apt is using for its color support
+ if (_config->FindB("APT::Color", false) == true)
+ setenv("DPKG_COLORS", "always", 0);
+ else
+ setenv("DPKG_COLORS", "never", 0);
+
execvp(Args[0], (char**) &Args[0]);
cerr << "Could not exec dpkg!" << endl;
_exit(100);
diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc
index 610f9379e..77928379f 100644
--- a/apt-pkg/edsp.cc
+++ b/apt-pkg/edsp.cc
@@ -176,6 +176,24 @@ static void WriteScenarioLimitedDependency(FILE* output,
fprintf(output, "Provides: %s\n", provides.c_str()+2);
}
/*}}}*/
+static bool SkipUnavailableVersions(pkgDepCache &Cache, pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const &Ver)/*{{{*/
+{
+ /* versions which aren't current and aren't available in
+ any "online" source file are bad, expect if they are the choosen
+ candidate: The exception is for build-dep implementation as it creates
+ such pseudo (package) versions and removes them later on again.
+ We filter out versions at all so packages in 'rc' state only available
+ in dpkg/status aren't passed to solvers as they can't be installed. */
+ if (Pkg->CurrentVer != 0)
+ return false;
+ if (Cache.GetCandidateVersion(Pkg) == Ver)
+ return false;
+ for (pkgCache::VerFileIterator I = Ver.FileList(); I.end() == false; ++I)
+ if (I.File().Flagged(pkgCache::Flag::NotSource) == false)
+ return false;
+ return true;
+}
+ /*}}}*/
// EDSP::WriteScenario - to the given file descriptor /*{{{*/
bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress)
{
@@ -190,6 +208,8 @@ bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress)
continue;
for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver, ++p)
{
+ if (SkipUnavailableVersions(Cache, Pkg, Ver))
+ continue;
WriteScenarioVersion(Cache, output, Pkg, Ver);
WriteScenarioDependency(output, Ver);
fprintf(output, "\n");
@@ -211,6 +231,8 @@ bool EDSP::WriteLimitedScenario(pkgDepCache &Cache, FILE* output,
for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg, ++p)
for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
{
+ if (SkipUnavailableVersions(Cache, Pkg, Ver))
+ continue;
WriteScenarioVersion(Cache, output, Pkg, Ver);
WriteScenarioLimitedDependency(output, Ver, pkgset);
fprintf(output, "\n");
diff --git a/apt-pkg/indexfile.cc b/apt-pkg/indexfile.cc
index a777c38ac..7ded0101b 100644
--- a/apt-pkg/indexfile.cc
+++ b/apt-pkg/indexfile.cc
@@ -137,8 +137,10 @@ std::string IndexTarget::Option(OptionKeys const EnumKey) const /*{{{*/
APT_CASE(ARCHITECTURE);
APT_CASE(BASE_URI);
APT_CASE(REPO_URI);
+ APT_CASE(IDENTIFIER);
APT_CASE(TARGET_OF);
APT_CASE(CREATED_BY);
+ APT_CASE(FALLBACK_OF);
APT_CASE(PDIFFS);
APT_CASE(DEFAULTENABLED);
APT_CASE(COMPRESSIONTYPES);
diff --git a/apt-pkg/indexfile.h b/apt-pkg/indexfile.h
index 5c666671c..76a3d069e 100644
--- a/apt-pkg/indexfile.h
+++ b/apt-pkg/indexfile.h
@@ -91,6 +91,8 @@ class IndexTarget /*{{{*/
SOURCESENTRY,
BY_HASH,
KEEPCOMPRESSEDAS,
+ FALLBACK_OF,
+ IDENTIFIER,
};
std::string Option(OptionKeys const Key) const;
bool OptionBool(OptionKeys const Key) const;