]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/depcache.cc
* support IsAutoInstallOk in the resolver too
[apt.git] / apt-pkg / depcache.cc
index 859e64ea17dd937ac2d1d0af477b64bd6b30f88d..8af6941cfbc5d869b9f758b4170e3287778e4066 100644 (file)
@@ -15,6 +15,7 @@
 #include <apt-pkg/algorithms.h>
 
 #include <apt-pkg/fileutl.h>
+#include <apt-pkg/strutl.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/tagfile.h>
@@ -47,7 +48,6 @@ ConfigValueInSubTree(const char* SubTree, const char *needle)
    return false;
 }
 
-
 pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) :
   cache(cache), released(false)
 {
@@ -83,6 +83,8 @@ pkgDepCache::ActionGroup::~ActionGroup()
 pkgDepCache::pkgDepCache(pkgCache *pCache,Policy *Plcy) :
   group_level(0), Cache(pCache), PkgState(0), DepState(0)
 {
+   DebugMarker = _config->FindB("Debug::pkgDepCache::Marker", false);
+   DebugAutoInstall = _config->FindB("Debug::pkgDepCache::AutoInstall", false);
    delLocalPolicy = 0;
    LocalPolicy = Plcy;
    if (LocalPolicy == 0)
@@ -269,7 +271,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)
         ostr.str(string(""));
         ostr << "Package: " << pkg.Name() 
              << "\nAuto-Installed: 1\n\n";
-        fprintf(OutFile,ostr.str().c_str());
+        fprintf(OutFile,"%s",ostr.str().c_str());
         fprintf(OutFile,"\n");
       }
    }
@@ -705,7 +707,8 @@ void pkgDepCache::Update(PkgIterator const &Pkg)
 // DepCache::MarkKeep - Put the package in the keep state              /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser)
+void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
+                           unsigned long Depth)
 {
    // Simplifies other routines.
    if (Pkg.end() == true)
@@ -746,6 +749,9 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser)
      P.Flags &= ~Flag::Auto;
 #endif
 
+   if (DebugMarker == true)
+      std::clog << OutputInDepth(Depth) << "MarkKeep " << Pkg << std::endl;
+
    RemoveSizes(Pkg);
    RemoveStates(Pkg);
 
@@ -765,7 +771,8 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser)
 // DepCache::MarkDelete - Put the package in the delete state          /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
+void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
+                             unsigned long Depth)
 {
    // Simplifies other routines.
    if (Pkg.end() == true)
@@ -787,6 +794,9 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
    if (Pkg->VersionList == 0)
       return;
 
+   if (DebugMarker == true)
+      std::clog << OutputInDepth(Depth) << "MarkDelete " << Pkg << std::endl;
+
    RemoveSizes(Pkg);
    RemoveStates(Pkg);
    
@@ -826,7 +836,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
        P.CandidateVer == (Version *)Pkg.CurrentVer()))
    {
       if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
-        MarkKeep(Pkg, false, FromUser);
+        MarkKeep(Pkg, false, FromUser, Depth+1);
       return;
    }
 
@@ -836,6 +846,17 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
    // We dont even try to install virtual packages..
    if (Pkg->VersionList == 0)
       return;
+
+   /* if the user doesn't request directly the install we have to check
+      if this install will conflict with any rule a application
+      like apt-get or aptitude might has set (for the user)
+      e.g. forbidden versions, holds or other magic stuff */
+   if(FromUser == false && !IsAutoInstallOk(Pkg, Depth))
+   {
+      MarkKeep(Pkg, false, FromUser, Depth);
+      return;
+   }
+
    /* Target the candidate version and remove the autoflag. We reset the
       autoflag below if this was called recursively. Otherwise the user
       should have the ability to de-auto a package by changing its state */
@@ -868,6 +889,9 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
    if (AutoInst == false)
       return;
 
+   if (DebugMarker == true)
+      std::clog << OutputInDepth(Depth) << "MarkInstall " << Pkg << std::endl;
+
    DepIterator Dep = P.InstVerIter(*this).DependsList();
    for (; Dep.end() != true;)
    {
@@ -937,12 +961,12 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
         }
       }
       if(isNewImportantDep)
-        if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
-           std::clog << "new important dependency: " 
+        if(DebugAutoInstall == true)
+           std::clog << OutputInDepth(Depth) << "new important dependency: "
                      << Start.TargetPkg().Name() << std::endl;
       if(isPreviouslySatisfiedImportantDep)
-       if(_config->FindB("Debug::pkgDepCache::AutoInstall", false) == true)
-         std::clog << "previously satisfied important dependency on "
+       if(DebugAutoInstall == true)
+         std::clog << OutputInDepth(Depth) << "previously satisfied important dependency on "
                    << Start.TargetPkg().Name() << std::endl;
 
       // skip important deps if the package is already installed
@@ -993,15 +1017,16 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
         
         if (InstPkg.end() == false) 
         {
-           if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
-              std::clog << "Installing " << InstPkg.Name() 
-                        << " as dep of " << Pkg.Name() 
+           if(DebugAutoInstall == true)
+              std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.Name()
+                        << " as " << Start.DepType() << " of " << Pkg.Name()
                         << std::endl;
            // now check if we should consider it a automatic dependency or not
            if(Pkg.Section() && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", Pkg.Section()))
            {
-              if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
-                 std::clog << "Setting NOT as auto-installed (direct dep of pkg in APT::Never-MarkAuto-Sections)" << std::endl;
+              if(DebugAutoInstall == true)
+                 std::clog << OutputInDepth(Depth) << "Setting NOT as auto-installed (direct "
+                            << Start.DepType() << " of pkg in APT::Never-MarkAuto-Sections)" << std::endl;
               MarkInstall(InstPkg,true,Depth + 1, true);
            }
            else 
@@ -1028,7 +1053,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
            PkgIterator Pkg = Ver.ParentPkg();
 
            if (Start->Type != Dep::DpkgBreaks)
-              MarkDelete(Pkg);
+              MarkDelete(Pkg,false,Depth + 1);
            else
               if (PkgState[Pkg->ID].CandidateVer != *I)
                  MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps);
@@ -1038,6 +1063,15 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
    }
 }
                                                                        /*}}}*/
+// DepCache::IsAutoInstallOk - check if it is to install this package  /*{{{*/
+// ---------------------------------------------------------------------
+/* The default implementation is useless, but an application using this
+   library can override this method to control the MarkInstall behaviour */
+bool pkgDepCache::IsAutoInstallOk(const PkgIterator &Pkg, unsigned long Depth)
+{
+   return (Pkg->SelectedState != pkgCache::State::Hold);
+}
+                                                                       /*}}}*/
 // DepCache::SetReInstall - Set the reinstallation flag                        /*{{{*/
 // ---------------------------------------------------------------------
 /* */