From c919ad6e4d0de48acb60f2a1371ade9bfb0451f8 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 9 Sep 2012 16:03:52 +0200 Subject: handle packages without a mandatory architecture (debian-policy §5.3) by introducing a pseudo-architecture 'none' so that the small group of users with these packages can get right of them without introducing too much hassle for other users (Closes: #686346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apt-pkg/pkgcachegen.cc | 53 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index f70cbd02a..490c2ecbb 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -200,7 +200,19 @@ bool pkgCacheGenerator::MergeList(ListParser &List, } if (Arch.empty() == true) - Arch = _config->Find("APT::Architecture"); + { + // use the pseudo arch 'none' for arch-less packages + Arch = "none"; + /* We might built a SingleArchCache here, which we don't want to blow up + just for these :none packages to a proper MultiArchCache, so just ensure + that we have always a native package structure first for SingleArch */ + pkgCache::PkgIterator NP; + if (NewPackage(NP, PackageName, _config->Find("APT::Architecture")) == false) + // TRANSLATOR: The first placeholder is a package name, + // the other two should be copied verbatim as they include debug info + return _error->Error(_("Error occurred while processing %s (%s%d)"), + PackageName.c_str(), "NewPackage", 0); + } // Get a pointer to the package structure pkgCache::PkgIterator Pkg; @@ -418,6 +430,42 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator return _error->Error(_("Error occurred while processing %s (%s%d)"), Pkg.Name(), "AddImplicitDepends", 1); } + /* :none packages are packages without an architecture. They are forbidden by + debian-policy, so usually they will only be in (old) dpkg status files - + and dpkg will complain about them - and are pretty rare. We therefore do + usually not create conflicts while the parent is created, but only if a :none + package (= the target) appears. This creates incorrect dependencies on :none + for architecture-specific dependencies on the package we copy from, but we + will ignore this bug as architecture-specific dependencies are only allowed + in jessie and until then the :none packages should be extinct (hopefully). + In other words: This should work long enough to allow graceful removal of + these packages, it is not supposed to allow users to keep using them … */ + if (strcmp(Pkg.Arch(), "none") == 0) + { + pkgCache::PkgIterator M = Grp.FindPreferredPkg(); + if (M.end() == false && Pkg != M) + { + pkgCache::DepIterator D = M.RevDependsList(); + Dynamic DynD(D); + for (; D.end() == false; ++D) + { + if ((D->Type != pkgCache::Dep::Conflicts && + D->Type != pkgCache::Dep::DpkgBreaks && + D->Type != pkgCache::Dep::Replaces) || + D.ParentPkg().Group() == Grp) + continue; + + map_ptrloc *OldDepLast = NULL; + pkgCache::VerIterator ConVersion = D.ParentVer(); + // duplicate the Conflicts/Breaks/Replaces for :none arch + if (D->Version == 0) + NewDepends(Pkg, ConVersion, "", 0, D->Type, OldDepLast); + else + NewDepends(Pkg, ConVersion, D.TargetVer(), + D->CompareOp, D->Type, OldDepLast); + } + } + } } if (unlikely(AddImplicitDepends(Grp, Pkg, Ver) == false)) return _error->Error(_("Error occurred while processing %s (%s%d)"), @@ -871,6 +919,9 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator &Ver, // Locate the target package pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch); + // we don't create 'none' packages and their dependencies if we can avoid it … + if (Pkg.end() == true && Arch == "none") + return true; Dynamic DynPkg(Pkg); if (Pkg.end() == true) { if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false)) -- cgit v1.2.3-70-g09d2 From 8ec008808cd6083a633685a732dfe9b8a58a89da Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 9 Sep 2012 21:22:54 +0200 Subject: * apt-pkg/pkgcachegen.cc: - do not create 'native' (or now 'none') package structures as a side effect of description translation parsing as it pollutes the cache --- apt-pkg/pkgcachegen.cc | 2 ++ debian/changelog | 3 +++ 2 files changed, 5 insertions(+) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 490c2ecbb..54b07c465 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -195,8 +195,10 @@ bool pkgCacheGenerator::MergeList(ListParser &List, string const Version = List.Version(); if (Version.empty() == true && Arch.empty() == true) { + // package descriptions if (MergeListGroup(List, PackageName) == false) return false; + continue; } if (Arch.empty() == true) diff --git a/debian/changelog b/debian/changelog index 90f3199b3..936f2557e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -32,6 +32,9 @@ apt (0.9.7.5) UNRELEASED; urgency=low - do not warn about files which have a record in the Release file, but are not present on the CD to mirror the behavior of the other methods and to allow uncompressed indexes to be dropped without scaring users + * apt-pkg/pkgcachegen.cc: + - do not create 'native' (or now 'none') package structures as a side + effect of description translation parsing as it pollutes the cache -- David Kalnischkies Sun, 26 Aug 2012 10:49:17 +0200 -- cgit v1.2.3-70-g09d2