summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/acquire-item.cc3
-rw-r--r--apt-pkg/acquire-worker.cc42
-rw-r--r--apt-pkg/acquire.cc59
-rw-r--r--apt-pkg/deb/dpkgpm.cc25
-rw-r--r--apt-pkg/sourcelist.cc3
5 files changed, 78 insertions, 54 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index 88b5a58b5..91d7a3eae 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -3279,9 +3279,8 @@ bool pkgAcqArchive::QueueNext()
// Create the item
Local = false;
- QueueURI(Desc);
-
++Vf;
+ QueueURI(Desc);
return true;
}
return false;
diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc
index 7afbec72a..7d6e6f79c 100644
--- a/apt-pkg/acquire-worker.cc
+++ b/apt-pkg/acquire-worker.cc
@@ -661,55 +661,15 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
if (OutFd == -1)
return false;
- HashStringList const hsl = Item->GetExpectedHashes();
-
if (isDoomedItem(Item->Owner))
return true;
- if (hsl.usable() == false && Item->Owner->HashesRequired() &&
- _config->Exists("Acquire::ForceHash") == false)
- {
- std::string const Message = "400 URI Failure"
- "\nURI: " + Item->URI +
- "\nFilename: " + Item->Owner->DestFile +
- "\nFailReason: WeakHashSums";
-
- auto const ItmOwners = Item->Owners;
- for (auto &O: ItmOwners)
- {
- O->Status = pkgAcquire::Item::StatAuthError;
- O->Failed(Message, Config);
- if (Log != nullptr)
- Log->Fail(O->GetItemDesc());
- }
- // "queued" successfully, the item just instantly failed
- return true;
- }
-
- if (Item->Owner->IsRedirectionLoop(Item->URI))
- {
- std::string const Message = "400 URI Failure"
- "\nURI: " + Item->URI +
- "\nFilename: " + Item->Owner->DestFile +
- "\nFailReason: RedirectionLoop";
-
- auto const ItmOwners = Item->Owners;
- for (auto &O: ItmOwners)
- {
- O->Status = pkgAcquire::Item::StatError;
- O->Failed(Message, Config);
- if (Log != nullptr)
- Log->Fail(O->GetItemDesc());
- }
- // "queued" successfully, the item just instantly failed
- return true;
- }
-
string Message = "600 URI Acquire\n";
Message.reserve(300);
Message += "URI: " + Item->URI;
Message += "\nFilename: " + Item->Owner->DestFile;
+ HashStringList const hsl = Item->GetExpectedHashes();
for (HashStringList::const_iterator hs = hsl.begin(); hs != hsl.end(); ++hs)
Message += "\nExpected-" + hs->HashType() + ": " + hs->HashValue();
diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc
index b5f88e1b3..b4d1b5959 100644
--- a/apt-pkg/acquire.cc
+++ b/apt-pkg/acquire.cc
@@ -269,6 +269,42 @@ void pkgAcquire::Remove(Worker *Work)
it is constructed which creates a queue (based on the current queue
mode) and puts the item in that queue. If the system is running then
the queue might be started. */
+static bool CheckForBadItemAndFailIt(pkgAcquire::Item * const Item,
+ pkgAcquire::MethodConfig const * const Config, pkgAcquireStatus * const Log)
+{
+ auto SavedDesc = Item->GetItemDesc();
+ if (Item->IsRedirectionLoop(SavedDesc.URI))
+ {
+ std::string const Message = "400 URI Failure"
+ "\nURI: " + SavedDesc.URI +
+ "\nFilename: " + Item->DestFile +
+ "\nFailReason: RedirectionLoop";
+
+ Item->Status = pkgAcquire::Item::StatError;
+ Item->Failed(Message, Config);
+ if (Log != nullptr)
+ Log->Fail(SavedDesc);
+ return true;
+ }
+
+ HashStringList const hsl = Item->GetExpectedHashes();
+ if (hsl.usable() == false && Item->HashesRequired() &&
+ _config->Exists("Acquire::ForceHash") == false)
+ {
+ std::string const Message = "400 URI Failure"
+ "\nURI: " + SavedDesc.URI +
+ "\nFilename: " + Item->DestFile +
+ "\nFailReason: WeakHashSums";
+
+ auto SavedDesc = Item->GetItemDesc();
+ Item->Status = pkgAcquire::Item::StatAuthError;
+ Item->Failed(Message, Config);
+ if (Log != nullptr)
+ Log->Fail(SavedDesc);
+ return true;
+ }
+ return false;
+}
void pkgAcquire::Enqueue(ItemDesc &Item)
{
// Determine which queue to put the item in
@@ -277,6 +313,13 @@ void pkgAcquire::Enqueue(ItemDesc &Item)
if (Name.empty() == true)
return;
+ /* the check for running avoids that we produce errors
+ in logging before we actually have started, which would
+ be easier to implement but would confuse users/implementations
+ so we check the items skipped here in #Startup */
+ if (Running && CheckForBadItemAndFailIt(Item.Owner, Config, Log))
+ return;
+
// Find the queue structure
Queue *I = Queues;
for (; I != 0 && I->Name != Name; I = I->Next);
@@ -912,10 +955,20 @@ bool pkgAcquire::Queue::Startup()
if (Workers == 0)
{
URI U(Name);
- pkgAcquire::MethodConfig *Cnf = Owner->GetConfig(U.Access);
- if (Cnf == 0)
+ pkgAcquire::MethodConfig * const Cnf = Owner->GetConfig(U.Access);
+ if (unlikely(Cnf == nullptr))
return false;
-
+
+ // now-running twin of the pkgAcquire::Enqueue call
+ for (QItem *I = Items; I != 0; )
+ {
+ auto const INext = I->Next;
+ for (auto &&O: I->Owners)
+ CheckForBadItemAndFailIt(O, Cnf, Owner->Log);
+ // if an item failed, it will be auto-dequeued invalidation our I here
+ I = INext;
+ }
+
Workers = new Worker(this,Cnf,Owner->Log);
Owner->Add(Workers);
if (Workers->Start() == false)
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index 0ac74d479..9d1739d68 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -1341,10 +1341,16 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
std::distance(List.cbegin(), List.cend());
ExpandPendingCalls(List, Cache);
- auto const StripAlreadyDoneFromPending = [&](APT::VersionVector & Pending) {
+ /* if dpkg told us that it has already done everything to the package we wanted it to do,
+ we shouldn't ask it for "more" later. That can e.g. happen if packages without conffiles
+ are purged as they will have pass through the purge states on remove already */
+ auto const StripAlreadyDoneFrom = [&](APT::VersionVector & Pending) {
Pending.erase(std::remove_if(Pending.begin(), Pending.end(), [&](pkgCache::VerIterator const &Ver) {
auto const PN = Ver.ParentPkg().FullName();
- return PackageOps[PN].size() <= PackageOpsDone[PN];
+ auto const POD = PackageOpsDone.find(PN);
+ if (POD == PackageOpsDone.end())
+ return false;
+ return PackageOps[PN].size() <= POD->second;
}), Pending.end());
};
@@ -1677,7 +1683,9 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
{
if (I->File[0] != '/')
return _error->Error("Internal Error, Pathname to install is not absolute '%s'",I->File.c_str());
- auto const file = flNotDir(I->File);
+ auto file = flNotDir(I->File);
+ if (flExtension(file) != "deb")
+ file.append(".deb");
std::string linkpath;
if (dpkg_recursive_install_numbered)
strprintf(linkpath, "%s/%.*lu-%s", tmpdir_to_free, p, n, file.c_str());
@@ -1703,7 +1711,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
else if (I->Op == Item::RemovePending)
{
++I;
- StripAlreadyDoneFromPending(approvedStates.Remove());
+ StripAlreadyDoneFrom(approvedStates.Remove());
if (approvedStates.Remove().empty())
continue;
}
@@ -1712,7 +1720,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
++I;
// explicit removes of packages without conffiles passthrough the purge states instantly, too.
// Setting these non-installed packages up for purging generates 'unknown pkg' warnings from dpkg
- StripAlreadyDoneFromPending(approvedStates.Purge());
+ StripAlreadyDoneFrom(approvedStates.Purge());
if (approvedStates.Purge().empty())
continue;
std::remove_reference<decltype(approvedStates.Remove())>::type approvedRemoves;
@@ -1964,8 +1972,8 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
if (d->dpkg_error.empty() == false)
{
// no point in reseting packages we already completed removal for
- StripAlreadyDoneFromPending(approvedStates.Remove());
- StripAlreadyDoneFromPending(approvedStates.Purge());
+ StripAlreadyDoneFrom(approvedStates.Remove());
+ StripAlreadyDoneFrom(approvedStates.Purge());
APT::StateChanges undo;
auto && undoRem = approvedStates.Remove();
std::move(undoRem.begin(), undoRem.end(), std::back_inserter(undo.Install()));
@@ -1975,6 +1983,9 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
if (undo.Save(false) == false)
_error->Error("Couldn't revert dpkg selection for approved remove/purge after an error was encountered!");
}
+
+ StripAlreadyDoneFrom(currentStates.Remove());
+ StripAlreadyDoneFrom(currentStates.Purge());
if (currentStates.Save(false) == false)
_error->Error("Couldn't restore dpkg selection states which were present before this interaction!");
diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc
index cfd824978..0da687895 100644
--- a/apt-pkg/sourcelist.cc
+++ b/apt-pkg/sourcelist.cc
@@ -568,7 +568,8 @@ bool pkgSourceList::AddVolatileFile(std::string const &File, std::vector<std::st
return false;
std::string const ext = flExtension(File);
- if (ext == "deb")
+ // udeb is not included as installing it is usually a mistake rather than intended
+ if (ext == "deb" || ext == "ddeb")
AddVolatileFile(new debDebPkgFileIndex(File));
else if (ext == "dsc")
AddVolatileFile(new debDscFileIndex(File));