]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/depcache.cc
cachefile: Only set members that were initialized successfully
[apt.git] / apt-pkg / depcache.cc
index 7b1448c73e34a2b960a68dfbb933b8ae8381d27d..4940387a6b09b541007c137b501809048d525302 100644 (file)
@@ -13,7 +13,6 @@
 #include <apt-pkg/depcache.h>
 #include <apt-pkg/versionmatch.h>
 #include <apt-pkg/error.h>
-#include <apt-pkg/sptr.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/configuration.h>
@@ -154,7 +153,7 @@ bool pkgDepCache::Init(OpProgress * const Prog)
       State.iFlags = 0;
 
       // Figure out the install version
-      State.CandidateVer = GetCandidateVer(I);
+      State.CandidateVer = LocalPolicy->GetCandidateVer(I);
       State.InstallVer = I.CurrentVer();
       State.Mode = ModeKeep;
 
@@ -836,6 +835,41 @@ bool pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
 
    ActionGroup group(*this);
 
+   if (FromUser == false)
+   {
+      VerIterator const PV = P.InstVerIter(*this);
+      if (PV.end() == false)
+      {
+        // removed metapackages mark their dependencies as manual to prevent in "desktop depends browser, texteditor"
+        // the removal of browser to suggest the removal of desktop and texteditor.
+        // We ignore the auto-bit here as we can't deal with metapackage cascardes otherwise.
+        // We do not check for or-groups here as we don't know which package takes care of
+        // providing the feature the user likes e.g.:  browser1 | browser2 | browser3
+        // Temporary removals are effected by this as well, which is bad, but unlikely in practice
+        bool const PinNeverMarkAutoSection = (PV->Section != 0 && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", PV.Section()));
+        if (PinNeverMarkAutoSection)
+        {
+           for (DepIterator D = PV.DependsList(); D.end() != true; ++D)
+           {
+              if (D.IsMultiArchImplicit() == true || D.IsNegative() == true || IsImportantDep(D) == false)
+                 continue;
+
+              pkgCacheFile CacheFile(this);
+              APT::VersionList verlist = APT::VersionList::FromDependency(CacheFile, D, APT::CacheSetHelper::INSTALLED);
+              for (auto const &V : verlist)
+              {
+                 PkgIterator const DP = V.ParentPkg();
+                 if(DebugAutoInstall == true)
+                    std::clog << OutputInDepth(Depth) << "Setting " << DP.FullName(false) << " NOT as auto-installed (direct "
+                       << D.DepType() << " of " << Pkg.FullName(false) << " which is in APT::Never-MarkAuto-Sections)" << std::endl;
+
+                 MarkAuto(DP, false);
+              }
+           }
+        }
+      }
+   }
+
    if (DebugMarker == true)
       std::clog << OutputInDepth(Depth) << (rPurge ? "MarkPurge " : "MarkDelete ") << Pkg << " FU=" << FromUser << std::endl;
 
@@ -982,6 +1016,8 @@ struct CompareProviders {
         if (instA != instB)
            return instA == false;
       }
+      if ((A->CurrentVer == 0 || B->CurrentVer == 0) && A->CurrentVer != B->CurrentVer)
+        return A->CurrentVer == 0;
       // Prefer packages in the same group as the target; e.g. foo:i386, foo:amd64
       if (A->Group != B->Group)
       {
@@ -1093,7 +1129,28 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
    if (DebugMarker == true)
       std::clog << OutputInDepth(Depth) << "MarkInstall " << Pkg << " FU=" << FromUser << std::endl;
 
-   DepIterator Dep = P.InstVerIter(*this).DependsList();
+   bool MoveAutoBitToDependencies = false;
+   VerIterator const PV = P.InstVerIter(*this);
+   if (unlikely(PV.end() == true))
+      return false;
+   else if (PV->Section != 0 && (P.Flags & Flag::Auto) != Flag::Auto)
+   {
+      VerIterator const CurVer = Pkg.CurrentVer();
+      if (CurVer.end() == false && CurVer->Section != 0 && strcmp(CurVer.Section(), PV.Section()) != 0)
+      {
+        bool const CurVerInMoveSection = ConfigValueInSubTree("APT::Move-Autobit-Sections", CurVer.Section());
+        bool const InstVerInMoveSection = ConfigValueInSubTree("APT::Move-Autobit-Sections", PV.Section());
+        MoveAutoBitToDependencies = (CurVerInMoveSection == false && InstVerInMoveSection == true);
+        if (MoveAutoBitToDependencies == true)
+        {
+           if(DebugAutoInstall == true)
+              std::clog << OutputInDepth(Depth) << "Setting " << Pkg.FullName(false) << " as auto-installed, moving manual to its dependencies" << std::endl;
+           MarkAuto(Pkg, true);
+        }
+      }
+   }
+
+   DepIterator Dep = PV.DependsList();
    for (; Dep.end() != true;)
    {
       // Grok or groups
@@ -1126,7 +1183,7 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 
       /* unsatisfiable dependency: IsInstallOkDependenciesSatisfiableByCandidates
          would have prevented us to get here if not overridden, so just skip
-        over the problem here as the frontend will know what it is doing */
+        over the problem here as the front-end will know what it is doing */
       if (Ors == 1 && (DepState[Start->ID] &DepCVer) != DepCVer && Start.IsNegative() == false)
         continue;
 
@@ -1205,14 +1262,17 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
               verlist.erase(InstVer);
               continue;
            }
+
            // now check if we should consider it a automatic dependency or not
-           if(InstPkg->CurrentVer == 0 && InstVer->Section != 0 && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", InstVer.Section()))
+           if(InstPkg->CurrentVer == 0 && MoveAutoBitToDependencies)
            {
               if(DebugAutoInstall == true)
-                 std::clog << OutputInDepth(Depth) << "Setting NOT as auto-installed (direct "
-                            << Start.DepType() << " of pkg in APT::Never-MarkAuto-Sections)" << std::endl;
+                 std::clog << OutputInDepth(Depth) << "Setting " << InstPkg.FullName(false) << " NOT as auto-installed (direct "
+                    << Start.DepType() << " of " << Pkg.FullName(false) << " which is manual and in APT::Move-Autobit-Sections)" << std::endl;
               MarkAuto(InstPkg, false);
            }
+
+
            break;
         } while(true);
         continue;
@@ -1222,9 +1282,9 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
         Otherwise we remove the offender if needed */
       else if (Start.IsNegative() == true && Start->Type != pkgCache::Dep::Obsoletes)
       {
-        SPtrArray<Version *> List = Start.AllTargets();
+        std::unique_ptr<Version *[]> List(Start.AllTargets());
         pkgCache::PkgIterator TrgPkg = Start.TargetPkg();
-        for (Version **I = List; *I != 0; I++)
+        for (Version **I = List.get(); *I != 0; I++)
         {
            VerIterator Ver(*this,*I);
            PkgIterator Pkg = Ver.ParentPkg();
@@ -1361,7 +1421,12 @@ bool pkgDepCache::IsInstallOkDependenciesSatisfiableByCandidates(PkgIterator con
         // the dependency is critical, but can't be installed, so discard the candidate
         // as the problemresolver will trip over it otherwise trying to install it (#735967)
         if (Pkg->CurrentVer != 0 && (PkgState[Pkg->ID].iFlags & Protected) != Protected)
+         {
            SetCandidateVersion(Pkg.CurrentVer());
+            StateCache &State = PkgState[Pkg->ID];
+            State.Mode = ModeKeep;
+            State.Update(Pkg, *this);
+         }
         return false;
       }
    }
@@ -1409,6 +1474,11 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
    }
 }
                                                                        /*}}}*/
+pkgCache::VerIterator pkgDepCache::GetCandidateVersion(PkgIterator const &Pkg)/*{{{*/
+{
+   return PkgState[Pkg->ID].CandidateVerIter(*this);
+}
+                                                                       /*}}}*/
 // DepCache::SetCandidateVersion - Change the candidate version                /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -1630,11 +1700,7 @@ void pkgDepCache::StateCache::Update(PkgIterator Pkg,pkgCache &Cache)
    CurVersion = "";
    if (Pkg->CurrentVer != 0)
       CurVersion = Pkg.CurrentVer().VerStr();
-   
-   // Strip off the epochs for display
-   CurVersion = StripEpoch(CurVersion);
-   CandVersion = StripEpoch(CandVersion);
-   
+
    // Figure out if its up or down or equal
    Status = Ver.CompareVer(Pkg.CurrentVer());
    if (Pkg->CurrentVer == 0 || Pkg->VersionList == 0 || CandidateVer == 0)
@@ -1721,6 +1787,8 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator const &Dep) const
 // Policy::GetPriority - Get the priority of the package pin           /*{{{*/
 APT_CONST signed short pkgDepCache::Policy::GetPriority(pkgCache::PkgIterator const &/*Pkg*/)
 { return 0; }
+APT_CONST signed short pkgDepCache::Policy::GetPriority(pkgCache::VerIterator const &/*Ver*/, bool /*ConsiderFiles*/)
+{ return 0; }
 APT_CONST signed short pkgDepCache::Policy::GetPriority(pkgCache::PkgFileIterator const &/*File*/)
 { return 0; }
                                                                        /*}}}*/
@@ -1951,7 +2019,7 @@ bool pkgDepCache::MarkAndSweep(InRootSetFunc &rootFunc)
 }
 bool pkgDepCache::MarkAndSweep()
 {
-   std::auto_ptr<InRootSetFunc> f(GetRootSetFunc());
+   std::unique_ptr<InRootSetFunc> f(GetRootSetFunc());
    if(f.get() != NULL)
       return MarkAndSweep(*f.get());
    else