From 5bf15716398fdb767ca6249a0155219b88d7ae60 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 19 Dec 2009 16:25:56 +0100 Subject: Implement the first step toward Multi-Arch by setting up a Group infrastructor for packages. APT is now aware of the fact that a package A in architecture X can't satisfy a dependency on package A in architecture Y - to handle these packages are now identified by name and architecture, so different architectures of the same package are handled internally as completly different packages. This is great for pinning, dependency checking and in many other situations, but sometimes we need to know which archs are available for a given package: Here Groups come to our rescue! --- apt-pkg/deb/deblistparser.cc | 40 +++++++++++++++++++++++++++++----------- apt-pkg/deb/deblistparser.h | 1 + 2 files changed, 30 insertions(+), 11 deletions(-) (limited to 'apt-pkg/deb') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 25a1df3f9..fe68aec0b 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -53,12 +53,25 @@ unsigned long debListParser::UniqFindTagWrite(const char *Tag) // ListParser::Package - Return the package name /*{{{*/ // --------------------------------------------------------------------- /* This is to return the name of the package this section describes */ -string debListParser::Package() -{ - string Result = Section.FindS("Package"); - if (Result.empty() == true) - _error->Error("Encountered a section with no Package: header"); - return Result; +string debListParser::Package() { + string const Result = Section.FindS("Package"); + if(unlikely(Result.empty() == true)) + _error->Error("Encountered a section with no Package: header"); + return Result; +} + /*}}}*/ +// ListParser::Architecture - Return the package arch /*{{{*/ +// --------------------------------------------------------------------- +/* This will return the Architecture of the package this section describes + Note that architecture "all" packages will get the architecture of the + Packages file parsed here */ +string debListParser::Architecture() { + string const Result = Section.FindS("Architecture"); + if (Result.empty() == true) + return Arch; + if (Result == "all") + return Arch; + return Result; } /*}}}*/ // ListParser::Version - Return the version string /*{{{*/ @@ -78,8 +91,10 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) { // Parse the section Ver->Section = UniqFindTagWrite("Section"); - Ver->Arch = UniqFindTagWrite("Architecture"); - + + // Parse the architecture + Ver->Arch = WriteUniqString(Architecture()); + // Archive Size Ver->Size = (unsigned)Section.FindI("Size"); @@ -537,6 +552,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver, return true; string Package; + string const pkgArch = Ver.Arch(); string Version; unsigned int Op; @@ -546,7 +562,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver, if (Start == 0) return _error->Error("Problem parsing dependency %s",Tag); - if (NewDepends(Ver,Package,Version,Op,Type) == false) + if (NewDepends(Ver,Package,pkgArch,Version,Op,Type) == false) return false; if (Start == Stop) break; @@ -619,6 +635,7 @@ bool debListParser::Step() if (Section.Find("Architecture",Start,Stop) == false) return true; + //FIXME: Accept different Architectures here if (stringcmp(Arch,Start,Stop) == 0) return true; @@ -641,8 +658,9 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI, if (Tags.Step(Section) == false) return false; - //mvo: I don't think we need to fill that in (it's unused since apt-0.6) - //FileI->Architecture = WriteUniqString(Arch); + // FIXME: Do we need it now for multi-arch? + // mvo: I don't think we need to fill that in (it's unused since apt-0.6) +// FileI->Architecture = WriteUniqString(Arch); // apt-secure does no longer download individual (per-section) Release // file. to provide Component pinning we use the section name now diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 1c709229f..5f91e073e 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -46,6 +46,7 @@ class debListParser : public pkgCacheGenerator::ListParser // These all operate against the current section virtual string Package(); + virtual string Architecture(); virtual string Version(); virtual bool NewVersion(pkgCache::VerIterator Ver); virtual string Description(); -- cgit v1.2.3 From 5dd4c8b811d9c7bc33e50254811f5bc0fc37f872 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 23 Dec 2009 12:38:19 +0100 Subject: merge Goswin Brederlow "support download of index files for different archs" patch which includes the following big changes: - Declare the unused [vendor] field in sources.list as option field, e.g. deb [arch=amd64,i386 lang=en_GB have=fun] http://example.org - When fetching index files download them for all APT::Architectures (overrideable with the options field above) - Allow all architectures of APT::Architectures to be in the Cache - Add the architecture to status and progress informations - Add b= (Binary architecture) to policy This commit doesn't incude the "pin-hack" as the Group structure will take care of this (and does it already to some extend). --- apt-pkg/deb/debindexfile.cc | 15 ++- apt-pkg/deb/debindexfile.h | 4 +- apt-pkg/deb/deblistparser.cc | 57 ++++++--- apt-pkg/deb/deblistparser.h | 2 +- apt-pkg/deb/debmetaindex.cc | 292 +++++++++++++++++++++++++++---------------- apt-pkg/deb/debmetaindex.h | 28 +++-- 6 files changed, 252 insertions(+), 146 deletions(-) (limited to 'apt-pkg/deb') diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index 5beb83665..73d72c729 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -149,9 +149,12 @@ unsigned long debSourcesIndex::Size() const // PackagesIndex::debPackagesIndex - Contructor /*{{{*/ // --------------------------------------------------------------------- /* */ -debPackagesIndex::debPackagesIndex(string URI,string Dist,string Section,bool Trusted) : - pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section) +debPackagesIndex::debPackagesIndex(string const &URI, string const &Dist, string const &Section, + bool const &Trusted, string const &Arch) : + pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section), Architecture(Arch) { + if (Architecture == "native") + Architecture = _config->Find("APT::Architecture"); } /*}}}*/ // PackagesIndex::ArchiveInfo - Short version of the archive url /*{{{*/ @@ -171,6 +174,8 @@ string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const Res += " "; Res += Ver.ParentPkg().Name(); Res += " "; + Res += Ver.Arch(); + Res += " "; Res += Ver.VerStr(); return Res; } @@ -204,6 +209,8 @@ string debPackagesIndex::Info(const char *Type) const else Info += Dist + '/' + Section; Info += " "; + Info += Architecture; + Info += " "; Info += Type; return Info; } @@ -227,7 +234,7 @@ string debPackagesIndex::IndexURI(const char *Type) const } else Res = URI + "dists/" + Dist + '/' + Section + - "/binary-" + _config->Find("APT::Architecture") + '/'; + "/binary-" + Architecture + '/'; Res += Type; return Res; @@ -259,7 +266,7 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const { string PackageFile = IndexFile("Packages"); FileFd Pkg(PackageFile,FileFd::ReadOnly); - debListParser Parser(&Pkg); + debListParser Parser(&Pkg, Architecture); if (_error->PendingError() == true) return _error->Error("Problem opening %s",PackageFile.c_str()); diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h index c0e8d7d8e..766e8b214 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@ -46,6 +46,7 @@ class debPackagesIndex : public pkgIndexFile string URI; string Dist; string Section; + string Architecture; string Info(const char *Type) const; string IndexFile(const char *Type) const; @@ -69,7 +70,8 @@ class debPackagesIndex : public pkgIndexFile virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; - debPackagesIndex(string URI,string Dist,string Section,bool Trusted); + debPackagesIndex(string const &URI, string const &Dist, string const &Section, + bool const &Trusted, string const &Arch = "native"); }; class debTranslationsIndex : public pkgIndexFile diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index fe68aec0b..b57eca813 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -32,10 +32,13 @@ static debListParser::WordList PrioList[] = {{"important",pkgCache::State::Impor // ListParser::debListParser - Constructor /*{{{*/ // --------------------------------------------------------------------- -/* */ -debListParser::debListParser(FileFd *File) : Tags(File) -{ - Arch = _config->Find("APT::architecture"); +/* Provide an architecture and only this one and "all" will be accepted + in Step(), if no Architecture is given we will accept every arch + we would accept in general with checkArchitecture() */ +debListParser::debListParser(FileFd *File, string const &Arch) : Tags(File), + Arch(Arch) { + if (Arch == "native") + this->Arch = _config->Find("APT::Architecture"); } /*}}}*/ // ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/ @@ -64,13 +67,19 @@ string debListParser::Package() { // --------------------------------------------------------------------- /* This will return the Architecture of the package this section describes Note that architecture "all" packages will get the architecture of the - Packages file parsed here */ + Packages file parsed here. */ string debListParser::Architecture() { string const Result = Section.FindS("Architecture"); - if (Result.empty() == true) - return Arch; - if (Result == "all") - return Arch; + if (Result.empty() == true || Result == "all") { + if (Arch.empty() == true) + /* FIXME: this is a problem for installed arch all + packages as we don't know from which arch this + package was installed - and therefore which + dependency this package resolves. */ + return _config->Find("APT::Architecture"); + else + return Arch; + } return Result; } /*}}}*/ @@ -199,8 +208,12 @@ bool debListParser::UsePackage(pkgCache::PkgIterator Pkg, { if (Pkg->Section == 0) Pkg->Section = UniqFindTagWrite("Section"); - if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false) - return false; + + // Packages which are not from "our" arch doesn't get the essential flag + string const static myArch = _config->Find("APT::Architecture"); + if (Pkg->Arch != 0 && myArch == Pkg.Arch()) + if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false) + return false; if (Section.FindFlag("Important",Pkg->Flags,pkgCache::Flag::Important) == false) return false; @@ -630,17 +643,23 @@ bool debListParser::Step() /* See if this is the correct Architecture, if it isn't then we drop the whole section. A missing arch tag only happens (in theory) inside the Status file, so that is a positive return */ - const char *Start; - const char *Stop; - if (Section.Find("Architecture",Start,Stop) == false) + string const Architecture = Section.FindS("Architecture"); + if (Architecture.empty() == true) return true; - //FIXME: Accept different Architectures here - if (stringcmp(Arch,Start,Stop) == 0) - return true; + if (Arch.empty() == true) + { + if (APT::Configuration::checkArchitecture(Architecture) == true) + return true; + } + else + { + if (Architecture == Arch) + return true; - if (stringcmp(Start,Stop,"all") == 0) - return true; + if (Architecture == "all") + return true; + } iOffset = Tags.Offset(); } diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 5f91e073e..cba4f8e5d 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -69,7 +69,7 @@ class debListParser : public pkgCacheGenerator::ListParser bool const &StripMultiArch = false); static const char *ConvertRelation(const char *I,unsigned int &Op); - debListParser(FileFd *File); + debListParser(FileFd *File, string const &Arch = ""); }; #endif diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 8f28f053b..eb01a0156 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -8,9 +8,11 @@ #include #include +#include + using namespace std; -string debReleaseIndex::Info(const char *Type, const string Section) const +string debReleaseIndex::Info(const char *Type, string const &Section, string const &Arch) const { string Info = ::URI::SiteOnly(URI) + ' '; if (Dist[Dist.size() - 1] == '/') @@ -19,7 +21,11 @@ string debReleaseIndex::Info(const char *Type, const string Section) const Info += Dist; } else - Info += Dist + '/' + Section; + { + Info += Dist + '/' + Section; + if (Arch.empty() == true) + Info += " " + Arch; + } Info += " "; Info += Type; return Info; @@ -61,16 +67,21 @@ string debReleaseIndex::MetaIndexURI(const char *Type) const return Res; } -string debReleaseIndex::IndexURISuffix(const char *Type, const string Section) const +string debReleaseIndex::IndexURISuffix(const char *Type, string const &Section, string const &Arch) const { string Res =""; if (Dist[Dist.size() - 1] != '/') - Res += Section + "/binary-" + _config->Find("APT::Architecture") + '/'; + { + if (Arch == "native") + Res += Section + "/binary-" + _config->Find("APT::Architecture") + '/'; + else + Res += Section + "/binary-" + Arch + '/'; + } return Res + Type; } -string debReleaseIndex::IndexURI(const char *Type, const string Section) const +string debReleaseIndex::IndexURI(const char *Type, string const &Section, string const &Arch) const { if (Dist[Dist.size() - 1] == '/') { @@ -82,10 +93,10 @@ string debReleaseIndex::IndexURI(const char *Type, const string Section) const return Res + Type; } else - return URI + "dists/" + Dist + '/' + IndexURISuffix(Type, Section); + return URI + "dists/" + Dist + '/' + IndexURISuffix(Type, Section, Arch); } -string debReleaseIndex::SourceIndexURISuffix(const char *Type, const string Section) const +string debReleaseIndex::SourceIndexURISuffix(const char *Type, const string &Section) const { string Res =""; if (Dist[Dist.size() - 1] != '/') @@ -93,7 +104,7 @@ string debReleaseIndex::SourceIndexURISuffix(const char *Type, const string Sect return Res + Type; } -string debReleaseIndex::SourceIndexURI(const char *Type, const string Section) const +string debReleaseIndex::SourceIndexURI(const char *Type, const string &Section) const { string Res; if (Dist[Dist.size() - 1] == '/') @@ -108,44 +119,61 @@ string debReleaseIndex::SourceIndexURI(const char *Type, const string Section) c return URI + "dists/" + Dist + "/" + SourceIndexURISuffix(Type, Section); } -debReleaseIndex::debReleaseIndex(string URI,string Dist) -{ - this->URI = URI; - this->Dist = Dist; - this->Indexes = NULL; - this->Type = "deb"; +debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist) { + this->URI = URI; + this->Dist = Dist; + this->Indexes = NULL; + this->Type = "deb"; } -debReleaseIndex::~debReleaseIndex() -{ - for (vector::const_iterator I = SectionEntries.begin(); - I != SectionEntries.end(); I++) - delete *I; +debReleaseIndex::~debReleaseIndex() { + for (map >::const_iterator A = ArchEntries.begin(); + A != ArchEntries.end(); ++A) + for (vector::const_iterator S = A->second.begin(); + S != A->second.end(); ++S) + delete *S; } -vector * debReleaseIndex::ComputeIndexTargets() const -{ - vector * IndexTargets = new vector ; - for (vector ::const_iterator I = SectionEntries.begin(); - I != SectionEntries.end(); - I++) - { - IndexTarget * Target = new IndexTarget(); - Target->ShortDesc = (*I)->IsSrc ? "Sources" : "Packages"; - Target->MetaKey - = (*I)->IsSrc ? SourceIndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section) - : IndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section); - Target->URI - = (*I)->IsSrc ? SourceIndexURI(Target->ShortDesc.c_str(), (*I)->Section) - : IndexURI(Target->ShortDesc.c_str(), (*I)->Section); - - Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section); - IndexTargets->push_back (Target); - } - return IndexTargets; +vector * debReleaseIndex::ComputeIndexTargets() const { + vector * IndexTargets = new vector ; + + map >::const_iterator const src = ArchEntries.find("source"); + if (src != ArchEntries.end()) { + vector const SectionEntries = src->second; + for (vector::const_iterator I = SectionEntries.begin(); + I != SectionEntries.end(); ++I) { + IndexTarget * Target = new IndexTarget(); + Target->ShortDesc = "Sources"; + Target->MetaKey = SourceIndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section); + Target->URI = SourceIndexURI(Target->ShortDesc.c_str(), (*I)->Section); + Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section); + IndexTargets->push_back (Target); + } + } + + // Only source release + if (IndexTargets->empty() == false && ArchEntries.size() == 1) + return IndexTargets; + + for (map >::const_iterator a = ArchEntries.begin(); + a != ArchEntries.end(); ++a) { + if (a->first == "source") + continue; + for (vector ::const_iterator I = a->second.begin(); + I != a->second.end(); ++I) { + IndexTarget * Target = new IndexTarget(); + Target->ShortDesc = "Packages"; + Target->MetaKey = IndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section, a->first); + Target->URI = IndexURI(Target->ShortDesc.c_str(), (*I)->Section, a->first); + Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section, a->first); + IndexTargets->push_back (Target); + } + } + + return IndexTargets; } /*}}}*/ -bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const +bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const { // special case for --print-uris if (GetAll) { @@ -170,23 +198,27 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const ComputeIndexTargets(), new indexRecords (Dist)); - // Queue the translations - std::vector const lang = APT::Configuration::getLanguages(true); - for (vector::const_iterator I = SectionEntries.begin(); - I != SectionEntries.end(); I++) { - - if((*I)->IsSrc) - continue; - - for (vector::const_iterator l = lang.begin(); - l != lang.end(); l++) - { - debTranslationsIndex i = debTranslationsIndex(URI,Dist,(*I)->Section,(*l).c_str()); - i.GetIndexes(Owner); - } - } - - return true; + // Queue the translations + std::vector const lang = APT::Configuration::getLanguages(true); + map > sections; + for (map >::const_iterator a = ArchEntries.begin(); + a != ArchEntries.end(); ++a) { + if (a->first == "source") + continue; + for (vector::const_iterator I = a->second.begin(); + I != a->second.end(); I++) + sections[(*I)->Section].insert(lang.begin(), lang.end()); + } + + for (map >::const_iterator s = sections.begin(); + s != sections.end(); ++s) + for (set::const_iterator l = s->second.begin(); + l != s->second.end(); l++) { + debTranslationsIndex i = debTranslationsIndex(URI,Dist,s->first,(*l).c_str()); + i.GetIndexes(Owner); + } + + return true; } bool debReleaseIndex::IsTrusted() const @@ -203,71 +235,111 @@ bool debReleaseIndex::IsTrusted() const return false; } -vector *debReleaseIndex::GetIndexFiles() -{ - if (Indexes != NULL) - return Indexes; - - Indexes = new vector ; - std::vector const lang = APT::Configuration::getLanguages(true); - for (vector::const_iterator I = SectionEntries.begin(); - I != SectionEntries.end(); I++) { - if ((*I)->IsSrc) - Indexes->push_back(new debSourcesIndex (URI, Dist, (*I)->Section, IsTrusted())); - else - { - Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted())); - - for (vector::const_iterator l = lang.begin(); - l != lang.end(); l++) - Indexes->push_back(new debTranslationsIndex(URI,Dist,(*I)->Section,(*l).c_str())); - } - } +vector *debReleaseIndex::GetIndexFiles() { + if (Indexes != NULL) + return Indexes; + + Indexes = new vector ; + map >::const_iterator const src = ArchEntries.find("source"); + if (src != ArchEntries.end()) { + vector const SectionEntries = src->second; + for (vector::const_iterator I = SectionEntries.begin(); + I != SectionEntries.end(); I++) + Indexes->push_back(new debSourcesIndex (URI, Dist, (*I)->Section, IsTrusted())); + } + + // Only source release + if (Indexes->empty() == false && ArchEntries.size() == 1) + return Indexes; + + std::vector const lang = APT::Configuration::getLanguages(true); + map > sections; + for (map >::const_iterator a = ArchEntries.begin(); + a != ArchEntries.end(); ++a) { + if (a->first == "source") + continue; + for (vector::const_iterator I = a->second.begin(); + I != a->second.end(); I++) { + Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted(), a->first)); + sections[(*I)->Section].insert(lang.begin(), lang.end()); + } + } + + for (map >::const_iterator s = sections.begin(); + s != sections.end(); ++s) + for (set::const_iterator l = s->second.begin(); + l != s->second.end(); l++) + Indexes->push_back(new debTranslationsIndex(URI,Dist,s->first,(*l).c_str())); + + return Indexes; +} - return Indexes; +void debReleaseIndex::PushSectionEntry(vector const &Archs, const debSectionEntry *Entry) { + for (vector::const_iterator a = Archs.begin(); + a != Archs.end(); ++a) + ArchEntries[*a].push_back(new debSectionEntry(Entry->Section, Entry->IsSrc)); + delete Entry; } -void debReleaseIndex::PushSectionEntry(const debSectionEntry *Entry) -{ - SectionEntries.push_back(Entry); +void debReleaseIndex::PushSectionEntry(string const &Arch, const debSectionEntry *Entry) { + ArchEntries[Arch].push_back(Entry); } -debReleaseIndex::debSectionEntry::debSectionEntry (string Section, bool IsSrc): Section(Section) -{ - this->IsSrc = IsSrc; +void debReleaseIndex::PushSectionEntry(const debSectionEntry *Entry) { + if (Entry->IsSrc == true) + PushSectionEntry("source", Entry); + else { + for (map >::iterator a = ArchEntries.begin(); + a != ArchEntries.end(); ++a) { + a->second.push_back(Entry); + } + } } +debReleaseIndex::debSectionEntry::debSectionEntry (string const &Section, + bool const &IsSrc): Section(Section), IsSrc(IsSrc) +{} + class debSLTypeDebian : public pkgSourceList::Type { protected: - bool CreateItemInternal(vector &List,string URI, - string Dist,string Section, - bool IsSrc) const + bool CreateItemInternal(vector &List, string const &URI, + string const &Dist, string const &Section, + bool const &IsSrc, map const &Options) const { - for (vector::const_iterator I = List.begin(); + map::const_iterator const arch = Options.find("arch"); + vector const Archs = + (arch != Options.end()) ? ExplodeString(arch->second) : + APT::Configuration::getArchitectures(); + + for (vector::const_iterator I = List.begin(); I != List.end(); I++) { - // This check insures that there will be only one Release file - // queued for all the Packages files and Sources files it - // corresponds to. - if (strcmp((*I)->GetType(), "deb") == 0) + // We only worry about debian entries here + if (strcmp((*I)->GetType(), "deb") != 0) + continue; + + debReleaseIndex *Deb = (debReleaseIndex *) (*I); + /* This check insures that there will be only one Release file + queued for all the Packages files and Sources files it + corresponds to. */ + if (Deb->GetURI() == URI && Deb->GetDist() == Dist) { - debReleaseIndex *Deb = (debReleaseIndex *) (*I); - // This check insures that there will be only one Release file - // queued for all the Packages files and Sources files it - // corresponds to. - if (Deb->GetURI() == URI && Deb->GetDist() == Dist) - { - Deb->PushSectionEntry(new debReleaseIndex::debSectionEntry(Section, IsSrc)); - return true; - } + if (IsSrc == true) + Deb->PushSectionEntry("source", new debReleaseIndex::debSectionEntry(Section, IsSrc)); + else + Deb->PushSectionEntry(Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc)); + return true; } } // No currently created Release file indexes this entry, so we create a new one. // XXX determine whether this release is trusted or not - debReleaseIndex *Deb = new debReleaseIndex(URI,Dist); - Deb->PushSectionEntry (new debReleaseIndex::debSectionEntry(Section, IsSrc)); + debReleaseIndex *Deb = new debReleaseIndex(URI, Dist); + if (IsSrc == true) + Deb->PushSectionEntry ("source", new debReleaseIndex::debSectionEntry(Section, IsSrc)); + else + Deb->PushSectionEntry (Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc)); List.push_back(Deb); return true; } @@ -277,10 +349,11 @@ class debSLTypeDeb : public debSLTypeDebian { public: - bool CreateItem(vector &List,string URI, - string Dist,string Section) const + bool CreateItem(vector &List, string const &URI, + string const &Dist, string const &Section, + std::map const &Options) const { - return CreateItemInternal(List, URI, Dist, Section, false); + return CreateItemInternal(List, URI, Dist, Section, false, Options); } debSLTypeDeb() @@ -294,10 +367,11 @@ class debSLTypeDebSrc : public debSLTypeDebian { public: - bool CreateItem(vector &List,string URI, - string Dist,string Section) const + bool CreateItem(vector &List, string const &URI, + string const &Dist, string const &Section, + std::map const &Options) const { - return CreateItemInternal(List, URI, Dist, Section, true); + return CreateItemInternal(List, URI, Dist, Section, true, Options); } debSLTypeDebSrc() diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h index 8e6a1463b..360fa5419 100644 --- a/apt-pkg/deb/debmetaindex.h +++ b/apt-pkg/deb/debmetaindex.h @@ -5,40 +5,44 @@ #include #include +#include + class debReleaseIndex : public metaIndex { public: class debSectionEntry { public: - debSectionEntry (string Section, bool IsSrc); - bool IsSrc; - string Section; + debSectionEntry (string const &Section, bool const &IsSrc); + string const Section; + bool const IsSrc; }; private: - vector SectionEntries; + std::map > ArchEntries; public: - debReleaseIndex(string URI, string Dist); + debReleaseIndex(string const &URI, string const &Dist); ~debReleaseIndex(); - virtual string ArchiveURI(string File) const {return URI + File;}; - virtual bool GetIndexes(pkgAcquire *Owner, bool GetAll=false) const; + virtual string ArchiveURI(string const &File) const {return URI + File;}; + virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const; vector * ComputeIndexTargets() const; - string Info(const char *Type, const string Section) const; + string Info(const char *Type, string const &Section, string const &Arch="") const; string MetaIndexInfo(const char *Type) const; string MetaIndexFile(const char *Types) const; string MetaIndexURI(const char *Type) const; - string IndexURI(const char *Type, const string Section) const; - string IndexURISuffix(const char *Type, const string Section) const; - string SourceIndexURI(const char *Type, const string Section) const; - string SourceIndexURISuffix(const char *Type, const string Section) const; + string IndexURI(const char *Type, string const &Section, string const &Arch="native") const; + string IndexURISuffix(const char *Type, string const &Section, string const &Arch="native") const; + string SourceIndexURI(const char *Type, const string &Section) const; + string SourceIndexURISuffix(const char *Type, const string &Section) const; virtual vector *GetIndexFiles(); virtual bool IsTrusted() const; + void PushSectionEntry(vector const &Archs, const debSectionEntry *Entry); + void PushSectionEntry(string const &Arch, const debSectionEntry *Entry); void PushSectionEntry(const debSectionEntry *Entry); }; -- cgit v1.2.3 From 25396fb06350344996a20d05423562f08a4165db Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 27 Dec 2009 19:39:47 +0100 Subject: Split ListParser::NewDepends into two methods to use these new method for creating the dependencies needed for our groups: For now for all groups only one package can be installed at the same time which conflicts with each other packages in the group. The exceptions are architecture all package. Also, the Multi-Arch field is now parsed, but not used for now. --- apt-pkg/deb/deblistparser.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'apt-pkg/deb') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index b57eca813..f683de423 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -104,6 +104,30 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) // Parse the architecture Ver->Arch = WriteUniqString(Architecture()); + // Parse multi-arch + if (Section.FindS("Architecture") == "all") + /* Arch all packages can't have a Multi-Arch field, + but we need a special treatment for them nonetheless */ + Ver->MultiArch = pkgCache::Version::All; + else + { + string const MultiArch = Section.FindS("Multi-Arch"); + if (MultiArch.empty() == true) + Ver->MultiArch = pkgCache::Version::None; + else if (MultiArch == "same") + Ver->MultiArch = pkgCache::Version::Same; + else if (MultiArch == "foreign") + Ver->MultiArch = pkgCache::Version::Foreign; + else if (MultiArch == "allowed") + Ver->MultiArch = pkgCache::Version::Allowed; + else + { + _error->Warning("Unknown Multi-Arch type »%s« for package »%s«", + MultiArch.c_str(), Section.FindS("Package").c_str()); + Ver->MultiArch = pkgCache::Version::None; + } + } + // Archive Size Ver->Size = (unsigned)Section.FindI("Size"); -- cgit v1.2.3 From 857e9c13d8d9808fcd1ac8ff3469f6c0b90b7fea Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 7 Feb 2010 12:38:13 +0100 Subject: Drop the Arch information from the Version structure as we can get the information from the parent package now --- apt-pkg/deb/deblistparser.cc | 10 +++++++--- apt-pkg/deb/deblistparser.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'apt-pkg/deb') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index f683de423..26841d3d2 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -83,6 +83,13 @@ string debListParser::Architecture() { return Result; } /*}}}*/ +// ListParser::ArchitectureAll /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debListParser::ArchitectureAll() { + return Section.FindS("Architecture") == "all"; +} + /*}}}*/ // ListParser::Version - Return the version string /*{{{*/ // --------------------------------------------------------------------- /* This is to return the string describing the version in debian form, @@ -101,9 +108,6 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) // Parse the section Ver->Section = UniqFindTagWrite("Section"); - // Parse the architecture - Ver->Arch = WriteUniqString(Architecture()); - // Parse multi-arch if (Section.FindS("Architecture") == "all") /* Arch all packages can't have a Multi-Arch field, diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index cba4f8e5d..8da051530 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -47,6 +47,7 @@ class debListParser : public pkgCacheGenerator::ListParser // These all operate against the current section virtual string Package(); virtual string Architecture(); + virtual bool ArchitectureAll(); virtual string Version(); virtual bool NewVersion(pkgCache::VerIterator Ver); virtual string Description(); -- cgit v1.2.3 From 67e0766f0eab85ce1aeacee75fc6b200f36996c9 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 10 Feb 2010 22:45:58 +0100 Subject: Foreign Versions add an implicit Provides to the other packages in the group --- apt-pkg/deb/deblistparser.cc | 55 +++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 19 deletions(-) (limited to 'apt-pkg/deb') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 26841d3d2..b6082cdd5 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -618,29 +618,46 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver) { const char *Start; const char *Stop; - if (Section.Find("Provides",Start,Stop) == false) - return true; - - string Package; - string Version; - unsigned int Op; - - while (1) + if (Section.Find("Provides",Start,Stop) == true) { - Start = ParseDepends(Start,Stop,Package,Version,Op); - if (Start == 0) - return _error->Error("Problem parsing Provides line"); - if (Op != pkgCache::Dep::NoOp) { - _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str()); - } else { - if (NewProvides(Ver,Package,Version) == false) - return false; + string Package; + string Version; + string const Arch = Ver.Arch(); + unsigned int Op; + + while (1) + { + Start = ParseDepends(Start,Stop,Package,Version,Op); + if (Start == 0) + return _error->Error("Problem parsing Provides line"); + if (Op != pkgCache::Dep::NoOp) { + _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str()); + } else { + if (NewProvides(Ver, Package, Arch, Version) == false) + return false; + } + + if (Start == Stop) + break; } + } - if (Start == Stop) - break; + if (Ver->MultiArch != pkgCache::Version::Foreign) + return true; + + std::vector const archs = APT::Configuration::getArchitectures(); + if (archs.size() <= 1) + return true; + + string const Package = Ver.ParentPkg().Name(); + string const Version = Ver.VerStr(); + for (std::vector::const_iterator a = archs.begin(); + a != archs.end(); ++a) + { + if (NewProvides(Ver, Package, *a, Version) == false) + return false; } - + return true; } /*}}}*/ -- cgit v1.2.3 From 4d174dc84ea184b5afa81abb3b94e2ef3380ece8 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 11 Feb 2010 12:19:48 +0100 Subject: Add Multi-Arch: allowed support by creating an implicit provide of name:any for such packages, so dependencies in this style can be easily resolved. --- apt-pkg/deb/deblistparser.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'apt-pkg/deb') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index b6082cdd5..3726a6a04 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -642,6 +642,12 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver) } } + if (Ver->MultiArch == pkgCache::Version::Allowed) + { + string const Package = string(Ver.ParentPkg().Name()).append(":").append("any"); + NewProvides(Ver, Package, "any", Ver.VerStr()); + } + if (Ver->MultiArch != pkgCache::Version::Foreign) return true; -- cgit v1.2.3 From 803ea2a87f81252b2c0d541b8502ed206ce57c84 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 12 Feb 2010 00:04:31 +0100 Subject: Add yet another pseudo package which isn't as pseudo as the others: Arch all packages are now represented by arch depending packages which all depend on a package with the same name and the special arch "all". This packages has NO dependencies, but beside this the same information. It is the only package which has a size, the arch depending ones all have a zero size. While the arch depending pseudo packages are used for dependency resolution the arch "all" package is used for downloading and ordering of the package. --- apt-pkg/deb/deblistparser.cc | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'apt-pkg/deb') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 3726a6a04..b3d95164a 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -148,6 +148,24 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) Ver->Priority = pkgCache::State::Extra; } + if (Ver->MultiArch == pkgCache::Version::All) + { + /* We maintain a "pseudo" arch=all package for architecture all versions + on which these versions can depend on. This pseudo package is many used + for downloading/installing: The other pseudo-packages will degenerate + to a NOP in the download/install step - this package will ensure that + it is downloaded only one time and installed only one time -- even if + the architecture bound versions coming in and out on regular basis. */ + if (strcmp(Ver.Arch(true),"all") == 0) + return true; + else + { + // our pseudo packages have no size to not confuse the fetcher + Ver->Size = 0; + Ver->InstalledSize = 0; + } + } + if (ParseDepends(Ver,"Depends",pkgCache::Dep::Depends) == false) return false; if (ParseDepends(Ver,"Pre-Depends",pkgCache::Dep::PreDepends) == false) @@ -593,7 +611,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver, return true; string Package; - string const pkgArch = Ver.Arch(); + string const pkgArch = Ver.Arch(true); string Version; unsigned int Op; @@ -622,7 +640,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver) { string Package; string Version; - string const Arch = Ver.Arch(); + string const Arch = Ver.Arch(true); unsigned int Op; while (1) -- cgit v1.2.3 From 42d71ab5fe58953a680bd300a99d173e23430d7c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 12 Feb 2010 17:17:16 +0100 Subject: In SingleArch environments we don't need the arch "all" pseudo package for handling arch:all packages, so we create only one package and stop calling it a pseudo package. --- apt-pkg/deb/deblistparser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/deb') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index b3d95164a..1948aedf3 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -158,7 +158,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) the architecture bound versions coming in and out on regular basis. */ if (strcmp(Ver.Arch(true),"all") == 0) return true; - else + else if (Ver.Pseudo() == true) { // our pseudo packages have no size to not confuse the fetcher Ver->Size = 0; -- cgit v1.2.3