Commit 0329b6ee authored by Lorenzo "Palinuro" Faletra's avatar Lorenzo "Palinuro" Faletra Committed by Lorenzo "Palinuro" Faletra

Import Debian version 2.1.7+parrot1

apt (2.1.7+parrot1) rolling-testing; urgency=medium

  * Import new Debian version.
  * Re-enable https-to-http redirects.

apt (2.1.7) unstable; urgency=medium

  [ David Kalnischkies ]
  * Do not hardcode (wrong) group and mode in setup warning (Closes: #962310)
  * Do not sent our filename-provides trick to EDSP solvers (Closes: #962741)
  * Tell EDSP solvers about all installed pkgs ignoring arch
  * Deduplicate EDSP Provides line of M-A:foreign packages
  * Delay removals due to Conflicts until Depends are resolved
  * Filter out impossible solutions for protected propagation
  * Add dependency points in the resolver also to providers
  * Reorder config check before checking systemd for non-interactive http
  * Reorder config check before result looping for SRV parsing debug
  * Fix test due to display change in ls (coreutils 8.32)
  * Detect pkg-config-dpkghook failure in tests to avoid fallback (Closes: #964475)

  [ Américo Monteiro ]
  * Portuguese manpages translation update (Closes: #962483)

  [ Julian Andres Klode ]
  * Replace some magic 64*1024 with APT_BUFFER_SIZE
  * Add basic support for the Protected field

  [ Sergio Oller Moreno ]
  * Minor Catalan grammar typo

  [ Frans Spiesschaert ]
  * Dutch program translation update (Closes: #963008)

apt (2.1.6) unstable; urgency=medium

  [ David Kalnischkies ]
  * Fix small memory leak in MethodConfig
  * Consider protected packages for removal if they are marked as such
  * Consider if a fix is successful before claiming it is
  * Allow 20 instead of 10 loops for pkgProblemResolver
  * Deal with duplicates in the solution space of a dep

apt (2.1.5) unstable; urgency=medium

  [ David Kalnischkies ]
  * Reset candidate version explicitly for internal state-keeping
    (Closes: #961266)
  * Known-bad candidate versions are not an upgrade option
  * Keep status number if candidate is discarded for kept back display
  * Allow pkgDepCache to be asked to check internal consistency
  * Don't update candidate provides map if the same as current
  * Ensure EDSP doesn't use a dangling architecture string
  * Allow FMV SSE4.2 detection to succeed on clang
  * Mark PatternTreeParser::Node destructor as virtual

  [ Frans Spiesschaert ]
  * Dutch manpages translation update (Closes: #961431)

apt (2.1.4) unstable; urgency=medium

  [ David Kalnischkies ]
  * Check satisfiability for versioned provides, not providing version

apt (2.1.3) unstable; urgency=medium

  [ David Kalnischkies ]
  * Prefer use of O_TMPFILE in GetTempFile if available
  * Allow prefix to be a complete filename for GetTempFile
  * Properly handle interrupted write() call in ExtractTar
  * Skip reading data from tar members if nobody will look at it
  * Keep going if a dep is bad for user requests to improve errors
  * Support negative dependencies in VCI::FromDependency
  * Deal with protected solution providers first
  * Propagate protected to already satisfied conflicts (Closes: #960705)
  * Propagate protected to already satisfied dependencies
  * Recognize propagated protected in pkgProblemResolver

  [ Julian Andres Klode ]
  * private-search: Only use V.TranslatedDescription() if good (LP: #1877987)

apt (2.1.2) unstable; urgency=critical

  [ Julian Andres Klode ]
  * SECURITY UPDATE: Out of bounds read in ar, tar implementations (LP: #1878177)
    - apt-pkg/contrib/arfile.cc: Fix out-of-bounds read in member name
    - apt-pkg/contrib/arfile.cc: Fix out-of-bounds read on unterminated
      member names in error path
    - apt-pkg/contrib/extracttar.cc: Fix out-of-bounds read on unterminated
      member names in error path
    - CVE-2020-3810

  [ Frans Spiesschaert ]
  * Dutch program translation update (Closes: #960186)
parent e725fd69
Pipeline #648 failed with stages
......@@ -25,11 +25,12 @@
# SOFTWARE.
include(CheckCXXSourceCompiles)
function(check_cxx_target var target code)
check_cxx_source_compiles(
"
__attribute__((target(\"${target}\"))) static int foo() { ${code} return 1; }
__attribute__((target(\"default\"))) static int foo() { ${code} return 0; }
int main() { return foo(); }
__attribute__((target(\"${target}\"))) static int foo(int i) { return ${code}; }
__attribute__((target(\"default\"))) static int foo(int i) { return i; }
int main(int i, char **) { return foo(i); }
" ${var})
endfunction()
......@@ -2,6 +2,9 @@
/* Internationalization macros for apt. This header should be included last
in each C file. */
#ifndef APT_I18N_H
#define APT_I18N_H
// Set by autoconf
#cmakedefine USE_NLS
......@@ -19,11 +22,13 @@
# define N_(x) x
#else
// apt will not use any gettext
# define setlocale(a, b)
# define textdomain(a)
# define bindtextdomain(a, b)
extern "C" inline char* setlocale(int, const char*) throw() { return nullptr; }
extern "C" inline char* textdomain(const char*) throw() { return nullptr; }
extern "C" inline char* bindtextdomain(const char*, const char*) throw() { return nullptr; }
extern "C" inline char* dgettext(const char*, const char* msg) throw() { return const_cast<char*>(msg); }
# define _(x) x
# define P_(msg,plural,n) (n == 1 ? msg : plural)
# define N_(x) x
# define dgettext(d, m) m
#endif
#endif
......@@ -198,13 +198,13 @@ endif()
# Check multiversioning
include(CheckCxxTarget)
check_cxx_target(HAVE_FMV_SSE42_AND_CRC32 "sse4.2" "__builtin_ia32_crc32si(0, 1llu);")
check_cxx_target(HAVE_FMV_SSE42_AND_CRC32DI "sse4.2" "__builtin_ia32_crc32di(0, 1llu);")
check_cxx_target(HAVE_FMV_SSE42_AND_CRC32 "sse4.2" "__builtin_ia32_crc32si(0,i)|__builtin_ia32_crc32hi(0,i)|__builtin_ia32_crc32qi(0,i)")
check_cxx_target(HAVE_FMV_SSE42_AND_CRC32DI "sse4.2" "__builtin_ia32_crc32di(0,i)")
# Configure some variables like package, version and architecture.
set(PACKAGE ${PROJECT_NAME})
set(PACKAGE_MAIL "APT Development Team <deity@lists.debian.org>")
set(PACKAGE_VERSION "2.1.1")
set(PACKAGE_VERSION "2.1.7")
string(REGEX MATCH "^[0-9.]+" PROJECT_VERSION ${PACKAGE_VERSION})
if (NOT DEFINED DPKG_DATADIR)
......
......@@ -105,18 +105,18 @@ static bool SetupAPTPartialDirectory(std::string const &grand, std::string const
{
// chown the partial dir
if(chown(partial.c_str(), pw->pw_uid, gr->gr_gid) != 0)
_error->WarningE("SetupAPTPartialDirectory", "chown to %s:root of directory %s failed", SandboxUser.c_str(), partial.c_str());
_error->WarningE("SetupAPTPartialDirectory", "chown to %s:%s of directory %s failed", SandboxUser.c_str(), ROOT_GROUP, partial.c_str());
}
}
if (chmod(partial.c_str(), mode) != 0)
_error->WarningE("SetupAPTPartialDirectory", "chmod 0700 of directory %s failed", partial.c_str());
_error->WarningE("SetupAPTPartialDirectory", "chmod 0%03o of directory %s failed", mode, partial.c_str());
}
else if (chmod(partial.c_str(), mode) != 0)
{
// if we haven't created the dir and aren't root, it is kinda expected that chmod doesn't work
if (partialExists == false)
_error->WarningE("SetupAPTPartialDirectory", "chmod 0700 of directory %s failed", partial.c_str());
_error->WarningE("SetupAPTPartialDirectory", "chmod 0%03o of directory %s failed", mode, partial.c_str());
}
_error->PushToStack();
......@@ -1474,5 +1474,5 @@ pkgAcquire::UriIterator::UriIterator(pkgAcquire::Queue *Q) : d(NULL), CurQ(Q), C
}
pkgAcquire::UriIterator::~UriIterator() {}
pkgAcquire::MethodConfig::~MethodConfig() {}
pkgAcquire::MethodConfig::~MethodConfig() { delete d; }
pkgAcquireStatus::~pkgAcquireStatus() {}
This diff is collapsed.
......@@ -48,6 +48,7 @@ struct APT_PUBLIC PatternTreeParser
virtual std::ostream &render(std::ostream &os) { return os; };
std::nullptr_t error(std::string message);
virtual ~Node() = default;
};
struct Error : public std::exception
......
......@@ -583,74 +583,54 @@ bool VersionContainerInterface::FromDependency(VersionContainerInterface * const
CacheSetHelper &helper)
{
bool found = false;
switch(selector) {
case CacheSetHelper::ALL:
{
pkgCache::PkgIterator const T = D.TargetPkg();
for (pkgCache::VerIterator Ver = T.VersionList(); Ver.end() == false; ++Ver)
auto const insertVersion = [&](pkgCache::PkgIterator const &TP, pkgCache::VerIterator const &TV) {
if (not TV.end() && not D.IsIgnorable(TP) && D.IsSatisfied(TV))
{
if (D.IsSatisfied(Ver) == true)
{
vci->insert(Ver);
found = true;
}
for (pkgCache::PrvIterator Prv = T.ProvidesList(); Prv.end() != true; ++Prv)
vci->insert(TV);
found = true;
}
};
pkgCache::PkgIterator const T = D.TargetPkg();
auto const insertAllTargetVersions = [&](auto const &getTargetVersion) {
insertVersion(T, getTargetVersion(T));
for (auto Prv = T.ProvidesList(); not Prv.end(); ++Prv)
{
if (D.IsIgnorable(Prv))
continue;
auto const OP = Prv.OwnerPkg();
auto const TV = getTargetVersion(OP);
if (Prv.OwnerVer() == TV && D.IsSatisfied(Prv))
{
pkgCache::VerIterator const V = Prv.OwnerVer();
if (unlikely(V.end() == true) || D.IsSatisfied(Prv) == false)
continue;
vci->insert(V);
vci->insert(TV);
found = true;
}
}
return found;
}
};
switch(selector) {
case CacheSetHelper::ALL:
for (auto Ver = T.VersionList(); not Ver.end(); ++Ver)
{
insertVersion(T, Ver);
for (pkgCache::PrvIterator Prv = T.ProvidesList(); not Prv.end(); ++Prv)
if (not D.IsIgnorable(Prv))
{
vci->insert(Prv.OwnerVer());
found = true;
}
}
return found;
case CacheSetHelper::CANDANDINST:
{
found = FromDependency(vci, Cache, D, CacheSetHelper::CANDIDATE, helper);
found &= FromDependency(vci, Cache, D, CacheSetHelper::INSTALLED, helper);
return found;
}
case CacheSetHelper::CANDIDATE:
{
pkgCache::PkgIterator const T = D.TargetPkg();
pkgCache::VerIterator const Cand = Cache[T].CandidateVerIter(Cache);
if (Cand.end() == false && D.IsSatisfied(Cand) == true)
{
vci->insert(Cand);
found = true;
}
for (pkgCache::PrvIterator Prv = T.ProvidesList(); Prv.end() != true; ++Prv)
{
pkgCache::VerIterator const V = Prv.OwnerVer();
pkgCache::VerIterator const Cand = Cache[Prv.OwnerPkg()].CandidateVerIter(Cache);
if (Cand.end() == true || V != Cand || D.IsSatisfied(Prv) == false)
continue;
vci->insert(Cand);
found = true;
}
return found;
}
// skip looking if we have already cached that we will find nothing
if (((Cache[D] & pkgDepCache::DepCVer) == 0) != D.IsNegative())
return found;
return insertAllTargetVersions([&](pkgCache::PkgIterator const &OP) { return Cache[OP].CandidateVerIter(Cache); });
case CacheSetHelper::INSTALLED:
{
pkgCache::PkgIterator const T = D.TargetPkg();
pkgCache::VerIterator const Cand = T.CurrentVer();
if (Cand.end() == false && D.IsSatisfied(Cand) == true)
{
vci->insert(Cand);
found = true;
}
for (pkgCache::PrvIterator Prv = T.ProvidesList(); Prv.end() != true; ++Prv)
{
pkgCache::VerIterator const V = Prv.OwnerVer();
pkgCache::VerIterator const Cand = Prv.OwnerPkg().CurrentVer();
if (Cand.end() == true || V != Cand || D.IsSatisfied(Prv) == false)
continue;
vci->insert(Cand);
found = true;
}
return found;
}
return insertAllTargetVersions([&](pkgCache::PkgIterator const &OP) { return OP.CurrentVer(); });
case CacheSetHelper::CANDINST:
return FromDependency(vci, Cache, D, CacheSetHelper::CANDIDATE, helper) ||
FromDependency(vci, Cache, D, CacheSetHelper::INSTALLED, helper);
......@@ -658,25 +638,7 @@ bool VersionContainerInterface::FromDependency(VersionContainerInterface * const
return FromDependency(vci, Cache, D, CacheSetHelper::INSTALLED, helper) ||
FromDependency(vci, Cache, D, CacheSetHelper::CANDIDATE, helper);
case CacheSetHelper::NEWEST:
{
pkgCache::PkgIterator const T = D.TargetPkg();
pkgCache::VerIterator const Cand = T.VersionList();
if (Cand.end() == false && D.IsSatisfied(Cand) == true)
{
vci->insert(Cand);
found = true;
}
for (pkgCache::PrvIterator Prv = T.ProvidesList(); Prv.end() != true; ++Prv)
{
pkgCache::VerIterator const V = Prv.OwnerVer();
pkgCache::VerIterator const Cand = Prv.OwnerPkg().VersionList();
if (Cand.end() == true || V != Cand || D.IsSatisfied(Prv) == false)
continue;
vci->insert(Cand);
found = true;
}
return found;
}
return insertAllTargetVersions([&](pkgCache::PkgIterator const &OP) { return OP.VersionList(); });
case CacheSetHelper::RELEASE:
case CacheSetHelper::VERSIONNUMBER:
// both make no sense here, so always false
......
......@@ -92,7 +92,7 @@ bool ARArchive::LoadHeaders()
StrToNum(Head.Size,Memb->Size,sizeof(Head.Size)) == false)
{
delete Memb;
return _error->Error(_("Invalid archive member header %s"), Head.Name);
return _error->Error(_("Invalid archive member header"));
}
// Check for an extra long name string
......@@ -119,7 +119,14 @@ bool ARArchive::LoadHeaders()
else
{
unsigned int I = sizeof(Head.Name) - 1;
for (; Head.Name[I] == ' ' || Head.Name[I] == '/'; I--);
for (; Head.Name[I] == ' ' || Head.Name[I] == '/'; I--)
{
if (I == 0)
{
delete Memb;
return _error->Error(_("Invalid archive member header"));
}
}
Memb->Name = std::string(Head.Name,I+1);
}
......
......@@ -254,53 +254,53 @@ bool ExtractTar::Go(pkgDirStream &Stream)
default:
BadRecord = true;
_error->Warning(_("Unknown TAR header type %u, member %s"),(unsigned)Tar->LinkFlag,Tar->Name);
_error->Warning(_("Unknown TAR header type %u"), (unsigned)Tar->LinkFlag);
break;
}
int Fd = -1;
if (BadRecord == false)
if (Stream.DoItem(Itm,Fd) == false)
if (not BadRecord && not Stream.DoItem(Itm, Fd))
return false;
if (Fd == -1 || Fd < -2 || BadRecord)
{
if (Itm.Size > 0 && not InFd.Skip(((Itm.Size + (sizeof(Block) - 1)) / sizeof(Block)) * sizeof(Block)))
return false;
// Copy the file over the FD
unsigned long long Size = Itm.Size;
while (Size != 0)
}
else if (Itm.Size != 0)
{
// Copy the file over the FD
auto Size = Itm.Size;
unsigned char Junk[32*1024];
unsigned long Read = min(Size, (unsigned long long)sizeof(Junk));
if (InFd.Read(Junk,((Read+511)/512)*512) == false)
return false;
if (BadRecord == false)
do
{
auto const Read = std::min<unsigned long long>(Size, sizeof(Junk));
if (not InFd.Read(Junk, ((Read + (sizeof(Block) - 1)) / sizeof(Block)) * sizeof(Block)))
return false;
if (Fd > 0)
{
if (write(Fd,Junk,Read) != (signed)Read)
return Stream.Fail(Itm,Fd);
if (not FileFd::Write(Fd, Junk, Read))
return Stream.Fail(Itm, Fd);
}
else
// An Fd of -2 means to send to a special processing function
else if (Fd == -2)
{
/* An Fd of -2 means to send to a special processing
function */
if (Fd == -2)
if (Stream.Process(Itm,Junk,Read,Itm.Size - Size) == false)
return Stream.Fail(Itm,Fd);
if (not Stream.Process(Itm, Junk, Read, Itm.Size - Size))
return Stream.Fail(Itm, Fd);
}
}
Size -= Read;
Size -= Read;
} while (Size != 0);
}
// And finish up
if (BadRecord == false)
if (Stream.FinishedFile(Itm,Fd) == false)
return false;
if (not BadRecord && not Stream.FinishedFile(Itm, Fd))
return false;
LastLongName.erase();
LastLongLink.erase();
}
return Done();
}
/*}}}*/
......@@ -3150,30 +3150,49 @@ FileFd* GetTempFile(std::string const &Prefix, bool ImmediateUnlink, FileFd * co
}
FileFd* GetTempFile(std::string const &Prefix, bool ImmediateUnlink, FileFd * const TmpFd, bool Buffered)
{
char fn[512];
FileFd * const Fd = TmpFd == nullptr ? new FileFd() : TmpFd;
std::string fn;
std::string const tempdir = GetTempDir();
snprintf(fn, sizeof(fn), "%s/%s.XXXXXX",
tempdir.c_str(), Prefix.c_str());
int const fd = mkstemp(fn);
int fd = -1;
#ifdef O_TMPFILE
if (ImmediateUnlink)
unlink(fn);
fd = open(tempdir.c_str(), O_RDWR|O_TMPFILE|O_EXCL|O_CLOEXEC, 0600);
if (fd < 0)
#endif
{
_error->Errno("GetTempFile",_("Unable to mkstemp %s"), fn);
if (TmpFd == nullptr)
delete Fd;
auto const suffix = Prefix.find(".XXXXXX.");
std::vector<char> buffer(tempdir.length() + 1 + Prefix.length() + (suffix == std::string::npos ? 7 : 0) + 1, '\0');
if (suffix != std::string::npos)
{
if (snprintf(buffer.data(), buffer.size(), "%s/%s", tempdir.c_str(), Prefix.c_str()) > 0)
{
ssize_t const suffixlen = (buffer.size() - 1) - (tempdir.length() + 1 + suffix + 7);
if (likely(suffixlen > 0))
fd = mkstemps(buffer.data(), suffixlen);
}
}
else
{
if (snprintf(buffer.data(), buffer.size(), "%s/%s.XXXXXX", tempdir.c_str(), Prefix.c_str()) > 0)
fd = mkstemp(buffer.data());
}
fn.assign(buffer.data(), buffer.size() - 1);
if (ImmediateUnlink && fd != -1)
unlink(fn.c_str());
}
if (fd < 0)
{
_error->Errno("GetTempFile",_("Unable to mkstemp %s"), fn.c_str());
return nullptr;
}
if (!Fd->OpenDescriptor(fd, FileFd::ReadWrite | (Buffered ? FileFd::BufferedWrite : 0), FileFd::None, true))
FileFd * const Fd = TmpFd == nullptr ? new FileFd() : TmpFd;
if (not Fd->OpenDescriptor(fd, FileFd::ReadWrite | (Buffered ? FileFd::BufferedWrite : 0), FileFd::None, true))
{
_error->Errno("GetTempFile",_("Unable to write to %s"),fn);
_error->Errno("GetTempFile",_("Unable to write to %s"),fn.c_str());
if (TmpFd == nullptr)
delete Fd;
return nullptr;
}
if (ImmediateUnlink == false)
if (not ImmediateUnlink)
Fd->SetFileName(fn);
return Fd;
}
......
......@@ -137,17 +137,12 @@ bool GetSrvRecords(std::string name, std::vector<SrvRec> &Result)
// sort them by priority
std::stable_sort(Result.begin(), Result.end());
for(std::vector<SrvRec>::iterator I = Result.begin();
I != Result.end(); ++I)
{
if (_config->FindB("Debug::Acquire::SrvRecs", false) == true)
{
std::cerr << "SrvRecs: got " << I->target
<< " prio: " << I->priority
<< " weight: " << I->weight
<< std::endl;
}
}
if (_config->FindB("Debug::Acquire::SrvRecs", false))
for(auto const &R : Result)
std::cerr << "SrvRecs: got " << R.target
<< " prio: " << R.priority
<< " weight: " << R.weight
<< '\n';
return true;
}
......
......@@ -318,6 +318,8 @@ bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg,
return false;
if (Section.FindFlag(pkgTagSection::Key::Important,Pkg->Flags,pkgCache::Flag::Important) == false)
return false;
if (Section.FindFlag(pkgTagSection::Key::Protected, Pkg->Flags, pkgCache::Flag::Important) == false)
return false;
if (std::find(forceEssential.begin(), forceEssential.end(), Pkg.Name()) != forceEssential.end())
{
......@@ -1018,12 +1020,11 @@ debDebFileParser::debDebFileParser(FileFd *File, std::string const &DebFile)
bool debDebFileParser::UsePackage(pkgCache::PkgIterator &Pkg,
pkgCache::VerIterator &Ver)
{
bool res = debListParser::UsePackage(Pkg, Ver);
// we use the full file path as a provides so that the file is found
// by its name
if(NewProvides(Ver, DebFile, Pkg.Cache()->NativeArch(), Ver.VerStr(), 0) == false)
if (not debListParser::UsePackage(Pkg, Ver))
return false;
return res;
// we use the full file path as a provides so that the file is found by its name
// using the MultiArchImplicit flag for this is a bit of a stretch
return NewProvides(Ver, DebFile, Pkg.Cache()->NativeArch(), Ver.VerStr(), pkgCache::Flag::MultiArchImplicit | pkgCache::Flag::ArchSpecific);
}
debListParser::~debListParser() {}
......@@ -270,7 +270,7 @@ static std::string getDpkgStatusLocation(Configuration const &Cnf) {
Configuration PathCnf;
PathCnf.Set("Dir", Cnf.Find("Dir", "/"));
PathCnf.Set("Dir::State::status", "status");
auto const cnfstatedir = Cnf.Find("Dir::State", STATE_DIR + 1);
auto const cnfstatedir = Cnf.Find("Dir::State", &STATE_DIR[1]);
// if the state dir ends in apt, replace it with dpkg -
// for the default this gives us the same as the fallback below.
// This can't be a ../dpkg as that would play bad with symlinks
......@@ -465,9 +465,14 @@ pid_t debSystem::ExecDpkg(std::vector<std::string> const &sArgs, int * const inp
}
/*}}}*/
bool debSystem::MultiArchSupported() const /*{{{*/
{
return AssertFeature("multi-arch");
}
/*}}}*/
bool debSystem::AssertFeature(std::string const &feature) /*{{{*/
{
std::vector<std::string> Args = GetDpkgBaseCommand();
Args.push_back("--assert-multi-arch");
Args.push_back("--assert-" + feature);
pid_t const dpkgAssertMultiArch = ExecDpkg(Args, nullptr, nullptr, true);
if (dpkgAssertMultiArch > 0)
{
......
......@@ -45,6 +45,7 @@ class debSystem : public pkgSystem
APT_HIDDEN static void DpkgChrootDirectory();
APT_HIDDEN static pid_t ExecDpkg(std::vector<std::string> const &sArgs, int * const inputFd, int * const outputFd, bool const DiscardOutput);
bool MultiArchSupported() const override;
static bool AssertFeature(std::string const &Feature);
std::vector<std::string> ArchitecturesSupported() const override;
bool LockInner(OpProgress *const Progress, int timeoutSec) override;
......
......@@ -1416,6 +1416,15 @@ static bool ItemIsEssential(pkgDPkgPM::Item const &I)
return true;
return (I.Pkg->Flags & pkgCache::Flag::Essential) != 0;
}
static bool ItemIsProtected(pkgDPkgPM::Item const &I)
{
static auto const cachegen = _config->Find("pkgCacheGen::Protected");
if (cachegen == "none" || cachegen == "native")
return true;
if (unlikely(I.Pkg.end()))
return true;
return (I.Pkg->Flags & pkgCache::Flag::Important) != 0;
}
bool pkgDPkgPM::ExpandPendingCalls(std::vector<Item> &List, pkgDepCache &Cache)
{
{
......@@ -1712,6 +1721,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
OpenLog();
bool dpkgMultiArch = _system->MultiArchSupported();
bool dpkgProtectedField = debSystem::AssertFeature("protected-field");
// start pty magic before the loop
StartPtyMagic();
......@@ -1780,6 +1790,10 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
{
ADDARGC("--force-remove-essential");
}
if (dpkgProtectedField && std::any_of(I, J, ItemIsProtected))
{
ADDARGC("--force-remove-protected");
}
ADDARGC("--remove");
break;
......
This diff is collapsed.
......@@ -368,6 +368,7 @@ class APT_PUBLIC pkgDepCache : protected pkgCache::Namespace
inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];};
inline StateCache &operator [](PkgIterator const &I) const {return PkgState[I->ID];};
inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];};
inline unsigned char const &operator [](DepIterator const &I) const {return DepState[I->ID];};
/** \return A function identifying packages in the root set other
* than manually installed packages and essential packages, or \b
......@@ -501,6 +502,8 @@ class APT_PUBLIC pkgDepCache : protected pkgCache::Namespace
pkgDepCache(pkgCache * const Cache,Policy * const Plcy = 0);
virtual ~pkgDepCache();
bool CheckConsistency(char const *const msgtag = "");
protected:
// methods call by IsInstallOk
bool IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg,
......@@ -515,14 +518,10 @@ class APT_PUBLIC pkgDepCache : protected pkgCache::Namespace
private:
void * const d;
APT_HIDDEN bool IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
unsigned long const Depth, bool const FromUser);
APT_HIDDEN bool MarkInstall_StateChange(PkgIterator const &Pkg, bool AutoInst, bool FromUser);
APT_HIDDEN bool MarkInstall_CollectDependencies(pkgCache::VerIterator const &PV, std::vector<pkgCache::DepIterator> &toInstall, std::vector<pkgCache::DepIterator> &toRemove);
APT_HIDDEN bool MarkInstall_RemoveConflictsIfNotUpgradeable(pkgCache::VerIterator const &PV, unsigned long Depth, std::vector<pkgCache::DepIterator> &toRemove, APT::PackageVector &toUpgrade);
APT_HIDDEN bool MarkInstall_UpgradeOrRemoveConflicts(bool const propagateProtected, unsigned long Depth, bool const ForceImportantDeps, APT::PackageVector &toUpgrade);
APT_HIDDEN bool MarkInstall_InstallDependencies(PkgIterator const &Pkg, unsigned long Depth, bool const ForceImportantDeps, std::vector<pkgCache::DepIterator> &toInstall, APT::PackageVector *const toMoveAuto, bool const propagateProtected, bool const FromUser);
APT_HIDDEN bool MarkInstall_DiscardInstall(PkgIterator const &Pkg);
APT_HIDDEN void PerformDependencyPass(OpProgress * const Prog);
};
#endif
......@@ -29,8 +29,10 @@
#include <sys/stat.h>
#include <unistd.h>
#include <algorithm>
#include <array>
#include <limits>
#include <sstream>
#include <string>