X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/23c5897cbdb5a957788201a5178e963586dcdbc9..a6c8798a6390b5c3a0775f8914e1cff2795e4cc1:/apt-pkg/orderlist.cc

diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc
index 7c950292a..a17a70112 100644
--- a/apt-pkg/orderlist.cc
+++ b/apt-pkg/orderlist.cc
@@ -117,7 +117,8 @@ bool pkgOrderList::IsMissing(PkgIterator Pkg)
       return false;
 
    // Skip Packages that need configure only.
-   if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && 
+   if ((Pkg.State() == pkgCache::PkgIterator::NeedsConfigure ||
+        Pkg.State() == pkgCache::PkgIterator::NeedsNothing) &&
        Cache[Pkg].Keep() == true)
       return false;
 
@@ -127,10 +128,6 @@ bool pkgOrderList::IsMissing(PkgIterator Pkg)
    if (FileList[Pkg->ID].empty() == false)
       return false;
 
-   // Missing Pseudo packages are missing if the real package is missing
-   if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == true)
-      return IsMissing(Pkg.Group().FindPkg("all"));
-
    return true;
 }
 									/*}}}*/
@@ -493,7 +490,7 @@ bool pkgOrderList::VisitRProvides(DepFunc F,VerIterator Ver)
    bool Res = true;
    for (PrvIterator P = Ver.ProvidesList(); P.end() == false; P++)
       Res &= (this->*F)(P.ParentPkg().RevDependsList());
-   return true;
+   return Res;
 }
 									/*}}}*/
 // OrderList::VisitProvides - Visit all of the providing packages	/*{{{*/
@@ -510,15 +507,11 @@ bool pkgOrderList::VisitProvides(DepIterator D,bool Critical)
       if (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing)
 	 continue;
       
-      if (D->Type != pkgCache::Dep::Conflicts &&
-	  D->Type != pkgCache::Dep::DpkgBreaks &&
-	  D->Type != pkgCache::Dep::Obsoletes &&
+      if (D.IsNegative() == false &&
 	  Cache[Pkg].InstallVer != *I)
 	 continue;
       
-      if ((D->Type == pkgCache::Dep::Conflicts ||
-	   D->Type == pkgCache::Dep::DpkgBreaks ||
-	   D->Type == pkgCache::Dep::Obsoletes) &&
+      if (D.IsNegative() == true &&
 	  (Version *)Pkg.CurrentVer() != *I)
 	 continue;
       
@@ -650,9 +643,7 @@ bool pkgOrderList::DepUnPackCrit(DepIterator D)
       {
 	 /* Forward critical dependencies MUST be correct before the 
 	    package can be unpacked. */
-	 if (D->Type != pkgCache::Dep::Conflicts &&
-	     D->Type != pkgCache::Dep::DpkgBreaks &&
-	     D->Type != pkgCache::Dep::Obsoletes &&
+	 if (D.IsNegative() == false &&
 	     D->Type != pkgCache::Dep::PreDepends)
 	    continue;
 	 	 	 	 
@@ -885,13 +876,16 @@ bool pkgOrderList::DepRemove(DepIterator D)
 	    continue;
 
 	 /* We wish to see if the dep on the parent package is okay
-	    in the removed (install) state of the target pkg. */	 
+	    in the removed (install) state of the target pkg. */
+	 bool tryFixDeps = false;
 	 if (CheckDep(D) == true)
 	 {
 	    // We want to catch loops with the code below.
 	    if (IsFlag(D.ParentPkg(),AddPending) == false)
 	       continue;
 	 }
+	 else
+	    tryFixDeps = true;
 
 	 // This is the loop detection
 	 if (IsFlag(D.ParentPkg(),Added) == true || 
@@ -902,6 +896,100 @@ bool pkgOrderList::DepRemove(DepIterator D)
 	    continue;
 	 }
 
+	 if (tryFixDeps == true)
+	 {
+	    for (pkgCache::DepIterator F = D.ParentPkg().CurrentVer().DependsList();
+		 F.end() == false; ++F)
+	    {
+	       if (F->Type != pkgCache::Dep::Depends && F->Type != pkgCache::Dep::PreDepends)
+		  continue;
+	       // Check the Providers
+	       if (F.TargetPkg()->ProvidesList != 0)
+	       {
+		  pkgCache::PrvIterator Prov = F.TargetPkg().ProvidesList();
+		  for (; Prov.end() == false; ++Prov)
+		  {
+		     pkgCache::PkgIterator const P = Prov.OwnerPkg();
+		     if (IsFlag(P, InList) == true &&
+			 IsFlag(P, AddPending) == true &&
+			 IsFlag(P, Added) == false &&
+			 Cache[P].InstallVer == 0)
+			break;
+		  }
+		  if (Prov.end() == false)
+		     for (pkgCache::PrvIterator Prv = F.TargetPkg().ProvidesList();
+			  Prv.end() == false; ++Prv)
+		     {
+			pkgCache::PkgIterator const P = Prv.OwnerPkg();
+			if (IsFlag(P, InList) == true &&
+			    IsFlag(P, AddPending) == false &&
+			    Cache[P].InstallVer != 0 &&
+			    VisitNode(P) == true)
+			{
+			   Flag(P, Immediate);
+			   tryFixDeps = false;
+			   break;
+			}
+		     }
+		  if (tryFixDeps == false)
+		     break;
+	       }
+
+	       // Check for Or groups
+	       if ((F->CompareOp & pkgCache::Dep::Or) != pkgCache::Dep::Or)
+		  continue;
+	       // Lets see if the package is part of the Or group
+	       pkgCache::DepIterator S = F;
+	       for (; S.end() == false; ++S)
+	       {
+		  if (S.TargetPkg() == D.TargetPkg())
+		     break;
+		  if ((S->CompareOp & pkgCache::Dep::Or) != pkgCache::Dep::Or ||
+		      CheckDep(S)) // Or group is satisfied by another package
+		     for (;S.end() == false; ++S);
+	       }
+	       if (S.end() == true)
+		  continue;
+	       // skip to the end of the or group
+	       for (;S.end() == false && (S->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; ++S);
+	       ++S;
+	       // The soon to be removed is part of the Or group
+	       // start again in the or group and find something which will serve as replacement
+	       for (; F.end() == false && F != S; ++F)
+	       {
+		  if (IsFlag(F.TargetPkg(), InList) == true &&
+		      IsFlag(F.TargetPkg(), AddPending) == false &&
+		      Cache[F.TargetPkg()].InstallVer != 0 &&
+		      VisitNode(F.TargetPkg()) == true)
+		  {
+		     Flag(F.TargetPkg(), Immediate);
+		     tryFixDeps = false;
+		     break;
+		  }
+		  else if (F.TargetPkg()->ProvidesList != 0)
+		  {
+		     pkgCache::PrvIterator Prv = F.TargetPkg().ProvidesList();
+		     for (; Prv.end() == false; ++Prv)
+		     {
+			if (IsFlag(Prv.OwnerPkg(), InList) == true &&
+			    IsFlag(Prv.OwnerPkg(), AddPending) == false &&
+			    Cache[Prv.OwnerPkg()].InstallVer != 0 &&
+			    VisitNode(Prv.OwnerPkg()) == true)
+			{
+			   Flag(Prv.OwnerPkg(), Immediate);
+			   tryFixDeps = false;
+			   break;
+			}
+		     }
+		     if (Prv.end() == false)
+			break;
+		  }
+	       }
+	       if (tryFixDeps == false)
+		  break;
+	    }
+	 }
+
 	 // Skip over missing files
 	 if (IsMissing(D.ParentPkg()) == true)
 	    continue;
@@ -983,10 +1071,14 @@ bool pkgOrderList::CheckDep(DepIterator D)
       
       /* Conflicts requires that all versions are not present, depends
          just needs one */
-      if (D->Type != pkgCache::Dep::Conflicts && 
-	  D->Type != pkgCache::Dep::DpkgBreaks && 
-	  D->Type != pkgCache::Dep::Obsoletes)
+      if (D.IsNegative() == false)
       {
+      	 // ignore provides by older versions of this package
+	 if (((D.Reverse() == false && Pkg == D.ParentPkg()) ||
+	      (D.Reverse() == true && Pkg == D.TargetPkg())) &&
+	     Cache[Pkg].InstallVer != *I)
+	    continue;
+
 	 /* Try to find something that does not have the after flag set
 	    if at all possible */
 	 if (IsFlag(Pkg,After) == true)