diff options
Diffstat (limited to 'apt-pkg')
-rw-r--r-- | apt-pkg/acquire-item.cc | 113 | ||||
-rw-r--r-- | apt-pkg/acquire-item.h | 9 | ||||
-rw-r--r-- | apt-pkg/deb/debmetaindex.cc | 231 | ||||
-rw-r--r-- | apt-pkg/deb/debmetaindex.h | 29 | ||||
-rw-r--r-- | apt-pkg/indexcopy.cc | 18 | ||||
-rw-r--r-- | apt-pkg/indexcopy.h | 4 | ||||
-rw-r--r-- | apt-pkg/indexrecords.cc | 284 | ||||
-rw-r--r-- | apt-pkg/indexrecords.h | 88 | ||||
-rw-r--r-- | apt-pkg/metaindex.cc | 76 | ||||
-rw-r--r-- | apt-pkg/metaindex.h | 66 | ||||
-rw-r--r-- | apt-pkg/sourcelist.cc | 1 |
11 files changed, 408 insertions, 511 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 0ab52a0cd..100199bc1 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -24,7 +24,7 @@ #include <apt-pkg/fileutl.h> #include <apt-pkg/sha1.h> #include <apt-pkg/tagfile.h> -#include <apt-pkg/indexrecords.h> +#include <apt-pkg/metaindex.h> #include <apt-pkg/acquire.h> #include <apt-pkg/hashes.h> #include <apt-pkg/indexfile.h> @@ -109,9 +109,9 @@ static std::string GetDiffsPatchFileName(std::string const &Final) /*{{{*/ } /*}}}*/ -static bool AllowInsecureRepositories(indexRecords const * const MetaIndexParser, pkgAcqMetaClearSig * const TransactionManager, pkgAcquire::Item * const I) /*{{{*/ +static bool AllowInsecureRepositories(metaIndex const * const MetaIndexParser, pkgAcqMetaClearSig * const TransactionManager, pkgAcquire::Item * const I) /*{{{*/ { - if(MetaIndexParser->IsAlwaysTrusted() || _config->FindB("Acquire::AllowInsecureRepositories") == true) + if(MetaIndexParser->GetTrusted() == metaIndex::TRI_YES || _config->FindB("Acquire::AllowInsecureRepositories") == true) return true; _error->Error(_("Use --allow-insecure-repositories to force the update")); @@ -120,11 +120,11 @@ static bool AllowInsecureRepositories(indexRecords const * const MetaIndexParser return false; } /*}}}*/ -static HashStringList GetExpectedHashesFromFor(indexRecords * const Parser, std::string const &MetaKey)/*{{{*/ +static HashStringList GetExpectedHashesFromFor(metaIndex * const Parser, std::string const &MetaKey)/*{{{*/ { if (Parser == NULL) return HashStringList(); - indexRecords::checkSum * const R = Parser->Lookup(MetaKey); + metaIndex::checkSum * const R = Parser->Lookup(MetaKey); if (R == NULL) return HashStringList(); return R->Hashes; @@ -144,7 +144,8 @@ APT_CONST bool pkgAcqTransactionItem::HashesRequired() const we can at least trust them for integrity of the download itself. Only repositories without a Release file can (obviously) not have hashes – and they are very uncommon and strongly discouraged */ - return TransactionManager->MetaIndexParser != NULL; + return TransactionManager->MetaIndexParser != NULL && + TransactionManager->MetaIndexParser->GetLoadedSuccessfully() != metaIndex::TRI_UNSET; } HashStringList pkgAcqTransactionItem::GetExpectedHashes() const { @@ -900,26 +901,28 @@ bool pkgAcqMetaBase::CheckAuthDone(string const &Message) /*{{{*/ } if (RealFileExists(FinalInRelease) || RealFileExists(FinalRelease)) { - TransactionManager->LastMetaIndexParser = new indexRecords; - _error->PushToStack(); - if (RealFileExists(FinalInRelease)) - TransactionManager->LastMetaIndexParser->Load(FinalInRelease); - else - TransactionManager->LastMetaIndexParser->Load(FinalRelease); - // its unlikely to happen, but if what we have is bad ignore it - if (_error->PendingError()) + TransactionManager->LastMetaIndexParser = TransactionManager->MetaIndexParser->UnloadedClone(); + if (TransactionManager->LastMetaIndexParser != NULL) { - delete TransactionManager->LastMetaIndexParser; - TransactionManager->LastMetaIndexParser = NULL; + _error->PushToStack(); + if (RealFileExists(FinalInRelease)) + TransactionManager->LastMetaIndexParser->Load(FinalInRelease, NULL); + else + TransactionManager->LastMetaIndexParser->Load(FinalRelease, NULL); + // its unlikely to happen, but if what we have is bad ignore it + if (_error->PendingError()) + { + delete TransactionManager->LastMetaIndexParser; + TransactionManager->LastMetaIndexParser = NULL; + } + _error->RevertToStack(); } - _error->RevertToStack(); } } - if (TransactionManager->MetaIndexParser->Load(DestFile) == false) + if (TransactionManager->MetaIndexParser->Load(DestFile, &ErrorText) == false) { Status = StatAuthError; - ErrorText = TransactionManager->MetaIndexParser->ErrorText; return false; } @@ -1065,14 +1068,16 @@ bool pkgAcqMetaBase::VerifyVendor(string const &Message) /*{{{*/ TransactionManager->IMSHit = true; unlink(DestFile.c_str()); PartialFile = DestFile = GetFinalFilename(); - delete TransactionManager->MetaIndexParser; - TransactionManager->MetaIndexParser = TransactionManager->LastMetaIndexParser; + // load the 'old' file in the 'new' one instead of flipping pointers as + // the new one isn't owned by us, while the old one is so cleanup would be confused. + TransactionManager->MetaIndexParser->swapLoad(TransactionManager->LastMetaIndexParser); + delete TransactionManager->LastMetaIndexParser; TransactionManager->LastMetaIndexParser = NULL; } if (_config->FindB("Debug::pkgAcquire::Auth", false)) { - std::cerr << "Got Codename: " << TransactionManager->MetaIndexParser->GetDist() << std::endl; + std::cerr << "Got Codename: " << TransactionManager->MetaIndexParser->GetCodename() << std::endl; std::cerr << "Expecting Dist: " << TransactionManager->MetaIndexParser->GetExpectedDist() << std::endl; std::cerr << "Transformed Dist: " << Transformed << std::endl; } @@ -1083,14 +1088,14 @@ bool pkgAcqMetaBase::VerifyVendor(string const &Message) /*{{{*/ // Status = StatAuthError; // ErrorText = "Conflicting distribution; expected " // + MetaIndexParser->GetExpectedDist() + " but got " -// + MetaIndexParser->GetDist(); +// + MetaIndexParser->GetCodename(); // return false; if (!Transformed.empty()) { _error->Warning(_("Conflicting distribution: %s (expected %s but got %s)"), Desc.Description.c_str(), Transformed.c_str(), - TransactionManager->MetaIndexParser->GetDist().c_str()); + TransactionManager->MetaIndexParser->GetCodename().c_str()); } } @@ -1105,7 +1110,7 @@ pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire * const Owner, /*{{{*/ IndexTarget const &ClearsignedTarget, IndexTarget const &DetachedDataTarget, IndexTarget const &DetachedSigTarget, std::vector<IndexTarget> const &IndexTargets, - indexRecords * const MetaIndexParser) : + metaIndex * const MetaIndexParser) : pkgAcqMetaIndex(Owner, this, ClearsignedTarget, DetachedSigTarget, IndexTargets), d(NULL), ClearsignedTarget(ClearsignedTarget), DetachedDataTarget(DetachedDataTarget), @@ -1118,8 +1123,6 @@ pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire * const Owner, /*{{{*/ /*}}}*/ pkgAcqMetaClearSig::~pkgAcqMetaClearSig() /*{{{*/ { - if (MetaIndexParser != NULL) - delete MetaIndexParser; if (LastMetaIndexParser != NULL) delete LastMetaIndexParser; } @@ -1218,25 +1221,28 @@ void pkgAcqMetaClearSig::Failed(string const &Message,pkgAcquire::MethodConfig c // open the last Release if we have it if (TransactionManager->IMSHit == false) { - TransactionManager->LastMetaIndexParser = new indexRecords; - _error->PushToStack(); - if (RealFileExists(FinalInRelease)) - TransactionManager->LastMetaIndexParser->Load(FinalInRelease); - else - TransactionManager->LastMetaIndexParser->Load(FinalRelease); - // its unlikely to happen, but if what we have is bad ignore it - if (_error->PendingError()) + TransactionManager->LastMetaIndexParser = TransactionManager->MetaIndexParser->UnloadedClone(); + if (TransactionManager->LastMetaIndexParser != NULL) { - delete TransactionManager->LastMetaIndexParser; - TransactionManager->LastMetaIndexParser = NULL; + _error->PushToStack(); + if (RealFileExists(FinalInRelease)) + TransactionManager->LastMetaIndexParser->Load(FinalInRelease, NULL); + else + TransactionManager->LastMetaIndexParser->Load(FinalRelease, NULL); + // its unlikely to happen, but if what we have is bad ignore it + if (_error->PendingError()) + { + delete TransactionManager->LastMetaIndexParser; + TransactionManager->LastMetaIndexParser = NULL; + } + _error->RevertToStack(); } - _error->RevertToStack(); } } // we parse the indexes here because at this point the user wanted // a repository that may potentially harm him - if (TransactionManager->MetaIndexParser->Load(PartialRelease) == false || VerifyVendor(Message) == false) + if (TransactionManager->MetaIndexParser->Load(PartialRelease, &ErrorText) == false || VerifyVendor(Message) == false) /* expired Release files are still a problem you need extra force for */; else QueueIndexes(true); @@ -1303,8 +1309,6 @@ void pkgAcqMetaIndex::Failed(string const &Message, { // ensure old Release files are removed TransactionManager->TransactionStageRemoval(this, GetFinalFilename()); - delete TransactionManager->MetaIndexParser; - TransactionManager->MetaIndexParser = NULL; // queue without any kind of hashsum support QueueIndexes(false); @@ -1453,25 +1457,28 @@ void pkgAcqMetaSig::Failed(string const &Message,pkgAcquire::MethodConfig const // open the last Release if we have it if (TransactionManager->IMSHit == false) { - TransactionManager->LastMetaIndexParser = new indexRecords; - _error->PushToStack(); - if (RealFileExists(FinalInRelease)) - TransactionManager->LastMetaIndexParser->Load(FinalInRelease); - else - TransactionManager->LastMetaIndexParser->Load(FinalRelease); - // its unlikely to happen, but if what we have is bad ignore it - if (_error->PendingError()) + TransactionManager->LastMetaIndexParser = TransactionManager->MetaIndexParser->UnloadedClone(); + if (TransactionManager->LastMetaIndexParser != NULL) { - delete TransactionManager->LastMetaIndexParser; - TransactionManager->LastMetaIndexParser = NULL; + _error->PushToStack(); + if (RealFileExists(FinalInRelease)) + TransactionManager->LastMetaIndexParser->Load(FinalInRelease, NULL); + else + TransactionManager->LastMetaIndexParser->Load(FinalRelease, NULL); + // its unlikely to happen, but if what we have is bad ignore it + if (_error->PendingError()) + { + delete TransactionManager->LastMetaIndexParser; + TransactionManager->LastMetaIndexParser = NULL; + } + _error->RevertToStack(); } - _error->RevertToStack(); } } // we parse the indexes here because at this point the user wanted // a repository that may potentially harm him - if (TransactionManager->MetaIndexParser->Load(MetaIndex->DestFile) == false || MetaIndex->VerifyVendor(Message) == false) + if (TransactionManager->MetaIndexParser->Load(MetaIndex->DestFile, &ErrorText) == false || MetaIndex->VerifyVendor(Message) == false) /* expired Release files are still a problem you need extra force for */; else MetaIndex->QueueIndexes(true); diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index 4d235dce2..10ece76c9 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -34,7 +34,6 @@ #include <apt-pkg/vendor.h> #include <apt-pkg/sourcelist.h> #include <apt-pkg/pkgrecords.h> -#include <apt-pkg/indexrecords.h> #endif /** \addtogroup acquire @@ -43,11 +42,11 @@ * \file acquire-item.h */ -class indexRecords; class pkgRecords; class pkgSourceList; class pkgAcqMetaClearSig; class pkgAcqIndexMergeDiffs; +class metaIndex; class pkgAcquire::Item : public WeakPointable /*{{{*/ /** \brief Represents the process by which a pkgAcquire object should @@ -559,8 +558,8 @@ class APT_HIDDEN pkgAcqMetaClearSig : public pkgAcqMetaIndex public: /** \brief A package-system-specific parser for the meta-index file. */ - indexRecords *MetaIndexParser; - indexRecords *LastMetaIndexParser; + metaIndex *MetaIndexParser; + metaIndex *LastMetaIndexParser; virtual void Failed(std::string const &Message,pkgAcquire::MethodConfig const * const Cnf); virtual std::string Custom600Headers() const; @@ -573,7 +572,7 @@ class APT_HIDDEN pkgAcqMetaClearSig : public pkgAcqMetaIndex IndexTarget const &DetachedDataTarget, IndexTarget const &DetachedSigTarget, std::vector<IndexTarget> const &IndexTargets, - indexRecords * const MetaIndexParser); + metaIndex * const MetaIndexParser); virtual ~pkgAcqMetaClearSig(); }; /*}}}*/ diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 1f725ba05..f0b859eb4 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -8,7 +8,6 @@ #include <apt-pkg/acquire-item.h> #include <apt-pkg/configuration.h> #include <apt-pkg/aptconfiguration.h> -#include <apt-pkg/indexrecords.h> #include <apt-pkg/sourcelist.h> #include <apt-pkg/hashes.h> #include <apt-pkg/metaindex.h> @@ -45,10 +44,7 @@ class APT_HIDDEN debReleaseIndexPrivate /*{{{*/ std::vector<debSectionEntry> DebEntries; std::vector<debSectionEntry> DebSrcEntries; - debReleaseIndex::TriState Trusted; - - debReleaseIndexPrivate() : Trusted(debReleaseIndex::TRI_UNSET) {} - debReleaseIndexPrivate(bool const pTrusted) : Trusted(pTrusted ? debReleaseIndex::TRI_YES : debReleaseIndex::TRI_NO) {} + debReleaseIndexPrivate() {} }; /*}}}*/ // ReleaseIndex::MetaIndex* - display helpers /*{{{*/ @@ -92,27 +88,15 @@ std::string debReleaseIndex::MetaIndexURI(const char *Type) const return Res; } /*}}}*/ -std::string debReleaseIndex::LocalFileName() const /*{{{*/ -{ - // 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 ""; -} - /*}}}*/ // ReleaseIndex Con- and Destructors /*{{{*/ debReleaseIndex::debReleaseIndex(std::string const &URI, std::string const &Dist) : metaIndex(URI, Dist, "deb"), d(new debReleaseIndexPrivate()) {} -debReleaseIndex::debReleaseIndex(std::string const &URI, std::string const &Dist, bool const Trusted) : - metaIndex(URI, Dist, "deb"), d(new debReleaseIndexPrivate(Trusted)) -{} +debReleaseIndex::debReleaseIndex(std::string const &URI, std::string const &Dist, bool const pTrusted) : + metaIndex(URI, Dist, "deb"), d(new debReleaseIndexPrivate()) +{ + Trusted = pTrusted ? TRI_YES : TRI_NO; +} debReleaseIndex::~debReleaseIndex() { if (d != NULL) delete d; @@ -227,22 +211,197 @@ void debReleaseIndex::AddComponent(bool const isSrc, std::string const &Name,/*{ } /*}}}*/ +bool debReleaseIndex::Load(std::string const &Filename, std::string * const ErrorText)/*{{{*/ +{ + LoadedSuccessfully = TRI_NO; + FileFd Fd; + if (OpenMaybeClearSignedFile(Filename, Fd) == false) + return false; + + pkgTagFile TagFile(&Fd, Fd.Size()); + if (_error->PendingError() == true) + { + if (ErrorText != NULL) + strprintf(*ErrorText, _("Unable to parse Release file %s"),Filename.c_str()); + return false; + } + + pkgTagSection Section; + const char *Start, *End; + if (TagFile.Step(Section) == false) + { + if (ErrorText != NULL) + strprintf(*ErrorText, _("No sections in Release file %s"), Filename.c_str()); + return false; + } + // FIXME: find better tag name + SupportsAcquireByHash = Section.FindB("Acquire-By-Hash", false); + + Suite = Section.FindS("Suite"); + Codename = Section.FindS("Codename"); + + bool FoundHashSum = false; + for (int i=0;HashString::SupportedHashes()[i] != NULL; i++) + { + if (!Section.Find(HashString::SupportedHashes()[i], Start, End)) + continue; + + std::string Name; + std::string Hash; + unsigned long long Size; + while (Start < End) + { + if (!parseSumData(Start, End, Name, Hash, Size)) + return false; + + if (Entries.find(Name) == Entries.end()) + { + metaIndex::checkSum *Sum = new metaIndex::checkSum; + Sum->MetaKeyFilename = Name; + Sum->Size = Size; + Sum->Hashes.FileSize(Size); + APT_IGNORE_DEPRECATED(Sum->Hash = HashString(HashString::SupportedHashes()[i],Hash);) + Entries[Name] = Sum; + } + Entries[Name]->Hashes.push_back(HashString(HashString::SupportedHashes()[i],Hash)); + FoundHashSum = true; + } + } + + if(FoundHashSum == false) + { + if (ErrorText != NULL) + strprintf(*ErrorText, _("No Hash entry in Release file %s"), Filename.c_str()); + return false; + } + + std::string const StrDate = Section.FindS("Date"); + if (RFC1123StrToTime(StrDate.c_str(), Date) == false) + { + if (ErrorText != NULL) + strprintf(*ErrorText, _("Invalid 'Date' entry in Release file %s"), Filename.c_str()); + return false; + } -bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const/*{{{*/ + std::string const Label = Section.FindS("Label"); + std::string const StrValidUntil = Section.FindS("Valid-Until"); + + // if we have a Valid-Until header in the Release file, use it as default + if (StrValidUntil.empty() == false) + { + if(RFC1123StrToTime(StrValidUntil.c_str(), ValidUntil) == false) + { + if (ErrorText != NULL) + strprintf(*ErrorText, _("Invalid 'Valid-Until' entry in Release file %s"), Filename.c_str()); + return false; + } + } + // get the user settings for this archive and use what expires earlier + int MaxAge = _config->FindI("Acquire::Max-ValidTime", 0); + if (Label.empty() == false) + MaxAge = _config->FindI(("Acquire::Max-ValidTime::" + Label).c_str(), MaxAge); + int MinAge = _config->FindI("Acquire::Min-ValidTime", 0); + if (Label.empty() == false) + MinAge = _config->FindI(("Acquire::Min-ValidTime::" + Label).c_str(), MinAge); + + LoadedSuccessfully = TRI_YES; + if(MaxAge == 0 && + (MinAge == 0 || ValidUntil == 0)) // No user settings, use the one from the Release file + return true; + + if (MinAge != 0 && ValidUntil != 0) { + time_t const min_date = Date + MinAge; + if (ValidUntil < min_date) + ValidUntil = min_date; + } + if (MaxAge != 0) { + time_t const max_date = Date + MaxAge; + if (ValidUntil == 0 || ValidUntil > max_date) + ValidUntil = max_date; + } + + return true; +} + /*}}}*/ +metaIndex * debReleaseIndex::UnloadedClone() const /*{{{*/ +{ + if (Trusted == TRI_NO) + return new debReleaseIndex(URI, Dist, false); + else if (Trusted == TRI_YES) + return new debReleaseIndex(URI, Dist, true); + else + return new debReleaseIndex(URI, Dist); +} + /*}}}*/ +bool debReleaseIndex::parseSumData(const char *&Start, const char *End, /*{{{*/ + std::string &Name, std::string &Hash, unsigned long long &Size) { - indexRecords * const iR = new indexRecords(Dist); - if (d->Trusted == TRI_YES) - iR->SetTrusted(true); - else if (d->Trusted == TRI_NO) - iR->SetTrusted(false); + Name = ""; + Hash = ""; + Size = 0; + /* Skip over the first blank */ + while ((*Start == '\t' || *Start == ' ' || *Start == '\n' || *Start == '\r') + && Start < End) + Start++; + if (Start >= End) + return false; - // special case for --print-uris + /* Move EntryEnd to the end of the first entry (the hash) */ + const char *EntryEnd = Start; + while ((*EntryEnd != '\t' && *EntryEnd != ' ') + && EntryEnd < End) + EntryEnd++; + if (EntryEnd == End) + return false; + + Hash.append(Start, EntryEnd-Start); + + /* Skip over intermediate blanks */ + Start = EntryEnd; + while (*Start == '\t' || *Start == ' ') + Start++; + if (Start >= End) + return false; + + EntryEnd = Start; + /* Find the end of the second entry (the size) */ + while ((*EntryEnd != '\t' && *EntryEnd != ' ' ) + && EntryEnd < End) + EntryEnd++; + if (EntryEnd == End) + return false; + + Size = strtoull (Start, NULL, 10); + + /* Skip over intermediate blanks */ + Start = EntryEnd; + while (*Start == '\t' || *Start == ' ') + Start++; + if (Start >= End) + return false; + + EntryEnd = Start; + /* Find the end of the third entry (the filename) */ + while ((*EntryEnd != '\t' && *EntryEnd != ' ' && + *EntryEnd != '\n' && *EntryEnd != '\r') + && EntryEnd < End) + EntryEnd++; + + Name.append(Start, EntryEnd-Start); + Start = EntryEnd; //prepare for the next round + return true; +} + /*}}}*/ + +bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll)/*{{{*/ +{ std::vector<IndexTarget> const targets = GetIndexTargets(); #define APT_TARGET(X) IndexTarget("", X, MetaIndexInfo(X), MetaIndexURI(X), false, std::map<std::string,std::string>()) pkgAcqMetaClearSig * const TransactionManager = new pkgAcqMetaClearSig(Owner, APT_TARGET("InRelease"), APT_TARGET("Release"), APT_TARGET("Release.gpg"), - targets, iR); + targets, this); #undef APT_TARGET + // special case for --print-uris if (GetAll) { for (std::vector<IndexTarget>::const_iterator Target = targets.begin(); Target != targets.end(); ++Target) @@ -253,20 +412,20 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const/*{ } /*}}}*/ // ReleaseIndex::IsTrusted /*{{{*/ -bool debReleaseIndex::SetTrusted(TriState const Trusted) +bool debReleaseIndex::SetTrusted(TriState const pTrusted) { - if (d->Trusted == TRI_UNSET) - d->Trusted = Trusted; - else if (d->Trusted != Trusted) + if (Trusted == TRI_UNSET) + Trusted = pTrusted; + else if (Trusted != pTrusted) // TRANSLATOR: The first is an option name from sources.list manpage, the other two URI and Suite return _error->Error(_("Conflicting values set for option %s concerning source %s %s"), "Trusted", URI.c_str(), Dist.c_str()); return true; } bool debReleaseIndex::IsTrusted() const { - if (d->Trusted == TRI_YES) + if (Trusted == TRI_YES) return true; - else if (d->Trusted == TRI_NO) + else if (Trusted == TRI_NO) return false; diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h index a6db4e287..19fe6806c 100644 --- a/apt-pkg/deb/debmetaindex.h +++ b/apt-pkg/deb/debmetaindex.h @@ -27,6 +27,8 @@ class APT_HIDDEN debReleaseIndex : public metaIndex { debReleaseIndexPrivate * const d; + APT_HIDDEN bool parseSumData(const char *&Start, const char *End, std::string &Name, + std::string &Hash, unsigned long long &Size); public: APT_HIDDEN std::string MetaIndexInfo(const char *Type) const; @@ -38,20 +40,18 @@ class APT_HIDDEN debReleaseIndex : public metaIndex virtual ~debReleaseIndex(); virtual std::string ArchiveURI(std::string const &File) const {return URI + File;}; - virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const; + virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false); virtual std::vector<IndexTarget> GetIndexTargets() const; virtual std::string Describe() const; virtual pkgCache::RlsFileIterator FindInCache(pkgCache &Cache, bool const ModifyCheck) const; virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; - virtual std::string LocalFileName() const; + virtual bool Load(std::string const &Filename, std::string * const ErrorText); + virtual metaIndex * UnloadedClone() const; virtual std::vector <pkgIndexFile *> *GetIndexFiles(); - enum APT_HIDDEN TriState { - TRI_YES, TRI_DONTCARE, TRI_NO, TRI_UNSET - }; bool SetTrusted(TriState const Trusted); virtual bool IsTrusted() const; @@ -64,15 +64,15 @@ class APT_HIDDEN debReleaseIndex : public metaIndex class APT_HIDDEN debDebFileMetaIndex : public metaIndex { - private: - void * const d; +private: + void * const d; std::string DebFile; debDebPkgFileIndex *DebIndex; - public: +public: virtual std::string ArchiveURI(std::string const& /*File*/) const { return DebFile; } - virtual bool GetIndexes(pkgAcquire* /*Owner*/, const bool& /*GetAll=false*/) const { + virtual bool GetIndexes(pkgAcquire* /*Owner*/, const bool& /*GetAll=false*/) { return true; } virtual std::vector<IndexTarget> GetIndexTargets() const { @@ -84,6 +84,17 @@ class APT_HIDDEN debDebFileMetaIndex : public metaIndex virtual bool IsTrusted() const { return true; } + virtual bool Load(std::string const &, std::string * const ErrorText) + { + LoadedSuccessfully = TRI_NO; + if (ErrorText != NULL) + strprintf(*ErrorText, "Unparseable metaindex as it represents the standalone deb file %s", DebFile.c_str()); + return false; + } + virtual metaIndex * UnloadedClone() const + { + return NULL; + } debDebFileMetaIndex(std::string const &DebFile); virtual ~debDebFileMetaIndex(); diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc index 6d210e65b..f9adb2fb8 100644 --- a/apt-pkg/indexcopy.cc +++ b/apt-pkg/indexcopy.cc @@ -19,10 +19,11 @@ #include <apt-pkg/aptconfiguration.h> #include <apt-pkg/configuration.h> #include <apt-pkg/tagfile.h> -#include <apt-pkg/indexrecords.h> +#include <apt-pkg/metaindex.h> #include <apt-pkg/cdrom.h> #include <apt-pkg/gpgv.h> #include <apt-pkg/hashes.h> +#include <apt-pkg/debmetaindex.h> #include <iostream> #include <sstream> @@ -476,9 +477,9 @@ bool SourceCopy::RewriteEntry(FileFd &Target, std::string const &File) } /*}}}*/ // SigVerify::Verify - Verify a files md5sum against its metaindex /*{{{*/ -bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex) +bool SigVerify::Verify(string prefix, string file, metaIndex *MetaIndex) { - const indexRecords::checkSum *Record = MetaIndex->Lookup(file); + const metaIndex::checkSum *Record = MetaIndex->Lookup(file); bool const Debug = _config->FindB("Debug::aptcdrom",false); // we skip non-existing files in the verifcation of the Release file @@ -545,11 +546,11 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList, // Read all Release files for (vector<string>::iterator I = SigList.begin(); I != SigList.end(); ++I) - { + { if(Debug) cout << "Signature verify for: " << *I << endl; - indexRecords *MetaIndex = new indexRecords; + metaIndex *MetaIndex = new debReleaseIndex("",""); string prefix = *I; string const releasegpg = *I+"Release.gpg"; @@ -591,12 +592,13 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList, } // Open the Release file and add it to the MetaIndex - if(!MetaIndex->Load(release)) + std::string ErrorText; + if(MetaIndex->Load(release, &ErrorText) == false) { - _error->Error("%s",MetaIndex->ErrorText.c_str()); + _error->Error("%s", ErrorText.c_str()); return false; } - + // go over the Indexfiles and see if they verify // if so, remove them from our copy of the lists vector<string> keys = MetaIndex->MetaKeys(); diff --git a/apt-pkg/indexcopy.h b/apt-pkg/indexcopy.h index 4f4c47169..6eecad028 100644 --- a/apt-pkg/indexcopy.h +++ b/apt-pkg/indexcopy.h @@ -25,9 +25,9 @@ using std::vector; #endif class pkgTagSection; -class indexRecords; class pkgCdromStatus; class FileFd; +class metaIndex; class IndexCopy /*{{{*/ { @@ -106,7 +106,7 @@ class SigVerify /*{{{*/ /** \brief dpointer placeholder (for later in case we need it) */ void * const d; - APT_HIDDEN bool Verify(std::string prefix,std::string file, indexRecords *records); + APT_HIDDEN bool Verify(std::string prefix,std::string file, metaIndex *records); APT_HIDDEN bool CopyMetaIndex(std::string CDROM, std::string CDName, std::string prefix, std::string file); diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc deleted file mode 100644 index 03ba59460..000000000 --- a/apt-pkg/indexrecords.cc +++ /dev/null @@ -1,284 +0,0 @@ -// -*- mode: cpp; mode: fold -*- -// Description /*{{{*/ -// $Id: indexrecords.cc,v 1.1.2.4 2003/12/30 02:11:43 mdz Exp $ - /*}}}*/ -// Include Files /*{{{*/ -#include<config.h> - -#include <apt-pkg/indexrecords.h> -#include <apt-pkg/tagfile.h> -#include <apt-pkg/error.h> -#include <apt-pkg/strutl.h> -#include <apt-pkg/configuration.h> -#include <apt-pkg/fileutl.h> -#include <apt-pkg/hashes.h> -#include <apt-pkg/gpgv.h> - -#include <stdlib.h> -#include <time.h> -#include <clocale> -#include <map> -#include <string> -#include <utility> -#include <vector> - -#include <apti18n.h> - /*}}}*/ - -using std::string; - -APT_PURE string indexRecords::GetDist() const -{ - return this->Dist; -} - -APT_PURE string indexRecords::GetSuite() const -{ - return this->Suite; -} - -APT_PURE bool indexRecords::GetSupportsAcquireByHash() const -{ - return this->SupportsAcquireByHash; -} - -APT_PURE bool indexRecords::CheckDist(string const &MaybeDist) const -{ - return (this->Dist == MaybeDist - || this->Suite == MaybeDist); -} - -APT_PURE string indexRecords::GetExpectedDist() const -{ - return this->ExpectedDist; -} - -APT_PURE time_t indexRecords::GetValidUntil() const -{ - return this->ValidUntil; -} - -APT_PURE time_t indexRecords::GetDate() const -{ - return this->Date; -} - -APT_PURE indexRecords::checkSum *indexRecords::Lookup(string const &MetaKey) -{ - std::map<std::string, indexRecords::checkSum* >::const_iterator sum = Entries.find(MetaKey); - if (sum == Entries.end()) - return NULL; - return sum->second; -} - -APT_PURE bool indexRecords::Exists(string const &MetaKey) const -{ - return Entries.find(MetaKey) != Entries.end(); -} - -bool indexRecords::Load(string const &Filename) /*{{{*/ -{ - FileFd Fd; - if (OpenMaybeClearSignedFile(Filename, Fd) == false) - return false; - - pkgTagFile TagFile(&Fd, Fd.Size()); - if (_error->PendingError() == true) - { - strprintf(ErrorText, _("Unable to parse Release file %s"),Filename.c_str()); - return false; - } - - pkgTagSection Section; - const char *Start, *End; - if (TagFile.Step(Section) == false) - { - strprintf(ErrorText, _("No sections in Release file %s"), Filename.c_str()); - return false; - } - // FIXME: find better tag name - SupportsAcquireByHash = Section.FindB("Acquire-By-Hash", false); - - Suite = Section.FindS("Suite"); - Dist = Section.FindS("Codename"); - - bool FoundHashSum = false; - for (int i=0;HashString::SupportedHashes()[i] != NULL; i++) - { - if (!Section.Find(HashString::SupportedHashes()[i], Start, End)) - continue; - - string Name; - string Hash; - unsigned long long Size; - while (Start < End) - { - if (!parseSumData(Start, End, Name, Hash, Size)) - return false; - - if (Entries.find(Name) == Entries.end()) - { - indexRecords::checkSum *Sum = new indexRecords::checkSum; - Sum->MetaKeyFilename = Name; - Sum->Size = Size; - Sum->Hashes.FileSize(Size); - APT_IGNORE_DEPRECATED(Sum->Hash = HashString(HashString::SupportedHashes()[i],Hash);) - Entries[Name] = Sum; - } - Entries[Name]->Hashes.push_back(HashString(HashString::SupportedHashes()[i],Hash)); - FoundHashSum = true; - } - } - - if(FoundHashSum == false) - { - strprintf(ErrorText, _("No Hash entry in Release file %s"), Filename.c_str()); - return false; - } - - string const StrDate = Section.FindS("Date"); - if (RFC1123StrToTime(StrDate.c_str(), Date) == false) - { - strprintf(ErrorText, _("Invalid 'Date' entry in Release file %s"), Filename.c_str()); - return false; - } - - string const Label = Section.FindS("Label"); - string const StrValidUntil = Section.FindS("Valid-Until"); - - // if we have a Valid-Until header in the Release file, use it as default - if (StrValidUntil.empty() == false) - { - if(RFC1123StrToTime(StrValidUntil.c_str(), ValidUntil) == false) - { - strprintf(ErrorText, _("Invalid 'Valid-Until' entry in Release file %s"), Filename.c_str()); - return false; - } - } - // get the user settings for this archive and use what expires earlier - int MaxAge = _config->FindI("Acquire::Max-ValidTime", 0); - if (Label.empty() == false) - MaxAge = _config->FindI(("Acquire::Max-ValidTime::" + Label).c_str(), MaxAge); - int MinAge = _config->FindI("Acquire::Min-ValidTime", 0); - if (Label.empty() == false) - MinAge = _config->FindI(("Acquire::Min-ValidTime::" + Label).c_str(), MinAge); - - if(MaxAge == 0 && - (MinAge == 0 || ValidUntil == 0)) // No user settings, use the one from the Release file - return true; - - if (MinAge != 0 && ValidUntil != 0) { - time_t const min_date = Date + MinAge; - if (ValidUntil < min_date) - ValidUntil = min_date; - } - if (MaxAge != 0) { - time_t const max_date = Date + MaxAge; - if (ValidUntil == 0 || ValidUntil > max_date) - ValidUntil = max_date; - } - - return true; -} - /*}}}*/ -std::vector<string> indexRecords::MetaKeys() /*{{{*/ -{ - std::vector<std::string> keys; - std::map<string,checkSum *>::iterator I = Entries.begin(); - while(I != Entries.end()) { - keys.push_back((*I).first); - ++I; - } - return keys; -} - /*}}}*/ -bool indexRecords::parseSumData(const char *&Start, const char *End, /*{{{*/ - string &Name, string &Hash, unsigned long long &Size) -{ - Name = ""; - Hash = ""; - Size = 0; - /* Skip over the first blank */ - while ((*Start == '\t' || *Start == ' ' || *Start == '\n' || *Start == '\r') - && Start < End) - Start++; - if (Start >= End) - return false; - - /* Move EntryEnd to the end of the first entry (the hash) */ - const char *EntryEnd = Start; - while ((*EntryEnd != '\t' && *EntryEnd != ' ') - && EntryEnd < End) - EntryEnd++; - if (EntryEnd == End) - return false; - - Hash.append(Start, EntryEnd-Start); - - /* Skip over intermediate blanks */ - Start = EntryEnd; - while (*Start == '\t' || *Start == ' ') - Start++; - if (Start >= End) - return false; - - EntryEnd = Start; - /* Find the end of the second entry (the size) */ - while ((*EntryEnd != '\t' && *EntryEnd != ' ' ) - && EntryEnd < End) - EntryEnd++; - if (EntryEnd == End) - return false; - - Size = strtoull (Start, NULL, 10); - - /* Skip over intermediate blanks */ - Start = EntryEnd; - while (*Start == '\t' || *Start == ' ') - Start++; - if (Start >= End) - return false; - - EntryEnd = Start; - /* Find the end of the third entry (the filename) */ - while ((*EntryEnd != '\t' && *EntryEnd != ' ' && - *EntryEnd != '\n' && *EntryEnd != '\r') - && EntryEnd < End) - EntryEnd++; - - Name.append(Start, EntryEnd-Start); - Start = EntryEnd; //prepare for the next round - return true; -} - /*}}}*/ - -APT_PURE bool indexRecords::IsAlwaysTrusted() const -{ - if (Trusted == ALWAYS_TRUSTED) - return true; - return false; -} -APT_PURE bool indexRecords::IsNeverTrusted() const -{ - if (Trusted == NEVER_TRUSTED) - return true; - return false; -} -void indexRecords::SetTrusted(bool const Trusted) -{ - if (Trusted == true) - this->Trusted = ALWAYS_TRUSTED; - else - this->Trusted = NEVER_TRUSTED; -} - -indexRecords::indexRecords(const string &ExpectedDist) : - Trusted(CHECK_TRUST), d(NULL), ExpectedDist(ExpectedDist), ValidUntil(0), - SupportsAcquireByHash(false) -{ -} - -indexRecords::~indexRecords() { - for (std::map<std::string, checkSum*>::const_iterator S = Entries.begin(); S != Entries.end(); ++S) - delete S->second; -} diff --git a/apt-pkg/indexrecords.h b/apt-pkg/indexrecords.h deleted file mode 100644 index 683247e42..000000000 --- a/apt-pkg/indexrecords.h +++ /dev/null @@ -1,88 +0,0 @@ -// -*- mode: cpp; mode: fold -*- -#ifndef PKGLIB_INDEXRECORDS_H -#define PKGLIB_INDEXRECORDS_H - -#include <apt-pkg/hashes.h> - -#include <map> -#include <vector> -#include <ctime> -#include <string> - -#ifndef APT_8_CLEANER_HEADERS -#include <apt-pkg/fileutl.h> -#endif -#ifndef APT_10_CLEANER_HEADERS -#include <apt-pkg/pkgcache.h> -#endif - -class indexRecords -{ - APT_HIDDEN bool parseSumData(const char *&Start, const char *End, std::string &Name, - std::string &Hash, unsigned long long &Size); - public: - struct checkSum; - std::string ErrorText; - - private: - enum APT_HIDDEN { ALWAYS_TRUSTED, NEVER_TRUSTED, CHECK_TRUST } Trusted; - // dpointer (for later) - void * const d; - - protected: - std::string Dist; - std::string Suite; - std::string ExpectedDist; - time_t Date; - time_t ValidUntil; - bool SupportsAcquireByHash; - - std::map<std::string,checkSum *> Entries; - - public: - explicit indexRecords(const std::string &ExpectedDist = ""); - - // Lookup function - virtual checkSum *Lookup(std::string const &MetaKey); - /** \brief tests if a checksum for this file is available */ - bool Exists(std::string const &MetaKey) const; - std::vector<std::string> MetaKeys(); - - virtual bool Load(std::string const &Filename); - virtual bool CheckDist(std::string const &MaybeDist) const; - - std::string GetDist() const; - std::string GetSuite() const; - bool GetSupportsAcquireByHash() const; - time_t GetValidUntil() const; - time_t GetDate() const; - std::string GetExpectedDist() const; - - /** \brief check if source is marked as always trusted */ - bool IsAlwaysTrusted() const; - /** \brief check if source is marked as never trusted */ - bool IsNeverTrusted() const; - - /** \brief sets an explicit trust value - * - * \b true means that the source should always be considered trusted, - * while \b false marks a source as always untrusted, even if we have - * a valid signature and everything. - */ - void SetTrusted(bool const Trusted); - - virtual ~indexRecords(); -}; - -APT_IGNORE_DEPRECATED_PUSH -struct indexRecords::checkSum -{ - std::string MetaKeyFilename; - HashStringList Hashes; - unsigned long long Size; - - APT_DEPRECATED HashString Hash; -}; -APT_IGNORE_DEPRECATED_POP - -#endif diff --git a/apt-pkg/metaindex.cc b/apt-pkg/metaindex.cc index 0c88ee9cd..8bd13bb18 100644 --- a/apt-pkg/metaindex.cc +++ b/apt-pkg/metaindex.cc @@ -9,20 +9,6 @@ #include <vector> /*}}}*/ -#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) -std::string metaIndex::LocalFileName() const { return ""; } -#else -#include <apt-pkg/debmetaindex.h> -std::string metaIndex::LocalFileName() const -{ - debReleaseIndex const * deb = dynamic_cast<debReleaseIndex const*>(this); - if (deb != NULL) - return deb->LocalFileName(); - - return ""; -} -#endif - std::string metaIndex::Describe() const { return "Release"; @@ -38,10 +24,11 @@ bool metaIndex::Merge(pkgCacheGenerator &Gen,OpProgress *) const return Gen.SelectReleaseFile("", ""); } - metaIndex::metaIndex(std::string const &URI, std::string const &Dist, char const * const Type) -: d(NULL), Indexes(NULL), Type(Type), URI(URI), Dist(Dist) +: d(NULL), Indexes(NULL), Type(Type), URI(URI), Dist(Dist), Trusted(TRI_UNSET), + LoadedSuccessfully(TRI_UNSET), + Date(0), ValidUntil(0), SupportsAcquireByHash(false) { /* nothing */ } @@ -55,3 +42,60 @@ metaIndex::~metaIndex() delete *I; delete Indexes; } + +// one line Getters for public fields /*{{{*/ +APT_PURE std::string metaIndex::GetURI() const { return URI; } +APT_PURE std::string metaIndex::GetDist() const { return Dist; } +APT_PURE const char* metaIndex::GetType() const { return Type; } +APT_PURE metaIndex::TriState metaIndex::GetTrusted() const { return Trusted; } +APT_PURE std::string metaIndex::GetCodename() const { return Codename; } +APT_PURE std::string metaIndex::GetSuite() const { return Suite; } +APT_PURE bool metaIndex::GetSupportsAcquireByHash() const { return SupportsAcquireByHash; } +APT_PURE time_t metaIndex::GetValidUntil() const { return ValidUntil; } +APT_PURE time_t metaIndex::GetDate() const { return this->Date; } +APT_PURE metaIndex::TriState metaIndex::GetLoadedSuccessfully() const { return LoadedSuccessfully; } + +APT_PURE bool metaIndex::CheckDist(string const &MaybeDist) const +{ + return (this->Codename == MaybeDist + || this->Suite == MaybeDist); +} +APT_PURE std::string metaIndex::GetExpectedDist() const +{ + // TODO: Used to be an explicit value set in the constructor + return ""; +} + /*}}}*/ +APT_PURE metaIndex::checkSum *metaIndex::Lookup(string const &MetaKey) const /*{{{*/ +{ + std::map<std::string, metaIndex::checkSum* >::const_iterator sum = Entries.find(MetaKey); + if (sum == Entries.end()) + return NULL; + return sum->second; +} + /*}}}*/ +APT_PURE bool metaIndex::Exists(string const &MetaKey) const /*{{{*/ +{ + return Entries.find(MetaKey) != Entries.end(); +} + /*}}}*/ +std::vector<std::string> metaIndex::MetaKeys() const /*{{{*/ +{ + std::vector<std::string> keys; + std::map<string,checkSum *>::const_iterator I = Entries.begin(); + while(I != Entries.end()) { + keys.push_back((*I).first); + ++I; + } + return keys; +} + /*}}}*/ +void metaIndex::swapLoad(metaIndex * const OldMetaIndex) /*{{{*/ +{ + std::swap(Entries, OldMetaIndex->Entries); + std::swap(Date, OldMetaIndex->Date); + std::swap(ValidUntil, OldMetaIndex->ValidUntil); + std::swap(SupportsAcquireByHash, OldMetaIndex->SupportsAcquireByHash); + std::swap(LoadedSuccessfully, OldMetaIndex->LoadedSuccessfully); +} + /*}}}*/ diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h index 9667e1c92..5be7397ae 100644 --- a/apt-pkg/metaindex.h +++ b/apt-pkg/metaindex.h @@ -28,35 +28,81 @@ class OpProgress; class metaIndex { +public: + APT_IGNORE_DEPRECATED_PUSH + struct checkSum + { + std::string MetaKeyFilename; + HashStringList Hashes; + unsigned long long Size; + + APT_DEPRECATED HashString Hash; + }; + APT_IGNORE_DEPRECATED_POP + + enum APT_HIDDEN TriState { + TRI_YES, TRI_DONTCARE, TRI_NO, TRI_UNSET + }; +private: void * const d; - protected: +protected: std::vector <pkgIndexFile *> *Indexes; + // parsed from the sources.list const char *Type; std::string URI; std::string Dist; + TriState Trusted; + TriState LoadedSuccessfully; - public: + // parsed from a file + std::string Suite; + std::string Codename; + time_t Date; + time_t ValidUntil; + bool SupportsAcquireByHash; + std::map<std::string, checkSum *> Entries; +public: // Various accessors - virtual std::string GetURI() const {return URI;} - virtual std::string GetDist() const {return Dist;} - virtual const char* GetType() const {return Type;} + std::string GetURI() const; + std::string GetDist() const; + const char* GetType() const; + TriState GetTrusted() const; - // interface to to query it - /** \return the path of the local file (or "" if its not available) */ - virtual std::string LocalFileName() const; + std::string GetCodename() const; + std::string GetSuite() const; + bool GetSupportsAcquireByHash() const; + time_t GetValidUntil() const; + time_t GetDate() const; + + std::string GetExpectedDist() const; + bool CheckDist(std::string const &MaybeDist) const; // Interface for acquire + virtual std::string Describe() const; virtual std::string ArchiveURI(std::string const& File) const = 0; - virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const = 0; + virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) = 0; virtual std::vector<IndexTarget> GetIndexTargets() const = 0; virtual std::vector<pkgIndexFile *> *GetIndexFiles() = 0; virtual bool IsTrusted() const = 0; + virtual bool Load(std::string const &Filename, std::string * const ErrorText) = 0; + /** @return a new metaIndex object based on this one, but without information from #Load */ + virtual metaIndex * UnloadedClone() const = 0; + // the given metaIndex is potentially invalid after this call and should be deleted + void swapLoad(metaIndex * const OldMetaIndex); - virtual std::string Describe() const; + // Lookup functions for parsed Hashes + checkSum *Lookup(std::string const &MetaKey) const; + /** \brief tests if a checksum for this file is available */ + bool Exists(std::string const &MetaKey) const; + std::vector<std::string> MetaKeys() const; + TriState GetLoadedSuccessfully() const; + + // Interfaces for pkgCacheGen virtual pkgCache::RlsFileIterator FindInCache(pkgCache &Cache, bool const ModifyCheck) const; virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; + metaIndex(std::string const &URI, std::string const &Dist, char const * const Type); virtual ~metaIndex(); diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 69f7ac043..0502f0e1d 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -103,6 +103,7 @@ bool pkgSourceList::Type::ParseStanza(vector<metaIndex *> &List, /*{{{*/ APT_PLUSMINUS("Targets", "target"); #undef APT_PLUSMINUS mapping.insert(std::make_pair("Trusted", "trusted")); + for (std::map<char const * const, char const * const>::const_iterator m = mapping.begin(); m != mapping.end(); ++m) if (Tags.Exists(m->first)) { |