From e5a91f7e42a72c97e12e66569f3b8fc777652c26 Mon Sep 17 00:00:00 2001
From: David Kalnischkies <kalnischkies@gmail.com>
Date: Sun, 10 Jun 2012 00:08:28 +0200
Subject: [PATCH] * apt-pkg/deb/deblistparser.cc:   - set
 pkgCacheGen::Essential to "all" again (Closes: #675449) *
 apt-pkg/algorithms.cc:   - force install only for one essential package out
 of a group

---
 apt-pkg/algorithms.cc        | 35 ++++++++++++++++++++++++++++++-----
 apt-pkg/deb/deblistparser.cc | 11 +++++------
 debian/changelog             |  4 ++++
 3 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index 2d710097a..2f5fcc7ab 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -362,11 +362,36 @@ bool pkgDistUpgrade(pkgDepCache &Cache)
       if (I->CurrentVer != 0)
 	 Cache.MarkInstall(I, true, 0, false);
 
-   /* Now, auto upgrade all essential packages - this ensures that
-      the essential packages are present and working */
-   for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
-      if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
-	 Cache.MarkInstall(I, true, 0, false);
+   /* Now, install each essential package which is not installed
+      (and not provided by another package in the same name group) */
+   std::string essential = _config->Find("pkgCacheGen::Essential", "all");
+   if (essential == "all")
+   {
+      for (pkgCache::GrpIterator G = Cache.GrpBegin(); G.end() == false; ++G)
+      {
+	 bool isEssential = false;
+	 bool instEssential = false;
+	 for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P))
+	 {
+	    if ((P->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential)
+	       continue;
+	    isEssential = true;
+	    if (Cache[P].Install() == true)
+	    {
+	       instEssential = true;
+	       break;
+	    }
+	 }
+	 if (isEssential == false || instEssential == true)
+	    continue;
+	 pkgCache::PkgIterator P = G.FindPreferredPkg();
+	 Cache.MarkInstall(P, true, 0, false);
+      }
+   }
+   else if (essential != "none")
+      for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+	 if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+	    Cache.MarkInstall(I, true, 0, false);
    
    /* We do it again over all previously installed packages to force 
       conflict resolution on them all. */
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 7bef6772c..0a7e41538 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -243,13 +243,12 @@ bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg,
    if (Pkg->Section == 0)
       Pkg->Section = UniqFindTagWrite("Section");
 
-   // Packages which are not from the "native" arch doesn't get the essential flag
-   // in the default "native" mode - it is also possible to mark "all" or "none".
-   // The "installed" mode is handled by ParseStatus(), See #544481 and friends.
    string const static myArch = _config->Find("APT::Architecture");
-   string const static essential = _config->Find("pkgCacheGen::Essential", "native");
-   if ((essential == "native" && Pkg->Arch != 0 && myArch == Pkg.Arch()) ||
-       essential == "all")
+   // Possible values are: "all", "native", "installed" and "none"
+   // The "installed" mode is handled by ParseStatus(), See #544481 and friends.
+   string const static essential = _config->Find("pkgCacheGen::Essential", "all");
+   if (essential == "all" ||
+       (essential == "native" && Pkg->Arch != 0 && myArch == Pkg.Arch()))
       if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false)
 	 return false;
    if (Section.FindFlag("Important",Pkg->Flags,pkgCache::Flag::Important) == false)
diff --git a/debian/changelog b/debian/changelog
index 4641da2b3..3a8ae4002 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -26,6 +26,10 @@ apt (0.9.5.2) UNRELEASED; urgency=low
   * ftparchive/apt-ftparchive.cc:
     - default to putting the Contents-* files below $(SECTION) as apt-file
       expects them there - thanks Martin-Éric Racine! (Closes: #675827)
+  * apt-pkg/deb/deblistparser.cc:
+    - set pkgCacheGen::Essential to "all" again (Closes: #675449)
+  * apt-pkg/algorithms.cc:
+    - force install only for one essential package out of a group
 
   [ Justin B Rye ]
   * doc/apt-cdrom.8.xml:
-- 
2.47.2