X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/6de692d84ab70299ae61767460c179c6a2676b74..261727f05ca7ff7d9d6d9b8927cb5c6ad293ebce:/apt-pkg/deb/debmetaindex.cc?ds=sidebyside diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 8f28f053b..e1f86d20f 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -1,30 +1,28 @@ -// ijones, walters +#include #include #include #include +#include #include #include #include -#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include using namespace std; -string debReleaseIndex::Info(const char *Type, const string Section) const -{ - string Info = ::URI::SiteOnly(URI) + ' '; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Info += Dist; - } - else - Info += Dist + '/' + Section; - Info += " "; - Info += Type; - return Info; -} - string debReleaseIndex::MetaIndexInfo(const char *Type) const { string Info = ::URI::SiteOnly(URI) + ' '; @@ -61,226 +59,404 @@ string debReleaseIndex::MetaIndexURI(const char *Type) const return Res; } -string debReleaseIndex::IndexURISuffix(const char *Type, const string Section) const +std::string debReleaseIndex::LocalFileName() const { - string Res =""; - if (Dist[Dist.size() - 1] != '/') - Res += Section + "/binary-" + _config->Find("APT::Architecture") + '/'; - return Res + Type; + // see if we have a InRelease file + std::string PathInRelease = MetaIndexFile("InRelease"); + if (FileExists(PathInRelease)) + return PathInRelease; + + // and if not return the normal one + if (FileExists(PathInRelease)) + return MetaIndexFile("Release"); + + return ""; } - -string debReleaseIndex::IndexURI(const char *Type, const string Section) const +debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist) : + metaIndex(URI, Dist, "deb"), Trusted(CHECK_TRUST) +{} + +debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist, bool const Trusted) : + metaIndex(URI, Dist, "deb") { + SetTrusted(Trusted); +} + +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; +} + +template +void foreachTarget(std::string const URI, std::string const Dist, + std::map > const &ArchEntries, + CallC &Call) { - if (Dist[Dist.size() - 1] == '/') + bool const flatArchive = (Dist[Dist.length() - 1] == '/'); + std::string baseURI = URI; + if (flatArchive) { - string Res; if (Dist != "/") - Res = URI + Dist; - else - Res = URI; - return Res + Type; + baseURI += Dist; } else - return URI + "dists/" + Dist + '/' + IndexURISuffix(Type, Section); - } + baseURI += "dists/" + Dist + "/"; + std::string const Release = (Dist == "/") ? "" : Dist; + std::string const Site = ::URI::SiteOnly(URI); + std::vector lang = APT::Configuration::getLanguages(true); + if (lang.empty()) + lang.push_back("none"); + map >::const_iterator const src = ArchEntries.find("source"); + if (src != ArchEntries.end()) + { + std::vector const targets = _config->FindVector("APT::Acquire::Targets::deb-src", "", true); + for (std::vector::const_iterator T = targets.begin(); T != targets.end(); ++T) + { +#define APT_T_CONFIG(X) _config->Find(std::string("APT::Acquire::Targets::deb-src::") + *T + "::" + (X)) + std::string const MetaKey = APT_T_CONFIG(flatArchive ? "flatMetaKey" : "MetaKey"); + std::string const ShortDesc = APT_T_CONFIG("ShortDescription"); + std::string const LongDesc = APT_T_CONFIG(flatArchive ? "flatDescription" : "Description"); + bool const IsOptional = _config->FindB(std::string("APT::Acquire::Targets::deb-src::") + *T + "::Optional", true); +#undef APT_T_CONFIG + if (MetaKey.empty()) + continue; + + vector const SectionEntries = src->second; + for (vector::const_iterator I = SectionEntries.begin(); + I != SectionEntries.end(); ++I) + { + for (vector::const_iterator l = lang.begin(); l != lang.end(); ++l) + { + if (*l == "none" && MetaKey.find("$(LANGUAGE)") != std::string::npos) + continue; + + std::map Options; + Options.insert(std::make_pair("SITE", Site)); + Options.insert(std::make_pair("RELEASE", Release)); + Options.insert(std::make_pair("COMPONENT", (*I)->Section)); + Options.insert(std::make_pair("LANGUAGE", *l)); + Options.insert(std::make_pair("ARCHITECTURE", "source")); + Options.insert(std::make_pair("BASE_URI", baseURI)); + Options.insert(std::make_pair("CREATED_BY", *T)); + Call(MetaKey, ShortDesc, LongDesc, IsOptional, Options); + + if (MetaKey.find("$(LANGUAGE)") == std::string::npos) + break; + } -string debReleaseIndex::SourceIndexURISuffix(const char *Type, const string Section) const -{ - string Res =""; - if (Dist[Dist.size() - 1] != '/') - Res += Section + "/source/"; - return Res + Type; -} + if (MetaKey.find("$(COMPONENT)") == std::string::npos) + break; + } + } + } -string debReleaseIndex::SourceIndexURI(const char *Type, const string Section) const -{ - string Res; - if (Dist[Dist.size() - 1] == '/') + std::vector const targets = _config->FindVector("APT::Acquire::Targets::deb", "", true); + for (std::vector::const_iterator T = targets.begin(); T != targets.end(); ++T) { - if (Dist != "/") - Res = URI + Dist; - else - Res = URI; - return Res + Type; +#define APT_T_CONFIG(X) _config->Find(std::string("APT::Acquire::Targets::deb::") + *T + "::" + (X)) + std::string const MetaKey = APT_T_CONFIG(flatArchive ? "flatMetaKey" : "MetaKey"); + std::string const ShortDesc = APT_T_CONFIG("ShortDescription"); + std::string const LongDesc = APT_T_CONFIG(flatArchive ? "flatDescription" : "Description"); + bool const IsOptional = _config->FindB(std::string("APT::Acquire::Targets::deb::") + *T + "::Optional", true); +#undef APT_T_CONFIG + if (MetaKey.empty()) + continue; + + 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) { + + for (vector::const_iterator l = lang.begin(); l != lang.end(); ++l) + { + if (*l == "none" && MetaKey.find("$(LANGUAGE)") != std::string::npos) + continue; + + std::map Options; + Options.insert(std::make_pair("SITE", Site)); + Options.insert(std::make_pair("RELEASE", Release)); + Options.insert(std::make_pair("COMPONENT", (*I)->Section)); + Options.insert(std::make_pair("LANGUAGE", *l)); + Options.insert(std::make_pair("ARCHITECTURE", a->first)); + Options.insert(std::make_pair("BASE_URI", baseURI)); + Options.insert(std::make_pair("CREATED_BY", *T)); + Call(MetaKey, ShortDesc, LongDesc, IsOptional, Options); + + if (MetaKey.find("$(LANGUAGE)") == std::string::npos) + break; + } + + if (MetaKey.find("$(COMPONENT)") == std::string::npos) + break; + } + + if (MetaKey.find("$(ARCHITECTURE)") == std::string::npos) + break; + } } - else - 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() +struct ComputeIndexTargetsClass { - for (vector::const_iterator I = SectionEntries.begin(); - I != SectionEntries.end(); I++) - delete *I; -} + vector IndexTargets; -vector * debReleaseIndex::ComputeIndexTargets() const -{ - vector * IndexTargets = new vector ; - for (vector ::const_iterator I = SectionEntries.begin(); - I != SectionEntries.end(); - I++) + void operator()(std::string MetaKey, std::string ShortDesc, std::string LongDesc, + bool const IsOptional, std::map Options) { - 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; -} - /*}}}*/ -bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const -{ - // special case for --print-uris - if (GetAll) { - vector *targets = ComputeIndexTargets(); - for (vector ::const_iterator Target = targets->begin(); Target != targets->end(); Target++) { - new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description, - (*Target)->ShortDesc, HashString()); + for (std::map::const_iterator O = Options.begin(); O != Options.end(); ++O) + { + MetaKey = SubstVar(MetaKey, std::string("$(") + O->first + ")", O->second); + ShortDesc = SubstVar(ShortDesc, std::string("$(") + O->first + ")", O->second); + LongDesc = SubstVar(LongDesc, std::string("$(") + O->first + ")", O->second); } - // this is normally created in pkgAcqMetaSig, but if we run - // in --print-uris mode, we add it here - new pkgAcqMetaIndex(Owner, MetaIndexURI("Release"), - MetaIndexInfo("Release"), "Release", - MetaIndexURI("Release.gpg"), - ComputeIndexTargets(), - new indexRecords (Dist)); - + IndexTarget Target( + MetaKey, + ShortDesc, + LongDesc, + Options.find("BASE_URI")->second + MetaKey, + IsOptional, + Options + ); + IndexTargets.push_back(Target); } +}; - new pkgAcqMetaSig(Owner, MetaIndexURI("Release.gpg"), - MetaIndexInfo("Release.gpg"), "Release.gpg", - MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release", - ComputeIndexTargets(), - new indexRecords (Dist)); +std::vector debReleaseIndex::GetIndexTargets() const +{ + ComputeIndexTargetsClass comp; + foreachTarget(URI, Dist, ArchEntries, comp); + return comp.IndexTargets; +} - // 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; + /*}}}*/ +bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const +{ + indexRecords * const iR = new indexRecords(Dist); + if (Trusted == ALWAYS_TRUSTED) + iR->SetTrusted(true); + else if (Trusted == NEVER_TRUSTED) + iR->SetTrusted(false); - for (vector::const_iterator l = lang.begin(); - l != lang.end(); l++) - { - debTranslationsIndex i = debTranslationsIndex(URI,Dist,(*I)->Section,(*l).c_str()); - i.GetIndexes(Owner); - } + // special case for --print-uris + std::vector const targets = GetIndexTargets(); +#define APT_TARGET(X) IndexTarget("", X, MetaIndexInfo(X), MetaIndexURI(X), false, std::map()) + pkgAcqMetaBase * const TransactionManager = new pkgAcqMetaClearSig(Owner, + APT_TARGET("InRelease"), APT_TARGET("Release"), APT_TARGET("Release.gpg"), + targets, iR); +#undef APT_TARGET + if (GetAll) + { + for (std::vector::const_iterator Target = targets.begin(); Target != targets.end(); ++Target) + new pkgAcqIndex(Owner, TransactionManager, *Target); } return true; } +void debReleaseIndex::SetTrusted(bool const Trusted) +{ + if (Trusted == true) + this->Trusted = ALWAYS_TRUSTED; + else + this->Trusted = NEVER_TRUSTED; +} + bool debReleaseIndex::IsTrusted() const { - string VerifiedSigFile = _config->FindDir("Dir::State::lists") + - URItoFileName(MetaIndexURI("Release")) + ".gpg"; - + if (Trusted == ALWAYS_TRUSTED) + return true; + else if (Trusted == NEVER_TRUSTED) + return false; + + if(_config->FindB("APT::Authentication::TrustCDROM", false)) if(URI.substr(0,strlen("cdrom:")) == "cdrom:") return true; - + + string VerifiedSigFile = _config->FindDir("Dir::State::lists") + + URItoFileName(MetaIndexURI("Release")) + ".gpg"; + if (FileExists(VerifiedSigFile)) return true; - return false; + + VerifiedSigFile = _config->FindDir("Dir::State::lists") + + URItoFileName(MetaIndexURI("InRelease")); + + return FileExists(VerifiedSigFile); } -vector *debReleaseIndex::GetIndexFiles() +struct GetIndexFilesClass { - if (Indexes != NULL) - return Indexes; + vector * const Indexes; + std::string const URI; + std::string const Release; + bool const IsTrusted; - 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 + void operator()(std::string const &/*URI*/, std::string const &/*ShortDesc*/, std::string const &/*LongDesc*/, + bool const /*IsOptional*/, std::map Options) + { + std::string const TargetName = Options.find("CREATED_BY")->second; + if (TargetName == "Packages") { - 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())); + Indexes->push_back(new debPackagesIndex( + URI, + Release, + Options.find("COMPONENT")->second, + IsTrusted, + Options.find("ARCHITECTURE")->second + )); } + else if (TargetName == "Sources") + Indexes->push_back(new debSourcesIndex( + URI, + Release, + Options.find("COMPONENT")->second, + IsTrusted + )); + else if (TargetName == "Translations") + Indexes->push_back(new debTranslationsIndex( + URI, + Release, + Options.find("COMPONENT")->second, + Options.find("LANGUAGE")->second + )); } - return Indexes; -} + GetIndexFilesClass(std::string const &URI, std::string const &Release, bool const IsTrusted) : + Indexes(new vector ), URI(URI), Release(Release), IsTrusted(IsTrusted) {} +}; -void debReleaseIndex::PushSectionEntry(const debSectionEntry *Entry) +std::vector *debReleaseIndex::GetIndexFiles() { - SectionEntries.push_back(Entry); + if (Indexes != NULL) + return Indexes; + + GetIndexFilesClass comp(URI, Dist, IsTrusted()); + foreachTarget(URI, Dist, ArchEntries, comp); + return Indexes = comp.Indexes; } -debReleaseIndex::debSectionEntry::debSectionEntry (string Section, bool IsSrc): Section(Section) -{ - this->IsSrc = IsSrc; +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; } -class debSLTypeDebian : public pkgSourceList::Type +void debReleaseIndex::PushSectionEntry(string const &Arch, const debSectionEntry *Entry) { + ArchEntries[Arch].push_back(Entry); +} + +debReleaseIndex::debSectionEntry::debSectionEntry (string const &Section, + bool const &IsSrc): Section(Section), IsSrc(IsSrc) +{} + +class APT_HIDDEN 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(); - I != List.end(); I++) + // parse arch=, arch+= and arch-= settings + map::const_iterator arch = Options.find("arch"); + vector Archs; + if (arch != Options.end()) + Archs = VectorizeString(arch->second, ','); + else + Archs = APT::Configuration::getArchitectures(); + + if ((arch = Options.find("arch+")) != Options.end()) { - // 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) + std::vector const plusArch = VectorizeString(arch->second, ','); + for (std::vector::const_iterator plus = plusArch.begin(); plus != plusArch.end(); ++plus) + if (std::find(Archs.begin(), Archs.end(), *plus) == Archs.end()) + Archs.push_back(*plus); + } + if ((arch = Options.find("arch-")) != Options.end()) + { + std::vector const minusArch = VectorizeString(arch->second, ','); + for (std::vector::const_iterator minus = minusArch.begin(); minus != minusArch.end(); ++minus) { - 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; - } + std::vector::iterator kill = std::find(Archs.begin(), Archs.end(), *minus); + if (kill != Archs.end()) + Archs.erase(kill); + } + } + + map::const_iterator const trusted = Options.find("trusted"); + + debReleaseIndex *Deb = NULL; + for (vector::const_iterator I = List.begin(); + I != List.end(); ++I) + { + // We only worry about debian entries here + if (strcmp((*I)->GetType(), "deb") != 0) + continue; + + /* This check insures that there will be only one Release file + queued for all the Packages files and Sources files it + corresponds to. */ + if ((*I)->GetURI() == URI && (*I)->GetDist() == Dist) + { + Deb = dynamic_cast(*I); + if (Deb != NULL) + break; } } + // 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)); - List.push_back(Deb); + if (Deb == NULL) + { + Deb = new debReleaseIndex(URI, Dist); + List.push_back(Deb); + } + + if (IsSrc == true) + Deb->PushSectionEntry ("source", new debReleaseIndex::debSectionEntry(Section, IsSrc)); + else + { + if (Dist[Dist.size() - 1] == '/') + Deb->PushSectionEntry ("any", new debReleaseIndex::debSectionEntry(Section, IsSrc)); + else + Deb->PushSectionEntry (Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc)); + } + + if (trusted != Options.end()) + Deb->SetTrusted(StringToBool(trusted->second, false)); + return true; } }; -class debSLTypeDeb : public debSLTypeDebian +debDebFileMetaIndex::debDebFileMetaIndex(std::string const &DebFile) + : metaIndex(DebFile, "local-uri", "deb-dist"), DebFile(DebFile) +{ + DebIndex = new debDebPkgFileIndex(DebFile); + Indexes = new vector(); + Indexes->push_back(DebIndex); +} + + +class APT_HIDDEN 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() @@ -290,14 +466,15 @@ class debSLTypeDeb : public debSLTypeDebian } }; -class debSLTypeDebSrc : public debSLTypeDebian +class APT_HIDDEN 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() @@ -307,5 +484,26 @@ class debSLTypeDebSrc : public debSLTypeDebian } }; -debSLTypeDeb _apt_DebType; -debSLTypeDebSrc _apt_DebSrcType; +class APT_HIDDEN debSLTypeDebFile : public pkgSourceList::Type +{ + public: + + bool CreateItem(vector &List, string const &URI, + string const &/*Dist*/, string const &/*Section*/, + std::map const &/*Options*/) const + { + metaIndex *mi = new debDebFileMetaIndex(URI); + List.push_back(mi); + return true; + } + + debSLTypeDebFile() + { + Name = "deb-file"; + Label = "Debian Deb File"; + } +}; + +APT_HIDDEN debSLTypeDeb _apt_DebType; +APT_HIDDEN debSLTypeDebSrc _apt_DebSrcType; +APT_HIDDEN debSLTypeDebFile _apt_DebFileType;