diff options
author | Michael Vogt <mvo@debian.org> | 2015-06-23 12:17:35 +0100 |
---|---|---|
committer | Michael Vogt <mvo@debian.org> | 2015-06-23 12:17:35 +0100 |
commit | 245dde96193702f7f51389d3583dee547f8ba366 (patch) | |
tree | 6cf8c191641c760bcc6a6c08fb0ff65d27e0cffd /apt-pkg/deb/debmetaindex.cc | |
parent | 5530255b5f3ad7de2e23dfcb39ce325001126501 (diff) | |
parent | c8a4ce6cbed57ae108dc955d4a850f9b129a0693 (diff) |
Merge remote-tracking branch 'donkult/debian/experimental' into debian/experimental
Diffstat (limited to 'apt-pkg/deb/debmetaindex.cc')
-rw-r--r-- | apt-pkg/deb/debmetaindex.cc | 602 |
1 files changed, 333 insertions, 269 deletions
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index c103da8f7..34fc98838 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -1,5 +1,6 @@ #include <config.h> +#include <apt-pkg/error.h> #include <apt-pkg/debmetaindex.h> #include <apt-pkg/debindexfile.h> #include <apt-pkg/strutl.h> @@ -10,10 +11,12 @@ #include <apt-pkg/indexrecords.h> #include <apt-pkg/sourcelist.h> #include <apt-pkg/hashes.h> -#include <apt-pkg/macros.h> #include <apt-pkg/metaindex.h> +#include <apt-pkg/pkgcachegen.h> +#include <apt-pkg/tagfile.h> +#include <apt-pkg/gpgv.h> +#include <apt-pkg/macros.h> -#include <string.h> #include <map> #include <string> #include <utility> @@ -21,30 +24,16 @@ #include <set> #include <algorithm> -using namespace std; +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> -string debReleaseIndex::Info(const char *Type, string const &Section, string const &Arch) const -{ - string Info = ::URI::SiteOnly(URI) + ' '; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Info += Dist; - } - else - { - Info += Dist + '/' + Section; - if (Arch.empty() != true) - Info += " " + Arch; - } - Info += " "; - Info += Type; - return Info; -} +using namespace std; string debReleaseIndex::MetaIndexInfo(const char *Type) const { - string Info = ::URI::SiteOnly(URI) + ' '; + string Info = ::URI::ArchiveOnly(URI) + ' '; if (Dist[Dist.size() - 1] == '/') { if (Dist != "/") @@ -56,6 +45,10 @@ string debReleaseIndex::MetaIndexInfo(const char *Type) const Info += Type; return Info; } +std::string debReleaseIndex::Describe() const +{ + return MetaIndexInfo("Release"); +} string debReleaseIndex::MetaIndexFile(const char *Type) const { @@ -78,7 +71,6 @@ string debReleaseIndex::MetaIndexURI(const char *Type) const return Res; } -#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) std::string debReleaseIndex::LocalFileName() const { // see if we have a InRelease file @@ -92,167 +84,183 @@ std::string debReleaseIndex::LocalFileName() const return ""; } -#endif -string debReleaseIndex::IndexURISuffix(const char *Type, string const &Section, string const &Arch) const -{ - string Res =""; - if (Dist[Dist.size() - 1] != '/') - { - if (Arch == "native") - Res += Section + "/binary-" + _config->Find("APT::Architecture") + '/'; - else - Res += Section + "/binary-" + Arch + '/'; - } - return Res + Type; +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<string, vector<debSectionEntry const*> >::const_iterator A = ArchEntries.begin(); + A != ArchEntries.end(); ++A) + for (vector<const debSectionEntry *>::const_iterator S = A->second.begin(); + S != A->second.end(); ++S) + delete *S; } - -string debReleaseIndex::IndexURI(const char *Type, string const &Section, string const &Arch) const +template<typename CallC> +void foreachTarget(std::string const URI, std::string const Dist, + std::map<std::string, std::vector<debReleaseIndex::debSectionEntry const *> > 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, Arch); - } + baseURI += "dists/" + Dist + "/"; + std::string const Release = (Dist == "/") ? "" : Dist; + std::string const Site = ::URI::ArchiveOnly(URI); + std::vector<std::string> lang = APT::Configuration::getLanguages(true); + if (lang.empty()) + lang.push_back("none"); + map<string, vector<debReleaseIndex::debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source"); + if (src != ArchEntries.end()) + { + std::vector<std::string> const targets = _config->FindVector("APT::Acquire::Targets::deb-src", "", true); + for (std::vector<std::string>::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; -string debReleaseIndex::SourceIndexURISuffix(const char *Type, const string &Section) const -{ - string Res =""; - if (Dist[Dist.size() - 1] != '/') - Res += Section + "/source/"; - return Res + Type; -} + vector<debReleaseIndex::debSectionEntry const*> const SectionEntries = src->second; + for (vector<debReleaseIndex::debSectionEntry const*>::const_iterator I = SectionEntries.begin(); + I != SectionEntries.end(); ++I) + { + for (vector<std::string>::const_iterator l = lang.begin(); l != lang.end(); ++l) + { + if (*l == "none" && MetaKey.find("$(LANGUAGE)") != std::string::npos) + continue; + + std::map<std::string, std::string> Options; + Options.insert(std::make_pair("SITE", Site)); + Options.insert(std::make_pair("RELEASE", Release)); + if (MetaKey.find("$(COMPONENT)") != std::string::npos) + Options.insert(std::make_pair("COMPONENT", (*I)->Section)); + if (MetaKey.find("$(LANGUAGE)") != std::string::npos) + 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("REPO_URI", URI)); + Options.insert(std::make_pair("TARGET_OF", "deb-src")); + Options.insert(std::make_pair("CREATED_BY", *T)); + Call(MetaKey, ShortDesc, LongDesc, IsOptional, Options); + + if (MetaKey.find("$(LANGUAGE)") == std::string::npos) + break; + } -string debReleaseIndex::SourceIndexURI(const char *Type, const string &Section) const -{ - string Res; - if (Dist[Dist.size() - 1] == '/') + if (MetaKey.find("$(COMPONENT)") == std::string::npos) + break; + } + } + } + + std::vector<std::string> const targets = _config->FindVector("APT::Acquire::Targets::deb", "", true); + for (std::vector<std::string>::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<string, vector<debReleaseIndex::debSectionEntry const*> >::const_iterator a = ArchEntries.begin(); + a != ArchEntries.end(); ++a) + { + if (a->first == "source") + continue; + + for (vector <const debReleaseIndex::debSectionEntry *>::const_iterator I = a->second.begin(); + I != a->second.end(); ++I) { + + for (vector<std::string>::const_iterator l = lang.begin(); l != lang.end(); ++l) + { + if (*l == "none" && MetaKey.find("$(LANGUAGE)") != std::string::npos) + continue; + + std::map<std::string, std::string> Options; + Options.insert(std::make_pair("SITE", Site)); + Options.insert(std::make_pair("RELEASE", Release)); + if (MetaKey.find("$(COMPONENT)") != std::string::npos) + Options.insert(std::make_pair("COMPONENT", (*I)->Section)); + if (MetaKey.find("$(LANGUAGE)") != std::string::npos) + Options.insert(std::make_pair("LANGUAGE", *l)); + if (MetaKey.find("$(ARCHITECTURE)") != std::string::npos) + Options.insert(std::make_pair("ARCHITECTURE", a->first)); + Options.insert(std::make_pair("BASE_URI", baseURI)); + Options.insert(std::make_pair("REPO_URI", URI)); + Options.insert(std::make_pair("TARGET_OF", "deb")); + 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); } -string debReleaseIndex::TranslationIndexURISuffix(const char *Type, const string &Section) const -{ - string Res =""; - if (Dist[Dist.size() - 1] != '/') - Res += Section + "/i18n/Translation-"; - return Res + Type; -} -string debReleaseIndex::TranslationIndexURI(const char *Type, const string &Section) const +struct ComputeIndexTargetsClass { - string Res; - if (Dist[Dist.size() - 1] == '/') + vector <IndexTarget> IndexTargets; + + void operator()(std::string MetaKey, std::string ShortDesc, std::string LongDesc, + bool const IsOptional, std::map<std::string, std::string> Options) { - if (Dist != "/") - Res = URI + Dist; - else - Res = URI; - return Res + Type; + for (std::map<std::string, std::string>::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); + } + IndexTarget Target( + MetaKey, + ShortDesc, + LongDesc, + Options.find("BASE_URI")->second + MetaKey, + IsOptional, + Options + ); + IndexTargets.push_back(Target); } - else - return URI + "dists/" + Dist + "/" + TranslationIndexURISuffix(Type, Section); -} - -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); +std::vector<IndexTarget> debReleaseIndex::GetIndexTargets() const +{ + ComputeIndexTargetsClass comp; + foreachTarget(URI, Dist, ArchEntries, comp); + return comp.IndexTargets; } -debReleaseIndex::~debReleaseIndex() { - for (map<string, vector<debSectionEntry const*> >::const_iterator A = ArchEntries.begin(); - A != ArchEntries.end(); ++A) - for (vector<const debSectionEntry *>::const_iterator S = A->second.begin(); - S != A->second.end(); ++S) - delete *S; -} -vector <IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const { - vector <IndexTarget *>* IndexTargets = new vector <IndexTarget *>; - - map<string, vector<debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source"); - if (src != ArchEntries.end()) { - vector<debSectionEntry const*> const SectionEntries = src->second; - for (vector<debSectionEntry const*>::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; - - std::set<std::string> sections; - for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin(); - a != ArchEntries.end(); ++a) { - if (a->first == "source") - continue; - for (vector <const debSectionEntry *>::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); - sections.insert((*I)->Section); - } - } - - std::vector<std::string> lang = APT::Configuration::getLanguages(true); - std::vector<std::string>::iterator lend = std::remove(lang.begin(), lang.end(), "none"); - if (lend != lang.end()) - lang.erase(lend); - - if (lang.empty() == true) - return IndexTargets; - - // get the Translation-* files, later we will skip download of non-existent if we have an index - for (std::set<std::string>::const_iterator s = sections.begin(); - s != sections.end(); ++s) { - for (std::vector<std::string>::const_iterator l = lang.begin(); - l != lang.end(); ++l) { - IndexTarget * Target = new OptionalIndexTarget(); - Target->ShortDesc = "Translation-" + *l; - Target->MetaKey = TranslationIndexURISuffix(l->c_str(), *s); - Target->URI = TranslationIndexURI(l->c_str(), *s); - Target->Description = Info (Target->ShortDesc.c_str(), *s); - IndexTargets->push_back(Target); - } - } - - return IndexTargets; -} /*}}}*/ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const { - bool const tryInRelease = _config->FindB("Acquire::TryInRelease", true); - indexRecords * const iR = new indexRecords(Dist); if (Trusted == ALWAYS_TRUSTED) iR->SetTrusted(true); @@ -260,37 +268,17 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const iR->SetTrusted(false); // special case for --print-uris - if (GetAll) { - vector <IndexTarget *> *targets = ComputeIndexTargets(); - for (vector <IndexTarget*>::const_iterator Target = targets->begin(); Target != targets->end(); ++Target) { - new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description, - (*Target)->ShortDesc, HashStringList()); - } - delete targets; - - // this is normally created in pkgAcqMetaSig, but if we run - // in --print-uris mode, we add it here - if (tryInRelease == false) - new pkgAcqMetaIndex(Owner, NULL, - MetaIndexURI("Release"), - MetaIndexInfo("Release"), "Release", - MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg", - ComputeIndexTargets(), - iR); + std::vector<IndexTarget> const targets = GetIndexTargets(); +#define APT_TARGET(X) IndexTarget("", X, MetaIndexInfo(X), MetaIndexURI(X), false, std::map<std::string,std::string>()) + 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<IndexTarget>::const_iterator Target = targets.begin(); Target != targets.end(); ++Target) + new pkgAcqIndex(Owner, TransactionManager, *Target); } - if (tryInRelease == true) - new pkgAcqMetaClearSig(Owner, - MetaIndexURI("InRelease"), MetaIndexInfo("InRelease"), "InRelease", - MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release", - MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg", - ComputeIndexTargets(), - iR); - else - new pkgAcqMetaIndex(Owner, NULL, - MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release", - MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg", - ComputeIndexTargets(), - iR); return true; } @@ -327,45 +315,25 @@ bool debReleaseIndex::IsTrusted() const return FileExists(VerifiedSigFile); } -vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() { - if (Indexes != NULL) - return Indexes; - - Indexes = new vector <pkgIndexFile*>; - map<string, vector<debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source"); - if (src != ArchEntries.end()) { - vector<debSectionEntry const*> const SectionEntries = src->second; - for (vector<debSectionEntry const*>::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<std::string> const lang = APT::Configuration::getLanguages(true); - map<string, set<string> > sections; - for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin(); - a != ArchEntries.end(); ++a) { - if (a->first == "source") - continue; - for (vector<debSectionEntry const*>::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<string, set<string> >::const_iterator s = sections.begin(); - s != sections.end(); ++s) - for (set<string>::const_iterator l = s->second.begin(); - l != s->second.end(); ++l) { - if (*l == "none") continue; - Indexes->push_back(new debTranslationsIndex(URI,Dist,s->first,(*l).c_str())); - } - - return Indexes; +std::vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() +{ + if (Indexes != NULL) + return Indexes; + + Indexes = new std::vector<pkgIndexFile*>(); + std::vector<IndexTarget> const Targets = GetIndexTargets(); + bool const istrusted = IsTrusted(); + for (std::vector<IndexTarget>::const_iterator T = Targets.begin(); T != Targets.end(); ++T) + { + std::string const TargetName = T->Option(IndexTarget::CREATED_BY); + if (TargetName == "Packages") + Indexes->push_back(new debPackagesIndex(*T, istrusted)); + else if (TargetName == "Sources") + Indexes->push_back(new debSourcesIndex(*T, istrusted)); + else if (TargetName == "Translations") + Indexes->push_back(new debTranslationsIndex(*T)); + } + return Indexes; } void debReleaseIndex::PushSectionEntry(vector<string> const &Archs, const debSectionEntry *Entry) { @@ -379,22 +347,121 @@ void debReleaseIndex::PushSectionEntry(string const &Arch, const debSectionEntry ArchEntries[Arch].push_back(Entry); } -void debReleaseIndex::PushSectionEntry(const debSectionEntry *Entry) { - if (Entry->IsSrc == true) - PushSectionEntry("source", Entry); - else { - for (map<string, vector<const debSectionEntry *> >::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 +static bool ReleaseFileName(debReleaseIndex const * const That, std::string &ReleaseFile) +{ + ReleaseFile = That->MetaIndexFile("InRelease"); + bool releaseExists = false; + if (FileExists(ReleaseFile) == true) + releaseExists = true; + else + { + ReleaseFile = That->MetaIndexFile("Release"); + if (FileExists(ReleaseFile)) + releaseExists = true; + } + return releaseExists; +} + +bool debReleaseIndex::Merge(pkgCacheGenerator &Gen,OpProgress * /*Prog*/) const/*{{{*/ +{ + std::string ReleaseFile; + bool const releaseExists = ReleaseFileName(this, ReleaseFile); + + ::URI Tmp(URI); + if (Gen.SelectReleaseFile(ReleaseFile, Tmp.Host) == false) + return _error->Error("Problem with SelectReleaseFile %s", ReleaseFile.c_str()); + + if (releaseExists == false) + return true; + + FileFd Rel; + // Beware: The 'Release' file might be clearsigned in case the + // signature for an 'InRelease' file couldn't be checked + if (OpenMaybeClearSignedFile(ReleaseFile, Rel) == false) + return false; + if (_error->PendingError() == true) + return false; + + // Store the IMS information + pkgCache::RlsFileIterator File = Gen.GetCurRlsFile(); + pkgCacheGenerator::Dynamic<pkgCache::RlsFileIterator> DynFile(File); + // Rel can't be used as this is potentially a temporary file + struct stat Buf; + if (stat(ReleaseFile.c_str(), &Buf) != 0) + return _error->Errno("fstat", "Unable to stat file %s", ReleaseFile.c_str()); + File->Size = Buf.st_size; + File->mtime = Buf.st_mtime; + + pkgTagFile TagFile(&Rel, Rel.Size()); + pkgTagSection Section; + if (_error->PendingError() == true || TagFile.Step(Section) == false) + return false; + + std::string data; + #define APT_INRELEASE(TYPE, TAG, STORE) \ + data = Section.FindS(TAG); \ + if (data.empty() == false) \ + { \ + map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::TYPE, data); \ + STORE = storage; \ + } + APT_INRELEASE(MIXED, "Suite", File->Archive) + APT_INRELEASE(VERSIONNUMBER, "Version", File->Version) + APT_INRELEASE(MIXED, "Origin", File->Origin) + APT_INRELEASE(MIXED, "Codename", File->Codename) + APT_INRELEASE(MIXED, "Label", File->Label) + #undef APT_INRELEASE + Section.FindFlag("NotAutomatic", File->Flags, pkgCache::Flag::NotAutomatic); + Section.FindFlag("ButAutomaticUpgrades", File->Flags, pkgCache::Flag::ButAutomaticUpgrades); + + return !_error->PendingError(); +} + /*}}}*/ +// ReleaseIndex::FindInCache - Find this index /*{{{*/ +pkgCache::RlsFileIterator debReleaseIndex::FindInCache(pkgCache &Cache, bool const ModifyCheck) const +{ + std::string ReleaseFile; + bool const releaseExists = ReleaseFileName(this, ReleaseFile); + + pkgCache::RlsFileIterator File = Cache.RlsFileBegin(); + for (; File.end() == false; ++File) + { + if (File->FileName == 0 || ReleaseFile != File.FileName()) + continue; + + // empty means the file does not exist by "design" + if (ModifyCheck == false || (releaseExists == false && File->Size == 0)) + return File; + + struct stat St; + if (stat(File.FileName(),&St) != 0) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "ReleaseIndex::FindInCache - stat failed on " << File.FileName() << std::endl; + return pkgCache::RlsFileIterator(Cache); + } + if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "ReleaseIndex::FindInCache - size (" << St.st_size << " <> " << File->Size + << ") or mtime (" << St.st_mtime << " <> " << File->mtime + << ") doesn't match for " << File.FileName() << std::endl; + return pkgCache::RlsFileIterator(Cache); + } + return File; + } + + return File; +} + /*}}}*/ + +debDebFileMetaIndex::~debDebFileMetaIndex() {} + +class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type { protected: @@ -404,9 +471,12 @@ class debSLTypeDebian : public pkgSourceList::Type { // parse arch=, arch+= and arch-= settings map<string, string>::const_iterator arch = Options.find("arch"); - vector<string> Archs = - (arch != Options.end()) ? VectorizeString(arch->second, ',') : - APT::Configuration::getArchitectures(); + vector<string> Archs; + if (arch != Options.end()) + Archs = VectorizeString(arch->second, ','); + else + Archs = APT::Configuration::getArchitectures(); + if ((arch = Options.find("arch+")) != Options.end()) { std::vector<std::string> const plusArch = VectorizeString(arch->second, ','); @@ -427,6 +497,7 @@ class debSLTypeDebian : public pkgSourceList::Type map<string, string>::const_iterator const trusted = Options.find("trusted"); + debReleaseIndex *Deb = NULL; for (vector<metaIndex *>::const_iterator I = List.begin(); I != List.end(); ++I) { @@ -434,34 +505,23 @@ class debSLTypeDebian : public pkgSourceList::Type if (strcmp((*I)->GetType(), "deb") != 0) continue; - debReleaseIndex *Deb = (debReleaseIndex *) (*I); - if (trusted != Options.end()) - Deb->SetTrusted(StringToBool(trusted->second, false)); - /* 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) + if ((*I)->GetURI() == URI && (*I)->GetDist() == Dist) { - 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)); - } - return true; + Deb = dynamic_cast<debReleaseIndex*>(*I); + if (Deb != NULL) + break; } } // No currently created Release file indexes this entry, so we create a new one. - debReleaseIndex *Deb; - if (trusted != Options.end()) - Deb = new debReleaseIndex(URI, Dist, StringToBool(trusted->second, false)); - else + if (Deb == NULL) + { Deb = new debReleaseIndex(URI, Dist); + List.push_back(Deb); + } if (IsSrc == true) Deb->PushSectionEntry ("source", new debReleaseIndex::debSectionEntry(Section, IsSrc)); @@ -472,7 +532,10 @@ class debSLTypeDebian : public pkgSourceList::Type else Deb->PushSectionEntry (Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc)); } - List.push_back(Deb); + + if (trusted != Options.end()) + Deb->SetTrusted(StringToBool(trusted->second, false)); + return true; } }; @@ -486,7 +549,7 @@ debDebFileMetaIndex::debDebFileMetaIndex(std::string const &DebFile) } -class debSLTypeDeb : public debSLTypeDebian +class APT_HIDDEN debSLTypeDeb : public debSLTypeDebian { public: @@ -504,7 +567,7 @@ class debSLTypeDeb : public debSLTypeDebian } }; -class debSLTypeDebSrc : public debSLTypeDebian +class APT_HIDDEN debSLTypeDebSrc : public debSLTypeDebian { public: @@ -522,7 +585,7 @@ class debSLTypeDebSrc : public debSLTypeDebian } }; -class debSLTypeDebFile : public pkgSourceList::Type +class APT_HIDDEN debSLTypeDebFile : public pkgSourceList::Type { public: @@ -541,6 +604,7 @@ class debSLTypeDebFile : public pkgSourceList::Type Label = "Debian Deb File"; } }; -debSLTypeDeb _apt_DebType; -debSLTypeDebSrc _apt_DebSrcType; -debSLTypeDebFile _apt_DebFileType; + +APT_HIDDEN debSLTypeDeb _apt_DebType; +APT_HIDDEN debSLTypeDebSrc _apt_DebSrcType; +APT_HIDDEN debSLTypeDebFile _apt_DebFileType; |