summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/algorithms.cc25
-rw-r--r--apt-pkg/depcache.cc67
-rw-r--r--apt-pkg/depcache.h40
3 files changed, 78 insertions, 54 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index 68a4af8ed..a30a02edb 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -984,26 +984,11 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
// Consider other options
if (InOr == false)
{
- if (Cache.AutoInstOk(I, Cache[I].CandidateVerIter(Cache),Start) == true)
- {
- if (Debug == true)
- clog << " Removing " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl;
- Cache.MarkDelete(I);
- if (Counter > 1)
- {
- if (Scores[Pkg->ID] > Scores[I->ID])
- Scores[I->ID] = Scores[Pkg->ID];
- }
- } else {
- /* The dependency of the TargetPkg would be satisfiable with I but it is
- forbidden to install I automatical, so anything we can do is hold
- back the TargetPkg.
- */
- if (Debug == true)
- clog << " Hold back " << Start.TargetPkg().Name() <<
- " rather than change denied AutoInstall " << I.Name() << endl;
- Cache.MarkKeep(Start.TargetPkg());
- }
+ if (Debug == true)
+ clog << " Removing " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl;
+ Cache.MarkDelete(I);
+ if (Counter > 1 && Scores[Pkg->ID] > Scores[I->ID])
+ Scores[I->ID] = Scores[Pkg->ID];
}
}
}
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index a284a05c7..7c86204f5 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -769,7 +769,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,6 +791,13 @@ 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)
+ {
+ MarkKeep(Pkg,false,FromUser,Depth+1);
+ return;
+ }
+
if (DebugMarker == true)
std::clog << OutputInDepth(Depth) << "MarkDelete " << Pkg << std::endl;
@@ -808,6 +815,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 << std::endl;
+ return false;
+ }
+ return true;
+}
+ /*}}}*/
// DepCache::MarkInstall - Put the package in the install state /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -843,6 +867,14 @@ 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)
+ {
+ MarkKeep(Pkg,false,FromUser,Depth+1);
+ 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,7 +903,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
AddStates(Pkg);
Update(Pkg);
AddSizes(Pkg);
-
+
if (AutoInst == false)
return;
@@ -1001,8 +1033,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 +1071,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 << std::endl;
+ return false;
+ }
+ return true;
}
/*}}}*/
// DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h
index 10f9c1091..44a7f8c02 100644
--- a/apt-pkg/depcache.h
+++ b/apt-pkg/depcache.h
@@ -363,20 +363,6 @@ class pkgDepCache : protected pkgCache::Namespace
*/
virtual bool MarkFollowsSuggests();
- /** \return \b true if it's OK for MarkInstall to recursively
- * install the given version of the given package.
- *
- * \param p the package that MarkInstall wants to install.
- * \param v the version being installed, or an end iterator
- * if p is being removed.
- * \param d the dependency being fixed.
- *
- * The default implementation unconditionally returns \b true.
- */
- virtual bool AutoInstOk(const PkgIterator &p,
- const VerIterator &v,
- const DepIterator &d);
-
/** \brief Update the Marked and Garbage fields of all packages.
*
* This routine is implicitly invoked after all state manipulators
@@ -406,7 +392,7 @@ class pkgDepCache : protected pkgCache::Namespace
void MarkKeep(PkgIterator const &Pkg, bool Soft = false,
bool FromUser = true, unsigned long Depth = 0);
void MarkDelete(PkgIterator const &Pkg, bool Purge = false,
- unsigned long Depth = 0);
+ unsigned long Depth = 0, bool FromUser = true);
void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
unsigned long Depth = 0, bool FromUser = true,
bool ForceImportantDeps = false);
@@ -417,7 +403,29 @@ class pkgDepCache : protected pkgCache::Namespace
/** Set the "is automatically installed" flag of Pkg. */
void MarkAuto(const PkgIterator &Pkg, bool Auto);
// @}
-
+
+ /** \return \b true if it's OK for MarkInstall to install
+ * the given package.
+ *
+ * \param Pkg the package that MarkInstall wants to install.
+ * \param AutoInst needs a previous MarkInstall this package?
+ * \param Depth recursive deep of this Marker call
+ * \param FromUser was the install requested by the user?
+ */
+ virtual bool IsInstallOk(const PkgIterator &Pkg,bool AutoInst = true,
+ unsigned long Depth = 0, bool FromUser = true);
+
+ /** \return \b true if it's OK for MarkDelete to remove
+ * the given package.
+ *
+ * \param Pkg the package that MarkDelete wants to remove.
+ * \param Purge should we purge instead of "only" remove?
+ * \param Depth recursive deep of this Marker call
+ * \param FromUser was the remove requested by the user?
+ */
+ virtual bool IsDeleteOk(const PkgIterator &Pkg,bool Purge = false,
+ unsigned long Depth = 0, bool FromUser = true);
+
// This is for debuging
void Update(OpProgress *Prog = 0);