- VerIterator Ver(Cache,*I);
- PkgIterator BrokenPkg = Ver.ParentPkg();
- VerIterator InstallVer(Cache,Cache[BrokenPkg].InstallVer);
-
- if (Debug && false) {
- if (Ver==0) {
- cout << " Checking if " << Ver << " of " << BrokenPkg.Name() << " satisfies this dependancy" << endl;
- } else {
- cout << " Checking if " << Ver.VerStr() << " of " << BrokenPkg.Name() << " satisfies this dependancy" << endl;
- }
-
- if (BrokenPkg.CurrentVer()==0) {
- cout << " CurrentVer " << BrokenPkg.CurrentVer() << " IsNow " << List->IsNow(BrokenPkg) << " NeedsNothing " << (BrokenPkg.State() == PkgIterator::NeedsNothing) << endl;
- } else {
- cout << " CurrentVer " << BrokenPkg.CurrentVer().VerStr() << " IsNow " << List->IsNow(BrokenPkg) << " NeedsNothing " << (BrokenPkg.State() == PkgIterator::NeedsNothing) << endl;
- }
-
- if (InstallVer==0) {
- cout << " InstallVer " << InstallVer << endl;
- } else {
- cout << " InstallVer " << InstallVer.VerStr() << endl;
- }
-
- cout << " Keep " << Cache[BrokenPkg].Keep() << " Unpacked " << List->IsFlag(BrokenPkg,pkgOrderList::UnPacked) << " Configured " << List->IsFlag(BrokenPkg,pkgOrderList::Configured) << " Removed " << List->IsFlag(BrokenPkg,pkgOrderList::Removed) << " Loop " << List->IsFlag(BrokenPkg,pkgOrderList::Loop) << " InList " << List->IsFlag(BrokenPkg,pkgOrderList::InList) << endl;
- cout << " Delete " << Cache[BrokenPkg].Delete() << endl;
- }
- // Check if it needs to be unpacked
- if (List->IsFlag(BrokenPkg,pkgOrderList::InList) && Cache[BrokenPkg].Delete() == false &&
- !List->IsFlag(BrokenPkg,pkgOrderList::Loop) && List->IsNow(BrokenPkg)) {
- List->Flag(Pkg,pkgOrderList::Loop);
- // Found a break, so unpack the package
- if (Debug)
- cout << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl;
- /* */
- SmartUnPack(BrokenPkg, false);
- }
- // Check if a package needs to be removed
- if (Cache[BrokenPkg].Delete() == true && !List->IsFlag(BrokenPkg,pkgOrderList::Configured)) {
- if (Debug)
- cout << " Removing " << BrokenPkg.Name() << " to avoid break" << endl;
- SmartRemove(BrokenPkg);
+ std::unique_ptr<Version *[]> VList(End.AllTargets());
+ for (Version **I = VList.get(); *I != 0; ++I)
+ {
+ VerIterator Ver(Cache,*I);
+ PkgIterator ConflictPkg = Ver.ParentPkg();
+ if (ConflictPkg.CurrentVer() != Ver)
+ {
+ if (Debug)
+ std::clog << OutputInDepth(Depth) << "Ignore not-installed version " << Ver.VerStr() << " of " << ConflictPkg.FullName() << " for " << End << std::endl;
+ continue;
+ }
+
+ if (List->IsNow(ConflictPkg) == false)
+ {
+ if (Debug)
+ std::clog << OutputInDepth(Depth) << "Ignore already dealt-with version " << Ver.VerStr() << " of " << ConflictPkg.FullName() << " for " << End << std::endl;
+ continue;
+ }
+
+ if (List->IsFlag(ConflictPkg,pkgOrderList::Removed) == true)
+ {
+ if (Debug)
+ clog << OutputInDepth(Depth) << "Ignoring " << End << " as " << ConflictPkg.FullName() << "was temporarily removed" << endl;
+ continue;
+ }
+
+ if (List->IsFlag(ConflictPkg,pkgOrderList::Loop) && PkgLoop)
+ {
+ if (End->Type == pkgCache::Dep::DpkgBreaks && End.IsMultiArchImplicit() == true)
+ {
+ if (Debug)
+ clog << OutputInDepth(Depth) << "Because dependency is MultiArchImplicit we ignored looping on: " << ConflictPkg << endl;
+ continue;
+ }
+ if (Debug)
+ {
+ if (End->Type == pkgCache::Dep::DpkgBreaks)
+ clog << OutputInDepth(Depth) << "Because of breaks knot, deconfigure " << ConflictPkg.FullName() << " temporarily" << endl;
+ else
+ clog << OutputInDepth(Depth) << "Because of conflict knot, removing " << ConflictPkg.FullName() << " temporarily" << endl;
+ }
+ if (EarlyRemove(ConflictPkg, &End) == false)
+ return _error->Error("Internal Error, Could not early remove %s (%d)",ConflictPkg.FullName().c_str(), 3);
+ SomethingBad = true;
+ continue;
+ }
+
+ if (Cache[ConflictPkg].Delete() == false)
+ {
+ if (Debug)
+ {
+ clog << OutputInDepth(Depth) << "Unpacking " << ConflictPkg.FullName() << " to avoid " << End;
+ if (PkgLoop == true)
+ clog << " (Looping)";
+ clog << std::endl;
+ }
+ // we would like to avoid temporary removals and all that at best via a simple unpack
+ _error->PushToStack();
+ if (NonLoopingSmart(UNPACK, Pkg, ConflictPkg, Depth, PkgLoop, NULL, &Changed) == false)
+ {
+ // but if it fails ignore this failure and look for alternative ways of solving
+ if (Debug)
+ {
+ clog << OutputInDepth(Depth) << "Avoidance unpack of " << ConflictPkg.FullName() << " failed for " << End << " ignoring:" << std::endl;
+ _error->DumpErrors(std::clog, GlobalError::DEBUG, false);
+ }
+ _error->RevertToStack();
+ // ignorance can only happen if a) one of the offenders is already gone
+ if (List->IsFlag(ConflictPkg,pkgOrderList::Removed) == true)
+ {
+ if (Debug)
+ clog << OutputInDepth(Depth) << "But " << ConflictPkg.FullName() << " was temporarily removed in the meantime to satisfy " << End << endl;
+ }
+ else if (List->IsFlag(Pkg,pkgOrderList::Removed) == true)
+ {
+ if (Debug)
+ clog << OutputInDepth(Depth) << "But " << Pkg.FullName() << " was temporarily removed in the meantime to satisfy " << End << endl;
+ }
+ // or b) we can make one go (removal or dpkg auto-deconfigure)
+ else
+ {
+ if (Debug)
+ clog << OutputInDepth(Depth) << "So temprorary remove/deconfigure " << ConflictPkg.FullName() << " to satisfy " << End << endl;
+ if (EarlyRemove(ConflictPkg, &End) == false)
+ return _error->Error("Internal Error, Could not early remove %s (%d)",ConflictPkg.FullName().c_str(), 2);
+ }
+ }
+ else
+ _error->MergeWithStack();
+ }
+ else
+ {
+ if (Debug)
+ clog << OutputInDepth(Depth) << "Removing " << ConflictPkg.FullName() << " now to avoid " << End << endl;
+ // no earlyremove() here as user has already agreed to the permanent removal
+ if (SmartRemove(Pkg) == false)
+ return _error->Error("Internal Error, Could not early remove %s (%d)",ConflictPkg.FullName().c_str(), 1);
+ }