// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: packagemanager.cc,v 1.19 1999/08/03 05:19:41 jgg Exp $
+// $Id: packagemanager.cc,v 1.24 1999/12/24 21:10:56 jgg Exp $
/* ######################################################################
Package Manager - Abstacts the package manager
if ((Cache[I].Keep() == true ||
Cache[I].InstVerIter(Cache) == I.CurrentVer()) &&
I.State() == pkgCache::PkgIterator::NeedsNothing &&
+ (Cache[I].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall &&
(I.Purge() != false || Cache[I].Mode != pkgDepCache::ModeDelete ||
(Cache[I].iFlags & pkgDepCache::Purge) != pkgDepCache::Purge))
continue;
{
if (D->Type != pkgCache::Dep::Conflicts)
continue;
+
+ // The package hasnt been changed
+ if (List->IsNow(Pkg) == false)
+ continue;
- if (D.ParentPkg() == Pkg)
+ // Ignore self conflicts, ignore conflicts from irrelevent versions
+ if (D.ParentPkg() == Pkg || D.ParentVer() != D.ParentPkg().CurrentVer())
continue;
if (pkgCheckDep(D.TargetVer(),Ver,D->CompareOp) == false)
continue;
-
- if (List->IsNow(Pkg) == false)
- continue;
if (EarlyRemove(D.ParentPkg()) == false)
- return false;
- }
+ return _error->Error("Reverse conflicts early remove for package '%s' failed",
+ Pkg.Name());
+ }
return true;
}
/*}}}*/
// Woops, it will not be re-installed!
if (List->IsFlag(Pkg,pkgOrderList::InList) == false)
return false;
+
+ // Essential packages get special treatment
+ bool IsEssential = false;
+ if ((Pkg->Flags & pkgCache::Flag::Essential) != 0)
+ IsEssential = true;
+
+ /* Check for packages that are the dependents of essential packages and
+ promote them too */
+ if (Pkg->CurrentVer != 0)
+ {
+ for (DepIterator D = Pkg.RevDependsList(); D.end() == false &&
+ IsEssential == false; D++)
+ if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
+ if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0)
+ IsEssential = true;
+ }
+
+ if (IsEssential == true)
+ {
+ if (_config->FindB("APT::Force-LoopBreak",false) == false)
+ return _error->Error("This installation run will require temporarily "
+ "removing the essential package %s due to a "
+ "Conflicts/Pre-Depends loop. This is often bad, "
+ "but if you really want to do it, activate the "
+ "APT::Force-LoopBreak option.",Pkg.Name());
+ }
bool Res = SmartRemove(Pkg);
if (Cache[Pkg].Delete() == false)
/* See if this packages install version has any predependencies
that are not met by 'now' packages. */
for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList();
- D.end() == false; D++)
+ D.end() == false; )
{
- if (D->Type == pkgCache::Dep::PreDepends)
+ // Compute a single dependency element (glob or)
+ pkgCache::DepIterator Start;
+ pkgCache::DepIterator End;
+ D.GlobOr(Start,End);
+
+ while (End->Type == pkgCache::Dep::PreDepends)
{
// Look for possible ok targets.
- Version **VList = D.AllTargets();
+ Version **VList = Start.AllTargets();
bool Bad = true;
for (Version **I = VList; *I != 0 && Bad == true; I++)
{
}
delete [] VList;
-
- if (Bad == true)
- return _error->Error("Internal Error, Couldn't configure a pre-depend");
- continue;
+ /* If this or element did not match then continue on to the
+ next or element until a matching element is found*/
+ if (Bad == true)
+ {
+ if (Start == End)
+ return _error->Error("Internal Error, Couldn't configure a pre-depend");
+ Start++;
+ }
+ else
+ break;
}
- if (D->Type == pkgCache::Dep::Conflicts)
+ if (End->Type == pkgCache::Dep::Conflicts)
{
/* Look for conflicts. Two packages that are both in the install
state cannot conflict so we don't check.. */
- Version **VList = D.AllTargets();
+ Version **VList = End.AllTargets();
for (Version **I = VList; *I != 0; I++)
{
VerIterator Ver(Cache,*I);
}
// Check for reverse conflicts.
- CheckRConflicts(Pkg,Pkg.RevDependsList(),
- Cache[Pkg].InstVerIter(Cache).VerStr());
+ if (CheckRConflicts(Pkg,Pkg.RevDependsList(),
+ Cache[Pkg].InstVerIter(Cache).VerStr()) == false)
+ return false;
+
for (PrvIterator P = Cache[Pkg].InstVerIter(Cache).ProvidesList();
P.end() == false; P++)
CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion());
if (List->IsMissing(Pkg) == true)
{
if (Debug == true)
- clog << "Sequence completed at" << Pkg.Name() << endl;
+ clog << "Sequence completed at " << Pkg.Name() << endl;
if (DoneSomething == false)
{
_error->Error("Internal Error, ordering was unable to handle the media swap");
}
// Sanity check
- if (Cache[Pkg].Keep() == true && Pkg.State() == pkgCache::PkgIterator::NeedsNothing)
+ if (Cache[Pkg].Keep() == true &&
+ Pkg.State() == pkgCache::PkgIterator::NeedsNothing &&
+ (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
{
_error->Error("Internal Error, trying to manipulate a kept package");
return Failed;