Browse Source

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).
debian/1.8.y
David Kalnischkies 14 years ago
parent
commit
5dd4c8b811
  1. 25
      apt-pkg/aptconfiguration.cc
  2. 16
      apt-pkg/aptconfiguration.h
  3. 34
      apt-pkg/cdrom.cc
  4. 6
      apt-pkg/clean.cc
  5. 17
      apt-pkg/contrib/strutl.cc
  6. 1
      apt-pkg/contrib/strutl.h
  7. 15
      apt-pkg/deb/debindexfile.cc
  8. 4
      apt-pkg/deb/debindexfile.h
  9. 57
      apt-pkg/deb/deblistparser.cc
  10. 2
      apt-pkg/deb/deblistparser.h
  11. 292
      apt-pkg/deb/debmetaindex.cc
  12. 28
      apt-pkg/deb/debmetaindex.h
  13. 4
      apt-pkg/metaindex.h
  14. 8
      apt-pkg/pkgcache.cc
  15. 81
      apt-pkg/sourcelist.cc
  16. 8
      apt-pkg/sourcelist.h
  17. 8
      apt-pkg/versionmatch.cc
  18. 2
      apt-pkg/versionmatch.h

25
apt-pkg/aptconfiguration.cc

@ -11,6 +11,7 @@
#include <apt-pkg/fileutl.h>
#include <apt-pkg/aptconfiguration.h>
#include <apt-pkg/configuration.h>
#include <system.h>
#include <vector>
#include <string>
@ -223,4 +224,28 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
return codes;
}
/*}}}*/
// getArchitectures - Return Vector of prefered Architectures /*{{{*/
std::vector<std::string> const Configuration::getArchitectures(bool const &Cached) {
using std::string;
std::vector<string> static archs;
if (likely(Cached == true) && archs.empty() == false)
return archs;
string const arch = _config->Find("APT::Architecture");
archs = _config->FindVector("APT::Architectures");
if (archs.empty() == true ||
std::find(archs.begin(), archs.end(), arch) == archs.end())
archs.push_back(arch);
return archs;
}
/*}}}*/
// checkArchitecture - are we interested in the given Architecture? /*{{{*/
bool const Configuration::checkArchitecture(std::string const &Arch) {
if (Arch == "all")
return true;
std::vector<std::string> const archs = getArchitectures(true);
return (std::find(archs.begin(), archs.end(), Arch) != archs.end());
}
/*}}}*/
}

16
apt-pkg/aptconfiguration.h

@ -66,6 +66,22 @@ public: /*{{{*/
std::vector<std::string> static const getLanguages(bool const &All = false,
bool const &Cached = true, char const * const Locale = 0);
/** \brief Returns a vector of Architectures we support
*
* \param Cached saves the result so we need to calculated it only once
* this parameter should ony be used for testing purposes.
*
* \return a vector of Architectures in prefered order
*/
std::vector<std::string> static const getArchitectures(bool const &Cached = true);
/** \brief Are we interested in the given Architecture?
*
* \param Arch we want to check
* \return true if we are interested, false otherwise
*/
bool static const checkArchitecture(std::string const &Arch);
/*}}}*/
};
/*}}}*/

34
apt-pkg/cdrom.cc

@ -6,6 +6,8 @@
#include<apt-pkg/cdromutl.h>
#include<apt-pkg/strutl.h>
#include<apt-pkg/cdrom.h>
#include<apt-pkg/aptconfiguration.h>
#include<sstream>
#include<fstream>
#include<config.h>
@ -216,33 +218,23 @@ int pkgCdrom::Score(string Path)
/* Here we drop everything that is not this machines arch */
bool pkgCdrom::DropBinaryArch(vector<string> &List)
{
char S[300];
snprintf(S,sizeof(S),"/binary-%s/",
_config->Find("Apt::Architecture").c_str());
for (unsigned int I = 0; I < List.size(); I++)
{
const char *Str = List[I].c_str();
const char *Res;
if ((Res = strstr(Str,"/binary-")) == 0)
const char *Start, *End;
if ((Start = strstr(Str,"/binary-")) == 0)
continue;
// Weird, remove it.
if (strlen(Res) < strlen(S))
{
List.erase(List.begin() + I);
I--;
continue;
}
// See if it is our arch
if (stringcmp(Res,Res + strlen(S),S) == 0)
continue;
// Erase it
// Between Start and End is the architecture
Start += 8;
if ((End = strstr(Start,"/")) != 0 && Start != End &&
APT::Configuration::checkArchitecture(string(Start, --End)) == true)
continue; // okay, architecture is accepted
// not accepted -> Erase it
List.erase(List.begin() + I);
I--;
--I; // the next entry is at the same index after the erase
}
return true;

6
apt-pkg/clean.cc

@ -12,6 +12,7 @@
#include <apt-pkg/strutl.h>
#include <apt-pkg/error.h>
#include <apt-pkg/configuration.h>
#include <apt-pkg/aptconfiguration.h>
#include <apti18n.h>
@ -26,7 +27,6 @@
bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache)
{
bool CleanInstalled = _config->FindB("APT::Clean-Installed",true);
string MyArch = _config->Find("APT::Architecture");
DIR *D = opendir(Dir.c_str());
if (D == 0)
@ -75,9 +75,9 @@ bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache)
for (I = Start; *I != 0 && *I != '.' ;I++);
if (*I != '.')
continue;
string Arch = DeQuoteString(string(Start,I-Start));
string const Arch = DeQuoteString(string(Start,I-Start));
if (Arch != "all" && Arch != MyArch)
if (APT::Configuration::checkArchitecture(Arch) == false)
continue;
// Lookup the package

17
apt-pkg/contrib/strutl.cc

@ -983,6 +983,23 @@ bool TokSplitString(char Tok,char *Input,char **List,
return true;
}
/*}}}*/
// ExplodeString - Split a string up into a vector /*{{{*/
// ---------------------------------------------------------------------
/* This can be used to split a given string up into a vector, so the
propose is the same as in the method above and this one is a bit slower
also, but the advantage is that we an iteratable vector */
vector<string> ExplodeString(string const &haystack, char const &split) {
string::const_iterator start = haystack.begin();
string::const_iterator end = start;
vector<string> exploded;
do {
for (; end != haystack.end() && *end != split; ++end);
exploded.push_back(string(start, end));
start = end;
} while (end != haystack.end() && (++end) != haystack.end());
return exploded;
}
/*}}}*/
// RegexChoice - Simple regex list/list matcher /*{{{*/
// ---------------------------------------------------------------------
/* */

1
apt-pkg/contrib/strutl.h

@ -59,6 +59,7 @@ bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base = 0)
bool Hex2Num(const string &Str,unsigned char *Num,unsigned int Length);
bool TokSplitString(char Tok,char *Input,char **List,
unsigned long ListMax);
vector<string> ExplodeString(string const &haystack, char const &split=',');
void ioprintf(ostream &out,const char *format,...) APT_FORMAT2;
void strprintf(string &out,const char *format,...) APT_FORMAT2;
char *safe_snprintf(char *Buffer,char *End,const char *Format,...) APT_FORMAT3;

15
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());

4
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

57
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();
}

2
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

292
apt-pkg/deb/debmetaindex.cc

@ -8,9 +8,11 @@
#include <apt-pkg/aptconfiguration.h>
#include <apt-pkg/error.h>
#include <set>
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 debSectionEntry *>::const_iterator I = SectionEntries.begin();
I != SectionEntries.end(); I++)
delete *I;
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 <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const
{
vector <struct IndexTarget *>* IndexTargets = new vector <IndexTarget *>;
for (vector <const debSectionEntry *>::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 <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
vector <struct 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;
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);
}
}
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<std::string> const lang = APT::Configuration::getLanguages(true);
for (vector<const debSectionEntry *>::const_iterator I = SectionEntries.begin();
I != SectionEntries.end(); I++) {
if((*I)->IsSrc)
continue;
for (vector<string>::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<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++)
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++) {
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 <pkgIndexFile *> *debReleaseIndex::GetIndexFiles()
{
if (Indexes != NULL)
return Indexes;
Indexes = new vector <pkgIndexFile*>;
std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
for (vector<const debSectionEntry *>::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<string>::const_iterator l = lang.begin();
l != lang.end(); l++)
Indexes->push_back(new debTranslationsIndex(URI,Dist,(*I)->Section,(*l).c_str()));
}
}
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++)
Indexes->push_back(new debTranslationsIndex(URI,Dist,s->first,(*l).c_str()));
return Indexes;
}
return Indexes;
void debReleaseIndex::PushSectionEntry(vector<string> const &Archs, const debSectionEntry *Entry) {
for (vector<string>::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<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
{
protected:
bool CreateItemInternal(vector<metaIndex *> &List,string URI,
string Dist,string Section,
bool IsSrc) const
bool CreateItemInternal(vector<metaIndex *> &List, string const &URI,
string const &Dist, string const &Section,
bool const &IsSrc, map<string, string> const &Options) const
{
for (vector<metaIndex *>::const_iterator I = List.begin();
map<string, string>::const_iterator const arch = Options.find("arch");
vector<string> const Archs =
(arch != Options.end()) ? ExplodeString(arch->second) :
APT::Configuration::getArchitectures();
for (vector<metaIndex *>::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<metaIndex *> &List,string URI,
string Dist,string Section) const
bool CreateItem(vector<metaIndex *> &List, string const &URI,
string const &Dist, string const &Section,
std::map<string, string> 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<metaIndex *> &List,string URI,
string Dist,string Section) const
bool CreateItem(vector<metaIndex *> &List, string const &URI,
string const &Dist, string const &Section,
std::map<string, string> const &Options) const
{
return CreateItemInternal(List, URI, Dist, Section, true);
return CreateItemInternal(List, URI, Dist, Section, true, Options);
}
debSLTypeDebSrc()

28
apt-pkg/deb/debmetaindex.h

@ -5,40 +5,44 @@
#include <apt-pkg/metaindex.h>
#include <apt-pkg/sourcelist.h>
#include <map>
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 <const debSectionEntry *> SectionEntries;
std::map<string, vector<debSectionEntry const*> > 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 <struct IndexTarget *>* 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 <pkgIndexFile *> *GetIndexFiles();
virtual bool IsTrusted() const;
void PushSectionEntry(vector<string> const &Archs, const debSectionEntry *Entry);
void PushSectionEntry(string const &Arch, const debSectionEntry *Entry);
void PushSectionEntry(const debSectionEntry *Entry);
};

4
apt-pkg/metaindex.h

@ -33,8 +33,8 @@ class metaIndex
virtual const char* GetType() const {return Type;}
// Interface for acquire
virtual string ArchiveURI(string /*File*/) const = 0;
virtual bool GetIndexes(pkgAcquire *Owner, bool GetAll=false) const = 0;
virtual string ArchiveURI(string const& /*File*/) const = 0;
virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const = 0;
virtual vector<pkgIndexFile *> *GetIndexFiles() = 0;
virtual bool IsTrusted() const = 0;

8
apt-pkg/pkgcache.cc

@ -406,7 +406,7 @@ operator<<(ostream& out, pkgCache::PkgIterator Pkg)
string candidate = string(Pkg.CandVersion() == 0 ? "none" : Pkg.CandVersion());
string newest = string(Pkg.VersionList().end() ? "none" : Pkg.VersionList().VerStr());
out << Pkg.Name() << " < " << current;
out << Pkg.Name() << " [ " << Pkg.Arch() << " ] < " << current;
if (current != candidate)
out << " -> " << candidate;
if ( newest != "none" && candidate != newest)
@ -699,7 +699,9 @@ string pkgCache::VerIterator::RelStr()
else
Res += File.Site();
}
}
}
if (S->Arch != 0)
Res.append(" [").append(Arch()).append("]");
return Res;
}
/*}}}*/
@ -738,6 +740,8 @@ string pkgCache::PkgFileIterator::RelStr()
Res = Res + (Res.empty() == true?"l=":",l=") + Label();
if (Component() != 0)
Res = Res + (Res.empty() == true?"c=":",c=") + Component();
if (Architecture() != 0)
Res = Res + (Res.empty() == true?"b=":",b=") + Architecture();
return Res;
}
/*}}}*/

81
apt-pkg/sourcelist.cc

@ -79,13 +79,51 @@ bool pkgSourceList::Type::FixupURI(string &URI) const
Weird types may override this. */
bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
const char *Buffer,
unsigned long CurLine,
string File) const
unsigned long const &CurLine,
string const &File) const
{
for (;Buffer != 0 && isspace(*Buffer); ++Buffer); // Skip whitespaces
// Parse option field if it exists
// e.g.: [ option1=value1 option2=value2 ]
map<string, string> Options;
if (Buffer != 0 && Buffer[0] == '[')
{
++Buffer; // ignore the [
for (;Buffer != 0 && isspace(*Buffer); ++Buffer); // Skip whitespaces
while (*Buffer != ']')
{
// get one option, e.g. option1=value1
string option;
if (ParseQuoteWord(Buffer,option) == false)
return _error->Error(_("Malformed line %lu in source list %s ([option] unparseable)"),CurLine,File.c_str());
if (option.length() < 3)
return _error->Error(_("Malformed line %lu in source list %s ([option] too short)"),CurLine,File.c_str());
size_t const needle = option.find('=');
if (needle == string::npos)
return _error->Error(_("Malformed line %lu in source list %s ([%s] is not an assignment)"),CurLine,File.c_str(), option.c_str());
string const key = string(option, 0, needle);
string const value = string(option, needle + 1, option.length());
if (key.empty() == true)
return _error->Error(_("Malformed line %lu in source list %s ([%s] has no key)"),CurLine,File.c_str(), option.c_str());
if (value.empty() == true)
return _error->Error(_("Malformed line %lu in source list %s ([%s] key %s has no value)"),CurLine,File.c_str(),option.c_str(),key.c_str());
Options[key] = value;
}
++Buffer; // ignore the ]
for (;Buffer != 0 && isspace(*Buffer); ++Buffer); // Skip whitespaces
}
string URI;
string Dist;
string Section;
string Section;
if (ParseQuoteWord(Buffer,URI) == false)
return _error->Error(_("Malformed line %lu in source list %s (URI)"),CurLine,File.c_str());
if (ParseQuoteWord(Buffer,Dist) == false)
@ -100,7 +138,7 @@ bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
if (ParseQuoteWord(Buffer,Section) == true)
return _error->Error(_("Malformed line %lu in source list %s (absolute dist)"),CurLine,File.c_str());
Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture"));
return CreateItem(List,URI,Dist,Section);
return CreateItem(List, URI, Dist, Section, Options);
}
// Grab the rest of the dists
@ -109,7 +147,7 @@ bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
do
{
if (CreateItem(List,URI,Dist,Section) == false)
if (CreateItem(List, URI, Dist, Section, Options) == false)
return false;
}
while (ParseQuoteWord(Buffer,Section) == true);
@ -246,36 +284,7 @@ bool pkgSourceList::ReadAppend(string File)
if (Parse == 0)
return _error->Error(_("Type '%s' is not known on line %u in source list %s"),LineType.c_str(),CurLine,File.c_str());
// Vendor name specified
if (C[0] == '[')
{
string VendorID;
if (ParseQuoteWord(C,VendorID) == false)
return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
if (VendorID.length() < 2 || VendorID.end()[-1] != ']')
return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
VendorID = string(VendorID,1,VendorID.size()-2);
// for (vector<const Vendor *>::const_iterator iter = VendorList.begin();
// iter != VendorList.end(); iter++)
// {
// if ((*iter)->GetVendorID() == VendorID)
// {
// if (_config->FindB("Debug::sourceList", false))
// std::cerr << "Comparing VendorID \"" << VendorID << "\" with \"" << (*iter)->GetVendorID() << '"' << std::endl;
// Verifier = *iter;
// break;
// }
// }
// if (Verifier == 0)
// return _error->Error(_("Unknown vendor ID '%s' in line %u of source list %s"),
// VendorID.c_str(),CurLine,File.c_str());
}
if (Parse->ParseLine(SrcList,C,CurLine,File) == false)
if (Parse->ParseLine(SrcList, C, CurLine, File) == false)
return false;
}
return true;

8
apt-pkg/sourcelist.h

@ -29,6 +29,7 @@
#include <string>
#include <vector>
#include <map>
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/metaindex.h>
@ -57,9 +58,10 @@ class pkgSourceList
bool FixupURI(string &URI) const;
virtual bool ParseLine(vector<metaIndex *> &List,
const char *Buffer,
unsigned long CurLine,string File) const;
virtual bool CreateItem(vector<metaIndex *> &List,string URI,
string Dist,string Section) const = 0;
unsigned long const &CurLine,string const &File) const;
virtual bool CreateItem(vector<metaIndex *> &List,string const &URI,
string const &Dist,string const &Section,
std::map<string, string> const &Options) const = 0;
Type();
virtual ~Type() {};
};

8
apt-pkg/versionmatch.cc

@ -100,6 +100,8 @@ pkgVersionMatch::pkgVersionMatch(string Data,MatchType Type) : Type(Type)
RelLabel = Fragments[J]+2;
else if (stringcasecmp(Fragments[J],Fragments[J]+2,"c=") == 0)
RelComponent = Fragments[J]+2;
else if (stringcasecmp(Fragments[J],Fragments[J]+2,"b=") == 0)
RelArchitecture = Fragments[J]+2;
}
if (RelVerStr.end()[-1] == '*')
@ -178,7 +180,7 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
if (RelVerStr.empty() == true && RelOrigin.empty() == true &&
RelArchive.empty() == true && RelLabel.empty() == true &&
RelRelease.empty() == true && RelCodename.empty() == true &&
RelComponent.empty() == true)
RelComponent.empty() == true && RelArchitecture.empty() == true)
return false;
if (RelVerStr.empty() == false)
@ -211,6 +213,10 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
if (File->Component == 0 ||
stringcasecmp(RelComponent,File.Component()) != 0)
return false;
if (RelArchitecture.empty() == false)
if (File->Architecture == 0 ||
stringcasecmp(RelArchitecture,File.Architecture()) != 0)
return false;
return true;
}

2
apt-pkg/versionmatch.h

@ -23,6 +23,7 @@
Codename (n=) e.g. etch, lenny, squeeze, sid
Label (l=)
Component (c=)
Binary Architecture (b=)
If there are no equals signs in the string then it is scanned in short
form - if it starts with a number it is Version otherwise it is an
Archive or a Codename.
@ -55,6 +56,7 @@ class pkgVersionMatch
string RelArchive;
string RelLabel;
string RelComponent;
string RelArchitecture;
bool MatchAll;
// Origin Matching

Loading…
Cancel
Save