]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/depcache.cc
Sync with Michael
[apt.git] / apt-pkg / depcache.cc
index 4d193dc2e81fd0fc19e567cd15f46d10278ba145..fe981ea763a339a35e44e5f7c4df2cb3cebb8551 100644 (file)
@@ -8,9 +8,6 @@
    ##################################################################### */
                                                                        /*}}}*/
 // Include Files                                                       /*{{{*/
-#ifdef __GNUG__
-#pragma implementation "apt-pkg/depcache.h"
-#endif
 #include <apt-pkg/depcache.h>
 #include <apt-pkg/version.h>
 #include <apt-pkg/error.h>
@@ -26,6 +23,8 @@
 #include <sstream>    
 #include <set>
 
+#include <sys/stat.h>
+
 #include <apti18n.h>    
 
 pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) :
@@ -179,7 +178,7 @@ bool pkgDepCache::readStateFile(OpProgress *Prog)
    return true;
 }
 
-bool pkgDepCache::writeStateFile(OpProgress *prog)
+bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)
 {
    if(_config->FindB("Debug::pkgAutoRemove",false))
       std::clog << "pkgDepCache::writeStateFile()" << std::endl;
@@ -241,6 +240,9 @@ bool pkgDepCache::writeStateFile(OpProgress *prog)
               std::clog << "Skipping already written " << pkg.Name() << std::endl;
            continue;
         }
+         // skip not installed ones if requested
+         if(InstalledOnly && pkg->CurrentVer == 0)
+            continue;
         if(_config->FindB("Debug::pkgAutoRemove",false))
            std::clog << "Writing new AutoInstall: " 
                      << pkg.Name() << std::endl;
@@ -253,8 +255,9 @@ bool pkgDepCache::writeStateFile(OpProgress *prog)
    }
    fclose(OutFile);
 
-   // move the outfile over the real file
+   // move the outfile over the real file and set permissions
    rename(outfile.c_str(), state.c_str());
+   chmod(state.c_str(), 0644);
 
    return true;
 }
@@ -712,9 +715,17 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser)
    // We dont even try to keep virtual packages..
    if (Pkg->VersionList == 0)
       return;
-   
+#if 0 // reseting the autoflag here means we lose the 
+      // auto-mark information if a user selects a package for removal
+      // but changes  his mind then and sets it for keep again
+      // - this makes sense as default when all Garbage dependencies
+      //   are automatically marked for removal (as aptitude does).
+      //   setting a package for keep then makes it no longer autoinstalled
+      //   for all other use-case this action is rather suprising
    if(FromUser && !P.Marked)
      P.Flags &= ~Flag::Auto;
+#endif
+
    RemoveSizes(Pkg);
    RemoveStates(Pkg);
 
@@ -873,6 +884,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
         bool found=false;
         VerIterator instVer = Pkg.CurrentVer();
         if(!instVer.end())
+        {
            for (DepIterator D = instVer.DependsList(); D.end() != true; D++)
            {
               //FIXME: deal better with or-groups(?)
@@ -881,9 +893,10 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
               if(IsImportantDep(D) && Start.TargetPkg() == D.TargetPkg())
                  found=true;
            }
-        // this is a new dep if it was not found to be already
-        // a important dep of the installed pacakge
-        isNewImportantDep = !found;
+           // this is a new dep if it was not found to be already
+           // a important dep of the installed pacakge
+           isNewImportantDep = !found;
+        }
       }
       if(isNewImportantDep)
         if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
@@ -941,11 +954,22 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
               std::clog << "Installing " << InstPkg.Name() 
                         << " as dep of " << Pkg.Name() 
                         << std::endl;
-           MarkInstall(InstPkg,true,Depth + 1, false, ForceImportantDeps);
-
-           // Set the autoflag, after MarkInstall because MarkInstall unsets it
-           if (P->CurrentVer == 0)
-              PkgState[InstPkg->ID].Flags |= Flag::Auto;
+           // now check if we should consider it a automatic dependency or not
+           string sec = _config->Find("APT::Never-MarkAuto-Section","");
+           if(Pkg.Section() && (string(Pkg.Section()) ==  sec))
+           {
+              if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
+                 std::clog << "Setting NOT as auto-installed because its a direct dep of a package in section " << sec << std::endl;
+              MarkInstall(InstPkg,true,Depth + 1, true);
+           }
+           else 
+           {
+              // mark automatic dependency
+              MarkInstall(InstPkg,true,Depth + 1, false, ForceImportantDeps);
+              // Set the autoflag, after MarkInstall because MarkInstall unsets it
+              if (P->CurrentVer == 0)
+                 PkgState[InstPkg->ID].Flags |= Flag::Auto;
+           }
         }
         continue;
       }
@@ -1108,6 +1132,34 @@ pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg)
    return Last;
 }
                                                                        /*}}}*/
+// Policy::IsImportantDep - True if the dependency is important                /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep)
+{
+   if(Dep.IsCritical())
+      return true;
+   else if(Dep->Type == pkgCache::Dep::Recommends) 
+   {
+      if ( _config->FindB("APT::Install-Recommends", false))
+        return true;
+      // we suport a special mode to only install-recommends for certain
+      // sections
+      // FIXME: this is a meant as a temporarly solution until the 
+      //        recommends are cleaned up
+      string s = _config->Find("APT::Install-Recommends-Section","");
+      if(s.size() > 0) 
+      {
+        const char *sec = Dep.TargetPkg().Section();
+        if (sec && strcmp(sec, s.c_str()) == 0)
+           return true;
+      }
+   }
+   else if(Dep->Type == pkgCache::Dep::Suggests)
+     return _config->FindB("APT::Install-Suggests", false);
+
+   return false;
+}
                                                                        /*}}}*/
 
 pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()
@@ -1310,9 +1362,13 @@ bool pkgDepCache::Sweep()
   {
      StateCache &state=PkgState[p->ID];
 
+     // skip required packages
+     if (!p.CurrentVer().end() && 
+        (p.CurrentVer()->Priority == pkgCache::State::Required))
+       continue;
+
      // if it is not marked and it is installed, it's garbage 
-     if(!state.Marked && (!p.CurrentVer().end() || state.Install()) &&
-       !state.Delete())
+     if(!state.Marked && (!p.CurrentVer().end() || state.Install()))
      {
        state.Garbage=true;
        if(_config->FindB("Debug::pkgAutoRemove",false))
@@ -1322,19 +1378,3 @@ bool pkgDepCache::Sweep()
 
    return true;
 }
-
-// Policy::IsImportantDep - True if the dependency is important                /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep)
-{
-   if(Dep.IsCritical())
-      return true;
-   else if(Dep->Type == pkgCache::Dep::Recommends)
-      return  _config->FindB("APT::Install-Recommends", false);
-   else if(Dep->Type == pkgCache::Dep::Suggests)
-     return _config->FindB("APT::Install-Suggests", false);
-
-   return false;
-}
-                                                                       /*}}}*/