]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/depcache.cc
merged from donkult
[apt.git] / apt-pkg / depcache.cc
index a284a05c7c90fc162caf54737039d39c5693884b..5c011d743e20a3807b4b77af679cb518b824f817 100644 (file)
@@ -127,9 +127,12 @@ bool pkgDepCache::Init(OpProgress *Prog)
    /* Set the current state of everything. In this state all of the
       packages are kept exactly as is. See AllUpgrade */
    int Done = 0;
+   int Update_interval = Head().PackageCount/100;
+   if (Update_interval == 0)
+      Update_interval = 1;
    for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
    {
-      if (Prog != 0)
+      if (Prog != 0 && Done%Update_interval == 0)
         Prog->Progress(Done);
       
       // Find the proper cache slot
@@ -175,6 +178,7 @@ bool pkgDepCache::readStateFile(OpProgress *Prog)                   /*{{{*/
       pkgTagFile tagfile(&state_file);
       pkgTagSection section;
       int amt=0;
+      bool debug_autoremove=_config->FindB("Debug::pkgAutoRemove",false);
       while(tagfile.Step(section)) {
         string pkgname = section.FindS("Package");
         pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname);
@@ -184,7 +188,7 @@ bool pkgDepCache::readStateFile(OpProgress *Prog)                   /*{{{*/
            short reason = section.FindI("Auto-Installed", 0);
            if(reason > 0)
               PkgState[pkg->ID].Flags  |= Flag::Auto;
-           if(_config->FindB("Debug::pkgAutoRemove",false))
+           if(debug_autoremove)
               std::cout << "Auto-Installed : " << pkgname << std::endl;
            amt+=section.size();
            if(Prog != NULL)
@@ -202,7 +206,9 @@ bool pkgDepCache::readStateFile(OpProgress *Prog)                   /*{{{*/
                                                                        /*}}}*/
 bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/
 {
-   if(_config->FindB("Debug::pkgAutoRemove",false))
+   bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
+   
+   if(debug_autoremove)
       std::clog << "pkgDepCache::writeStateFile()" << std::endl;
 
    FileFd StateFile;
@@ -257,14 +263,14 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)    /*{{{*/
    for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); pkg++) {
       if(PkgState[pkg->ID].Flags & Flag::Auto) {
         if (pkgs_seen.find(pkg.Name()) != pkgs_seen.end()) {
-           if(_config->FindB("Debug::pkgAutoRemove",false))
+           if(debug_autoremove)
               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))
+        if(debug_autoremove)
            std::clog << "Writing new AutoInstall: " 
                      << pkg.Name() << std::endl;
         ostr.str(string(""));
@@ -609,9 +615,12 @@ void pkgDepCache::Update(OpProgress *Prog)
    
    // Perform the depends pass
    int Done = 0;
+   int Update_interval = Head().PackageCount;
+   if (Update_interval == 0)
+      Update_interval = 1;
    for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
    {
-      if (Prog != 0 && Done%20 == 0)
+      if (Prog != 0 && Done%Update_interval == 0)
         Prog->Progress(Done);
       for (VerIterator V = I.VersionList(); V.end() != true; V++)
       {
@@ -747,7 +756,7 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
 #endif
 
    if (DebugMarker == true)
-      std::clog << OutputInDepth(Depth) << "MarkKeep " << Pkg << std::endl;
+      std::clog << OutputInDepth(Depth) << "MarkKeep " << Pkg << " FU=" << FromUser << std::endl;
 
    RemoveSizes(Pkg);
    RemoveStates(Pkg);
@@ -769,7 +778,7 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
 // ---------------------------------------------------------------------
 /* */
 void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
-                             unsigned long Depth)
+                             unsigned long Depth, bool FromUser)
 {
    // Simplifies other routines.
    if (Pkg.end() == true)
@@ -791,8 +800,12 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
    if (Pkg->VersionList == 0)
       return;
 
+   // check if we are allowed to install the package
+   if (IsDeleteOk(Pkg,rPurge,Depth,FromUser) == false)
+      return;
+
    if (DebugMarker == true)
-      std::clog << OutputInDepth(Depth) << "MarkDelete " << Pkg << std::endl;
+      std::clog << OutputInDepth(Depth) << "MarkDelete " << Pkg << " FU=" << FromUser << std::endl;
 
    RemoveSizes(Pkg);
    RemoveStates(Pkg);
@@ -808,6 +821,23 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
    AddSizes(Pkg);
 }
                                                                        /*}}}*/
+// DepCache::IsDeleteOk - check if it is ok to remove this package     /*{{{*/
+// ---------------------------------------------------------------------
+/* The default implementation just honors dpkg hold
+   But an application using this library can override this method
+   to control the MarkDelete behaviour */
+bool pkgDepCache::IsDeleteOk(PkgIterator const &Pkg,bool rPurge,
+                             unsigned long Depth, bool FromUser)
+{
+   if (FromUser == false && Pkg->SelectedState == pkgCache::State::Hold)
+   {
+      if (DebugMarker == true)
+        std::clog << OutputInDepth(Depth) << "Hold prevents MarkDelete of " << Pkg << " FU=" << FromUser << std::endl;
+      return false;
+   }
+   return true;
+}
+                                                                       /*}}}*/
 // DepCache::MarkInstall - Put the package in the install state                /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -843,6 +873,11 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
    // We dont even try to install virtual packages..
    if (Pkg->VersionList == 0)
       return;
+
+   // check if we are allowed to install the package
+   if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false)
+      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 */
@@ -871,12 +906,12 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
    AddStates(Pkg);
    Update(Pkg);
    AddSizes(Pkg);
-   
+
    if (AutoInst == false)
       return;
 
    if (DebugMarker == true)
-      std::clog << OutputInDepth(Depth) << "MarkInstall " << Pkg << std::endl;
+      std::clog << OutputInDepth(Depth) << "MarkInstall " << Pkg << " FU=" << FromUser << std::endl;
 
    DepIterator Dep = P.InstVerIter(*this).DependsList();
    for (; Dep.end() != true;)
@@ -1001,8 +1036,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
            }
         }
         
-        if (InstPkg.end() == false &&
-            AutoInstOk(InstPkg, (*this)[InstPkg].CandidateVerIter(*this), Start))
+        if (InstPkg.end() == false)
         {
            if(DebugAutoInstall == true)
               std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.Name()
@@ -1040,30 +1074,30 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
            PkgIterator Pkg = Ver.ParentPkg();
 
            if (Start->Type != Dep::DpkgBreaks)
-           {
-              if(AutoInstOk(Pkg, VerIterator(*this), Start))
-                 MarkDelete(Pkg);
-           }
-           else
-              if (PkgState[Pkg->ID].CandidateVer != *I &&
-                  AutoInstOk(Pkg, VerIterator(*this, PkgState[Pkg->ID].CandidateVer), Start))
-                 MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps);
+              MarkDelete(Pkg,false,Depth + 1, false);
+           else if (PkgState[Pkg->ID].CandidateVer != *I)
+              MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps);
         }
         continue;
       }      
    }
 }
                                                                        /*}}}*/
-// DepCache::AutoInstOk - check if it is to install this package       /*{{{*/
+// DepCache::IsInstallOk - check if it is ok to install this package   /*{{{*/
 // ---------------------------------------------------------------------
 /* The default implementation just honors dpkg hold
-   But an application using this  library can override this method
+   But an application using this library can override this method
    to control the MarkInstall behaviour */
-bool pkgDepCache::AutoInstOk(const PkgIterator &Pkg, 
-                             const VerIterator &v,
-                             const DepIterator &d)
+bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst,
+                             unsigned long Depth, bool FromUser)
 {
-   return (Pkg->SelectedState != pkgCache::State::Hold);
+   if (FromUser == false && Pkg->SelectedState == pkgCache::State::Hold)
+   {
+      if (DebugMarker == true)
+        std::clog << OutputInDepth(Depth) << "Hold prevents MarkInstall of " << Pkg << " FU=" << FromUser << std::endl;
+      return false;
+   }
+   return true;
 }
                                                                        /*}}}*/
 // DepCache::SetReInstall - Set the reinstallation flag                        /*{{{*/
@@ -1301,6 +1335,7 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
 {
    bool follow_recommends;
    bool follow_suggests;
+   bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
 
    // init the states
    for(PkgIterator p = PkgBegin(); !p.end(); ++p)
@@ -1309,8 +1344,7 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
       PkgState[p->ID].Garbage = false;
 
       // debug output
-      if(_config->FindB("Debug::pkgAutoRemove",false) 
-        && PkgState[p->ID].Flags & Flag::Auto)
+      if(debug_autoremove && PkgState[p->ID].Flags & Flag::Auto)
         std::clog << "AutoDep: " << p.Name() << std::endl;
    }
 
@@ -1381,7 +1415,9 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
    if(state.Marked)
       return;
 
-   if(_config->FindB("Debug::pkgAutoRemove",false))
+   bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove", false);
+   
+   if(debug_autoremove)
      {
        std::clog << "Marking: " << pkg.Name();
        if(!ver.end())
@@ -1412,7 +1448,7 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
           {
              if(_system->VS->CheckDep(V.VerStr(), d->CompareOp, d.TargetVer()))
              {
-               if(_config->FindB("Debug::pkgAutoRemove",false))
+               if(debug_autoremove)
                  {
                    std::clog << "Following dep: " << d.ParentPkg().Name()
                              << " " << d.ParentVer().VerStr() << " "
@@ -1436,7 +1472,7 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
              if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp, 
                                       d.TargetVer()))
              {
-               if(_config->FindB("Debug::pkgAutoRemove",false))
+               if(debug_autoremove)
                  {
                    std::clog << "Following dep: " << d.ParentPkg().Name()
                              << " " << d.ParentVer().VerStr() << " "
@@ -1464,9 +1500,11 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
                                                                        /*}}}*/
 bool pkgDepCache::Sweep()                                              /*{{{*/
 {
+   bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
+
    // do the sweep
    for(PkgIterator p=PkgBegin(); !p.end(); ++p)
-  {
+   {
      StateCache &state=PkgState[p->ID];
 
      // skip required packages
@@ -1478,7 +1516,7 @@ bool pkgDepCache::Sweep()                                         /*{{{*/
      if(!state.Marked && (!p.CurrentVer().end() || state.Install()))
      {
        state.Garbage=true;
-       if(_config->FindB("Debug::pkgAutoRemove",false))
+       if(debug_autoremove)
           std::cout << "Garbage: " << p.Name() << std::endl;
      }
   }