++PackagesTotal;
return true;
});
+ if ((I.Op == Item::Remove || I.Op == Item::Purge) && I.Pkg->CurrentVer != 0)
+ {
+ if (I.Pkg->CurrentState == pkgCache::State::UnPacked ||
+ I.Pkg->CurrentState == pkgCache::State::HalfInstalled)
+ {
+ if (likely(strcmp(PackageOps[name][0].state, "half-configured") == 0))
+ {
+ ++PackageOpsDone[name];
+ --PackagesTotal;
+ }
+ }
+ }
}
/* one extra: We don't want the progress bar to reach 100%, especially not
if we call dpkg --configure --pending and process a bunch of triggers
if (unlikely(Ent->d_type != DT_LNK && Ent->d_type != DT_UNKNOWN))
continue;
#endif
- if (unlikely(unlinkat(dfd, Ent->d_name, 0) != 0))
+ char path[strlen(tmpdir) + 1 + strlen(Ent->d_name) + 1];
+ sprintf(path, "%s/%s", tmpdir, Ent->d_name);
+ if (unlikely(unlink(path) != 0))
break;
}
closedir(D);
if (I.Op == Item::Install && alreadyConfigured.insert(I.Pkg->ID).second == true)
AppendList.emplace_back(Item::Configure, I.Pkg);
for (auto Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg)
- if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && alreadyConfigured.insert(Pkg->ID).second == true)
+ if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
+ Cache[Pkg].Delete() == false && alreadyConfigured.insert(Pkg->ID).second == true)
AppendList.emplace_back(Item::Configure, Pkg);
std::move(AppendList.begin(), AppendList.end(), std::back_inserter(List));
}
continue;
auto const Grp = I->Pkg.Group();
- size_t installedInstances = 0;
+ size_t installedInstances = 0, wannabeInstances = 0;
+ bool multiArchInstances = false;
for (auto Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg))
- if (Pkg->CurrentVer != 0 || Cache[Pkg].Install())
+ {
+ if (Pkg->CurrentVer != 0)
+ {
++installedInstances;
- if (installedInstances == 2)
+ if (Cache[Pkg].Delete() == false)
+ ++wannabeInstances;
+ }
+ else if (PackageOps.find(Pkg.FullName()) != PackageOps.end())
+ ++wannabeInstances;
+ if (multiArchInstances == false)
+ {
+ auto const V = Cache[Pkg].InstVerIter(Cache);
+ if (V.end() == false && (Pkg->CurrentVer == 0 || V != Pkg.CurrentVer()))
+ multiArchInstances = ((V->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same);
+ }
+ }
+ /* theoretically the installed check would be enough as some wannabe will
+ be first and hence be the crossgrade we were looking for, but #844300
+ prevents this so we keep these situations explicit removes.
+ It is also the reason why neither of them can be a M-A:same package */
+ if (installedInstances == 1 && wannabeInstances == 1 && multiArchInstances == false)
{
auto const FirstInstall = std::find_if_not(I, List.end(),
[](Item const &i) { return i.Op == Item::Remove || i.Op == Item::Purge; });