+
+ if (checkMultiArch != true || I->CurrentVer == 0)
+ continue;
+
+ VerIterator const V = I.CurrentVer();
+ if (V->MultiArch != Version::All)
+ continue;
+
+ recheck.insert(I.Index());
+ --Done; // no progress if we need to recheck the package
+ }
+
+ if (checkMultiArch == true) {
+ /* FIXME: recheck breaks proper progress reporting as we don't know
+ how many packages we need to recheck. To lower the effect
+ a bit we increase with a kill, but we should do something more clever… */
+ for(std::set<unsigned long>::const_iterator p = recheck.begin();
+ p != recheck.end(); ++p) {
+ if (Prog != 0 && Done%20 == 0)
+ Prog->Progress(Done);
+ PkgIterator P = PkgIterator(*Cache, Cache->PkgP + *p);
+ if (RemovePseudoInstalledPkg(P, recheck) == true) {
+ ++killed;
+ ++Done;
+ }
+ recheck.erase(p);
+ }
+
+ /* Okay, we have killed a great amount of pseudopackages -
+ we have killed so many that we have now arch "all" packages
+ without an installed pseudo package, but we NEED an installed
+ pseudo package, so we will search now for a pseudo package
+ we can install without breaking everything. */
+ for (GrpIterator G = Cache->GrpBegin(); G.end() != true; ++G)
+ {
+ PkgIterator P = G.FindPkg("all");
+ if (P.end() == true)
+ continue;
+ if (P->CurrentVer == 0)
+ continue;
+ bool installed = false;
+ for (P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P))
+ {
+ if (strcmp(P.Arch(), "all") == 0)
+ continue;
+ if (P->CurrentVer == 0)
+ continue;
+ installed = true;
+ break;
+ }
+ if (installed == false)
+ recheck.insert(G.Index());
+ }
+ std::vector<std::string> Archs = APT::Configuration::getArchitectures();
+ bool checkChanged = false;
+ do {
+ for(std::set<unsigned long>::const_iterator g = recheck.begin();
+ g != recheck.end(); ++g) {
+ GrpIterator G = GrpIterator(*Cache, Cache->GrpP + *g);
+ VerIterator allV = G.FindPkg("all").CurrentVer();
+ for (std::vector<std::string>::const_iterator a = Archs.begin();
+ a != Archs.end(); ++a)
+ {
+ PkgIterator P = G.FindPkg(*a);
+ if (P.end() == true) continue;
+ for (VerIterator V = P.VersionList(); V.end() != true; ++V)
+ {
+ if (allV->Hash != V->Hash ||
+ strcmp(allV.VerStr(),V.VerStr()) != 0)
+ continue;
+ unsigned char const CurDepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy);
+ if ((CurDepState & DepInstMin) != DepInstMin)
+ break; // we found the correct version, but it is broken. Better try another arch or later again
+ RemoveSizes(P);
+ RemoveStates(P);
+ P->CurrentVer = V.Index();
+ PkgState[P->ID].InstallVer = V;
+ AddStates(P);
+ Update(P);
+ AddSizes(P);
+ checkChanged = true;
+ break;
+ }
+ }
+ recheck.erase(g);
+ }
+ } while (checkChanged == true && recheck.empty() == false);
+
+ if (_config->FindB("Debug::MultiArchKiller", false) == true)
+ for(std::set<unsigned long>::const_iterator g = recheck.begin();
+ g != recheck.end(); ++g)
+ std::cout << "No pseudo package for »" << GrpIterator(*Cache, Cache->GrpP + *g).Name() << "« installed" << std::endl;