+ // not changing the mode is obviously also fine as we might want to call
+ // e.g. MarkInstall multiple times with different arguments for the same package
+ if (P.Mode == mode)
+ return true;
+
+ // if previous state was set by user only user can reset it
+ if ((P.iFlags & Protected) == Protected)
+ {
+ if (unlikely(DebugMarker == true))
+ std::clog << OutputInDepth(Depth) << "Ignore Mark" << PrintMode(mode)
+ << " of " << APT::PrettyPkg(this, Pkg) << " as its mode (" << PrintMode(P.Mode)
+ << ") is protected" << std::endl;
+ return false;
+ }
+ // enforce dpkg holds
+ else if (mode != ModeKeep && Pkg->SelectedState == pkgCache::State::Hold &&
+ _config->FindB("APT::Ignore-Hold",false) == false)
+ {
+ if (unlikely(DebugMarker == true))
+ std::clog << OutputInDepth(Depth) << "Hold prevents Mark" << PrintMode(mode)
+ << " of " << APT::PrettyPkg(this, Pkg) << std::endl;
+ return false;
+ }
+
+ return true;
+}
+ /*}}}*/
+// DepCache::MarkInstall - Put the package in the install state /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+struct CompareProviders {
+ pkgCache::PkgIterator const Pkg;
+ explicit CompareProviders(pkgCache::DepIterator const &Dep) : Pkg(Dep.TargetPkg()) {};
+ //bool operator() (APT::VersionList::iterator const &AV, APT::VersionList::iterator const &BV)
+ bool operator() (pkgCache::VerIterator const &AV, pkgCache::VerIterator const &BV)
+ {
+ pkgCache::PkgIterator const A = AV.ParentPkg();
+ pkgCache::PkgIterator const B = BV.ParentPkg();
+ // Prefer MA:same packages if other architectures for it are installed
+ if ((AV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same ||
+ (BV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
+ {
+ bool instA = false;
+ if ((AV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
+ {
+ pkgCache::GrpIterator Grp = A.Group();
+ for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
+ if (P->CurrentVer != 0)
+ {
+ instA = true;
+ break;
+ }
+ }
+ bool instB = false;
+ if ((BV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
+ {
+ pkgCache::GrpIterator Grp = B.Group();
+ for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
+ {
+ if (P->CurrentVer != 0)
+ {
+ instB = true;
+ break;
+ }
+ }
+ }
+ if (instA != instB)
+ return instA == false;
+ }
+ if ((A->CurrentVer == 0 || B->CurrentVer == 0) && A->CurrentVer != B->CurrentVer)
+ return A->CurrentVer == 0;
+ // Prefer packages in the same group as the target; e.g. foo:i386, foo:amd64
+ if (A->Group != B->Group)
+ {
+ if (A->Group == Pkg->Group && B->Group != Pkg->Group)
+ return false;
+ else if (B->Group == Pkg->Group && A->Group != Pkg->Group)
+ return true;
+ }
+ // we like essentials
+ if ((A->Flags & pkgCache::Flag::Essential) != (B->Flags & pkgCache::Flag::Essential))
+ {
+ if ((A->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+ return false;
+ else if ((B->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+ return true;
+ }
+ if ((A->Flags & pkgCache::Flag::Important) != (B->Flags & pkgCache::Flag::Important))
+ {
+ if ((A->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
+ return false;
+ else if ((B->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
+ return true;
+ }
+ // prefer native architecture
+ if (strcmp(A.Arch(), B.Arch()) != 0)
+ {
+ if (strcmp(A.Arch(), A.Cache()->NativeArch()) == 0)
+ return false;
+ else if (strcmp(B.Arch(), B.Cache()->NativeArch()) == 0)
+ return true;
+ std::vector<std::string> archs = APT::Configuration::getArchitectures();
+ for (std::vector<std::string>::const_iterator a = archs.begin(); a != archs.end(); ++a)
+ if (*a == A.Arch())
+ return false;
+ else if (*a == B.Arch())
+ return true;
+ }
+ // higher priority seems like a good idea
+ if (AV->Priority != BV->Priority)
+ return AV->Priority > BV->Priority;
+ // unable to decide…
+ return A->ID < B->ID;
+ }
+};
+bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
+ unsigned long Depth, bool FromUser,
+ bool ForceImportantDeps)
+{
+ if (IsModeChangeOk(ModeInstall, Pkg, Depth, FromUser) == false)
+ return false;
+
+ StateCache &P = PkgState[Pkg->ID];
+
+ // See if there is even any possible instalation candidate
+ if (P.CandidateVer == 0)
+ return false;
+
+ /* Check that it is not already marked for install and that it can be
+ installed */