X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/a6ae3d3df490e7a5a1c8324ba9dc2e63972b1529..422a2eba84361a8dfd84b549c13037512779c572:/apt-pkg/deb/dpkgpm.cc diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 5759e6ba5..9d1739d68 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -61,6 +61,8 @@ #include /*}}}*/ +extern char **environ; + using namespace std; APT_PURE static string AptHistoryRequestingUser() /*{{{*/ @@ -1339,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()); }; @@ -1535,9 +1543,13 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) if (I.Op == Item::Remove || I.Op == Item::Purge) toBeRemoved[I.Pkg->ID] = false; - if (std::find(toBeRemoved.begin(), toBeRemoved.end(), true) != toBeRemoved.end()) + bool const RemovePending = std::find(toBeRemoved.begin(), toBeRemoved.end(), true) != toBeRemoved.end(); + bool const PurgePending = approvedStates.Purge().empty() == false; + if (RemovePending != false || PurgePending != false) + List.emplace_back(Item::ConfigurePending, pkgCache::PkgIterator()); + if (RemovePending) List.emplace_back(Item::RemovePending, pkgCache::PkgIterator()); - if (approvedStates.Purge().empty() == false) + if (PurgePending) List.emplace_back(Item::PurgePending, pkgCache::PkgIterator()); // support subpressing of triggers processing for special @@ -1606,7 +1618,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) unsigned long const Op = I->Op; if (NoTriggers == true && I->Op != Item::TriggersPending && - I->Op != Item::ConfigurePending) + (I->Op != Item::ConfigurePending || std::next(I) != List.end())) { ADDARGC("--no-triggers"); } @@ -1671,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()); @@ -1697,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; } @@ -1706,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::type approvedRemoves; @@ -1958,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())); @@ -1969,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!");