diff options
Diffstat (limited to 'apt-pkg')
-rw-r--r-- | apt-pkg/acquire-item.cc | 14 | ||||
-rw-r--r-- | apt-pkg/acquire-item.h | 5 | ||||
-rw-r--r-- | apt-pkg/aptconfiguration.cc | 237 | ||||
-rw-r--r-- | apt-pkg/aptconfiguration.h | 27 | ||||
-rw-r--r-- | apt-pkg/contrib/configuration.cc | 22 | ||||
-rw-r--r-- | apt-pkg/contrib/configuration.h | 37 | ||||
-rw-r--r-- | apt-pkg/contrib/mmap.cc | 127 | ||||
-rw-r--r-- | apt-pkg/contrib/mmap.h | 10 | ||||
-rw-r--r-- | apt-pkg/contrib/strutl.cc | 18 | ||||
-rw-r--r-- | apt-pkg/contrib/strutl.h | 1 | ||||
-rw-r--r-- | apt-pkg/deb/debindexfile.cc | 29 | ||||
-rw-r--r-- | apt-pkg/deb/debindexfile.h | 5 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.cc | 29 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.h | 3 | ||||
-rw-r--r-- | apt-pkg/deb/debmetaindex.cc | 20 | ||||
-rw-r--r-- | apt-pkg/deb/debrecords.cc | 12 | ||||
-rw-r--r-- | apt-pkg/deb/debsrcrecords.cc | 5 | ||||
-rw-r--r-- | apt-pkg/deb/debsrcrecords.h | 6 | ||||
-rw-r--r-- | apt-pkg/deb/dpkgpm.cc | 2 | ||||
-rw-r--r-- | apt-pkg/depcache.cc | 6 | ||||
-rw-r--r-- | apt-pkg/indexfile.cc | 75 | ||||
-rw-r--r-- | apt-pkg/init.h | 2 | ||||
-rw-r--r-- | apt-pkg/pkgcache.cc | 27 | ||||
-rw-r--r-- | apt-pkg/pkgcache.h | 4 | ||||
-rw-r--r-- | apt-pkg/policy.cc | 14 | ||||
-rw-r--r-- | apt-pkg/srcrecords.cc | 4 | ||||
-rw-r--r-- | apt-pkg/srcrecords.h | 8 |
27 files changed, 559 insertions, 190 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 270838f0e..6d4336425 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -310,7 +310,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ if(last_space != string::npos) Description.erase(last_space, Description.size()-last_space); new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc, - ExpectedHash, available_patches); + ExpectedHash, ServerSha1, available_patches); Complete = false; Status = StatDone; Dequeue(); @@ -378,9 +378,10 @@ void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash, /*{ pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner, string URI,string URIDesc,string ShortDesc, HashString ExpectedHash, + string ServerSha1, vector<DiffInfo> diffs) : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash), - available_patches(diffs) + available_patches(diffs), ServerSha1(ServerSha1) { DestFile = _config->FindDir("Dir::State::lists") + "partial/"; @@ -466,6 +467,13 @@ bool pkgAcqIndexDiffs::QueueNextDiff() /*{{{*/ std::clog << "QueueNextDiff: " << FinalFile << " (" << local_sha1 << ")"<<std::endl; + // final file reached before all patches are applied + if(local_sha1 == ServerSha1) + { + Finish(true); + return true; + } + // remove all patches until the next matching patch is found // this requires the Index file to be ordered for(vector<DiffInfo>::iterator I=available_patches.begin(); @@ -563,7 +571,7 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash, /* // see if there is more to download if(available_patches.size() > 0) { new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc, - ExpectedHash, available_patches); + ExpectedHash, ServerSha1, available_patches); return Finish(); } else return Finish(true); diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index 592924f3b..bafa8263a 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -422,6 +422,10 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item * off the front? */ vector<DiffInfo> available_patches; + + /** Stop applying patches when reaching that sha1 */ + string ServerSha1; + /** The current status of this patch. */ enum DiffState { @@ -475,6 +479,7 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item */ pkgAcqIndexDiffs(pkgAcquire *Owner,string URI,string URIDesc, string ShortDesc, HashString ExpectedHash, + string ServerSha1, vector<DiffInfo> diffs=vector<DiffInfo>()); }; /*}}}*/ diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 45ae9bed5..10613f11d 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -8,13 +8,18 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#include <apt-pkg/fileutl.h> #include <apt-pkg/aptconfiguration.h> #include <apt-pkg/configuration.h> +#include <apt-pkg/fileutl.h> +#include <apt-pkg/macros.h> +#include <apt-pkg/strutl.h> + +#include <sys/types.h> +#include <dirent.h> -#include <vector> -#include <string> #include <algorithm> +#include <string> +#include <vector> /*}}}*/ namespace APT { // getCompressionTypes - Return Vector of usbale compressiontypes /*{{{*/ @@ -87,4 +92,230 @@ const Configuration::getCompressionTypes(bool const &Cached) { return types; } /*}}}*/ +// GetLanguages - Return Vector of Language Codes /*{{{*/ +// --------------------------------------------------------------------- +/* return a vector of language codes in the prefered order. + the special word "environment" will be replaced with the long and the short + code of the local settings and it will be insured that this will not add + duplicates. So in an german local the setting "environment, de_DE, en, de" + will result in "de_DE, de, en". + The special word "none" is the stopcode for the not-All code vector */ +std::vector<std::string> const Configuration::getLanguages(bool const &All, + bool const &Cached, char const ** const Locale) { + using std::string; + + // The detection is boring and has a lot of cornercases, + // so we cache the results to calculated it only once. + std::vector<string> static allCodes; + std::vector<string> static codes; + + // we have something in the cache + if (codes.empty() == false || allCodes.empty() == false) { + if (Cached == true) { + if(All == true && allCodes.empty() == false) + return allCodes; + else + return codes; + } else { + allCodes.clear(); + codes.clear(); + } + } + + // Include all Language codes we have a Translation file for in /var/lib/apt/lists + // so they will be all included in the Cache. + std::vector<string> builtin; + DIR *D = opendir(_config->FindDir("Dir::State::lists").c_str()); + if (D != 0) { + builtin.push_back("none"); + for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D)) { + string const name = Ent->d_name; + size_t const foundDash = name.rfind("-"); + size_t const foundUnderscore = name.rfind("_"); + if (foundDash == string::npos || foundUnderscore == string::npos || + foundDash <= foundUnderscore || + name.substr(foundUnderscore+1, foundDash-(foundUnderscore+1)) != "Translation") + continue; + string const c = name.substr(foundDash+1); + if (unlikely(c.empty() == true) || c == "en") + continue; + // Skip unusual files, like backups or that alike + string::const_iterator s = c.begin(); + for (;s != c.end(); ++s) { + if (isalpha(*s) == 0) + break; + } + if (s != c.end()) + continue; + if (std::find(builtin.begin(), builtin.end(), c) != builtin.end()) + continue; + builtin.push_back(c); + } + } + + // get the environment language codes: LC_MESSAGES (and later LANGUAGE) + // we extract both, a long and a short code and then we will + // check if we actually need both (rare) or if the short is enough + string const envMsg = string(Locale == 0 ? std::setlocale(LC_MESSAGES, NULL) : *Locale); + size_t const lenShort = (envMsg.find('_') != string::npos) ? envMsg.find('_') : 2; + size_t const lenLong = (envMsg.find_first_of(".@") != string::npos) ? envMsg.find_first_of(".@") : (lenShort + 3); + + string envLong = envMsg.substr(0,lenLong); + string const envShort = envLong.substr(0,lenShort); + bool envLongIncluded = true; + + // first cornercase: LANG=C, so we use only "en" Translation + if (envLong == "C") { + codes.push_back("en"); + allCodes = codes; + allCodes.insert(allCodes.end(), builtin.begin(), builtin.end()); + if (All == true) + return allCodes; + else + return codes; + } + + // to save the servers from unneeded queries, we only try also long codes + // for languages it is realistic to have a long code translation fileā¦ + // TODO: Improve translation acquire system to drop them dynamic + char const *needLong[] = { "cs", "en", "pt", "sv", "zh", NULL }; + if (envLong != envShort) { + for (char const **l = needLong; *l != NULL; l++) + if (envShort.compare(*l) == 0) { + envLongIncluded = false; + break; + } + } + + // we don't add the long code, but we allow the user to do so + if (envLongIncluded == true) + envLong.clear(); + + // FIXME: Remove support for the old APT::Acquire::Translation + // it was undocumented and so it should be not very widthly used + string const oldAcquire = _config->Find("APT::Acquire::Translation",""); + if (oldAcquire.empty() == false && oldAcquire != "environment") { + if (oldAcquire != "none") + codes.push_back(oldAcquire); + codes.push_back("en"); + allCodes = codes; + for (std::vector<string>::const_iterator b = builtin.begin(); + b != builtin.end(); ++b) + if (std::find(allCodes.begin(), allCodes.end(), *b) == allCodes.end()) + allCodes.push_back(*b); + if (All == true) + return allCodes; + else + return codes; + } + + // It is very likely we will need to environment codes later, + // so let us generate them now from LC_MESSAGES and LANGUAGE + std::vector<string> environment; + // take care of LC_MESSAGES + if (envLongIncluded == false) + environment.push_back(envLong); + environment.push_back(envShort); + // take care of LANGUAGE + const char *language_env = getenv("LANGUAGE") == 0 ? "" : getenv("LANGUAGE"); + string envLang = Locale == 0 ? language_env : *(Locale+1); + if (envLang.empty() == false) { + std::vector<string> env = ExplodeString(envLang,':'); + short addedLangs = 0; // add a maximum of 3 fallbacks from the environment + for (std::vector<string>::const_iterator e = env.begin(); + e != env.end() && addedLangs < 3; ++e) { + if (unlikely(e->empty() == true) || *e == "en") + continue; + if (*e == envLong || *e == envShort) + continue; + if (std::find(environment.begin(), environment.end(), *e) != environment.end()) + continue; + if (e->find('_') != string::npos) { + // Drop LongCodes here - ShortCodes are also included + string const shorty = e->substr(0, e->find('_')); + char const **n = needLong; + for (; *n != NULL; ++n) + if (shorty == *n) + break; + if (*n == NULL) + continue; + } + ++addedLangs; + environment.push_back(*e); + } + } + + // Support settings like Acquire::Translation=none on the command line to + // override the configuration settings vector of languages. + string const forceLang = _config->Find("Acquire::Languages",""); + if (forceLang.empty() == false) { + if (forceLang == "environment") { + codes = environment; + } else if (forceLang != "none") + codes.push_back(forceLang); + allCodes = codes; + for (std::vector<string>::const_iterator b = builtin.begin(); + b != builtin.end(); ++b) + if (std::find(allCodes.begin(), allCodes.end(), *b) == allCodes.end()) + allCodes.push_back(*b); + if (All == true) + return allCodes; + else + return codes; + } + + std::vector<string> const lang = _config->FindVector("Acquire::Languages"); + // the default setting -> "environment, en" + if (lang.empty() == true) { + codes = environment; + if (envShort != "en") + codes.push_back("en"); + allCodes = codes; + for (std::vector<string>::const_iterator b = builtin.begin(); + b != builtin.end(); ++b) + if (std::find(allCodes.begin(), allCodes.end(), *b) == allCodes.end()) + allCodes.push_back(*b); + if (All == true) + return allCodes; + else + return codes; + } + + // the configs define the order, so add the environment + // then needed and ensure the codes are not listed twice. + bool noneSeen = false; + for (std::vector<string>::const_iterator l = lang.begin(); + l != lang.end(); l++) { + if (*l == "environment") { + for (std::vector<string>::const_iterator e = environment.begin(); + e != environment.end(); ++e) { + if (std::find(allCodes.begin(), allCodes.end(), *e) != allCodes.end()) + continue; + if (noneSeen == false) + codes.push_back(*e); + allCodes.push_back(*e); + } + continue; + } else if (*l == "none") { + noneSeen = true; + continue; + } else if (std::find(allCodes.begin(), allCodes.end(), *l) != allCodes.end()) + continue; + + if (noneSeen == false) + codes.push_back(*l); + allCodes.push_back(*l); + } + + for (std::vector<string>::const_iterator b = builtin.begin(); + b != builtin.end(); ++b) + if (std::find(allCodes.begin(), allCodes.end(), *b) == allCodes.end()) + allCodes.push_back(*b); + + if (All == true) + return allCodes; + else + return codes; +} + /*}}}*/ } diff --git a/apt-pkg/aptconfiguration.h b/apt-pkg/aptconfiguration.h index 6a123adce..2ba1b3825 100644 --- a/apt-pkg/aptconfiguration.h +++ b/apt-pkg/aptconfiguration.h @@ -39,6 +39,33 @@ public: /*{{{*/ * \return a vector of (all) Language Codes in the prefered usage order */ std::vector<std::string> static const getCompressionTypes(bool const &Cached = true); + + /** \brief Returns a vector of Language Codes + * + * Languages can be defined with their two or five chars long code. + * This methods handles the various ways to set the prefered codes, + * honors the environment and ensures that the codes are not listed twice. + * + * The special word "environment" will be replaced with the long and the short + * code of the local settings and it will be insured that this will not add + * duplicates. So in an german local the setting "environment, de_DE, en, de" + * will result in "de_DE, de, en". + * + * Another special word is "none" which separates the prefered from all codes + * in this setting. So setting and method can be used to get codes the user want + * to see or to get all language codes APT (should) have Translations available. + * + * \param All return all codes or only codes for languages we want to use + * \param Cached saves the result so we need to calculated it only once + * this parameter should ony be used for testing purposes. + * \param Locale don't get the locale from the system but use this one instead + * this parameter should ony be used for testing purposes. + * + * \return a vector of (all) Language Codes in the prefered usage order + */ + std::vector<std::string> static const getLanguages(bool const &All = false, + bool const &Cached = true, char const ** const Locale = 0); + /*}}}*/ }; /*}}}*/ diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc index 8e3b84499..7588b041c 100644 --- a/apt-pkg/contrib/configuration.cc +++ b/apt-pkg/contrib/configuration.cc @@ -79,7 +79,7 @@ Configuration::~Configuration() /* This will lookup a single item by name below another item. It is a helper function for the main lookup function */ Configuration::Item *Configuration::Lookup(Item *Head,const char *S, - unsigned long Len,bool Create) + unsigned long const &Len,bool const &Create) { int Res = 1; Item *I = Head->Child; @@ -112,7 +112,7 @@ Configuration::Item *Configuration::Lookup(Item *Head,const char *S, // --------------------------------------------------------------------- /* This performs a fully scoped lookup of a given name, possibly creating new items */ -Configuration::Item *Configuration::Lookup(const char *Name,bool Create) +Configuration::Item *Configuration::Lookup(const char *Name,bool const &Create) { if (Name == 0) return Root->Child; @@ -239,7 +239,7 @@ vector<string> Configuration::FindVector(const char *Name) const // Configuration::FindI - Find an integer value /*{{{*/ // --------------------------------------------------------------------- /* */ -int Configuration::FindI(const char *Name,int Default) const +int Configuration::FindI(const char *Name,int const &Default) const { const Item *Itm = Lookup(Name); if (Itm == 0 || Itm->Value.empty() == true) @@ -256,7 +256,7 @@ int Configuration::FindI(const char *Name,int Default) const // Configuration::FindB - Find a boolean type /*{{{*/ // --------------------------------------------------------------------- /* */ -bool Configuration::FindB(const char *Name,bool Default) const +bool Configuration::FindB(const char *Name,bool const &Default) const { const Item *Itm = Lookup(Name); if (Itm == 0 || Itm->Value.empty() == true) @@ -332,7 +332,7 @@ void Configuration::Set(const char *Name,const string &Value) // Configuration::Set - Set an integer value /*{{{*/ // --------------------------------------------------------------------- /* */ -void Configuration::Set(const char *Name,int Value) +void Configuration::Set(const char *Name,int const &Value) { Item *Itm = Lookup(Name,true); if (Itm == 0) @@ -345,7 +345,7 @@ void Configuration::Set(const char *Name,int Value) // Configuration::Clear - Clear an single value from a list /*{{{*/ // --------------------------------------------------------------------- /* */ -void Configuration::Clear(const string Name, int Value) +void Configuration::Clear(string const &Name, int const &Value) { char S[300]; snprintf(S,sizeof(S),"%i",Value); @@ -355,7 +355,7 @@ void Configuration::Clear(const string Name, int Value) // Configuration::Clear - Clear an single value from a list /*{{{*/ // --------------------------------------------------------------------- /* */ -void Configuration::Clear(const string Name, string Value) +void Configuration::Clear(string const &Name, string const &Value) { Item *Top = Lookup(Name.c_str(),false); if (Top == 0 || Top->Child == 0) @@ -386,7 +386,7 @@ void Configuration::Clear(const string Name, string Value) // Configuration::Clear - Clear an entire tree /*{{{*/ // --------------------------------------------------------------------- /* */ -void Configuration::Clear(string Name) +void Configuration::Clear(string const &Name) { Item *Top = Lookup(Name.c_str(),false); if (Top == 0) @@ -501,8 +501,8 @@ string Configuration::Item::FullTag(const Item *Stop) const sections like 'zone "foo.org" { .. };' This causes each section to be added in with a tag like "zone::foo.org" instead of being split tag/value. AsSectional enables Sectional parsing.*/ -bool ReadConfigFile(Configuration &Conf,const string &FName,bool AsSectional, - unsigned Depth) +bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectional, + unsigned const &Depth) { // Open the stream for reading ifstream F(FName.c_str(),ios::in); @@ -830,7 +830,7 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool AsSectional, // --------------------------------------------------------------------- /* */ bool ReadConfigDir(Configuration &Conf,const string &Dir, - bool AsSectional, unsigned Depth) + bool const &AsSectional, unsigned const &Depth) { vector<string> const List = GetListOfFilesInDir(Dir, "conf", true, true); diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h index e2da83f5b..2494c1d7c 100644 --- a/apt-pkg/contrib/configuration.h +++ b/apt-pkg/contrib/configuration.h @@ -58,8 +58,8 @@ class Configuration Item *Root; bool ToFree; - Item *Lookup(Item *Head,const char *S,unsigned long Len,bool Create); - Item *Lookup(const char *Name,bool Create); + Item *Lookup(Item *Head,const char *S,unsigned long const &Len,bool const &Create); + Item *Lookup(const char *Name,const bool &Create); inline const Item *Lookup(const char *Name) const { return ((Configuration *)this)->Lookup(Name,false); @@ -68,32 +68,33 @@ class Configuration public: string Find(const char *Name,const char *Default = 0) const; - string Find(const string Name,const char *Default = 0) const {return Find(Name.c_str(),Default);}; + string Find(string const &Name,const char *Default = 0) const {return Find(Name.c_str(),Default);}; + string Find(string const &Name, string const &Default) const {return Find(Name.c_str(),Default.c_str());}; string FindFile(const char *Name,const char *Default = 0) const; string FindDir(const char *Name,const char *Default = 0) const; - std::vector<string> FindVector(const string &Name) const; + std::vector<string> FindVector(string const &Name) const; std::vector<string> FindVector(const char *Name) const; - int FindI(const char *Name,int Default = 0) const; - int FindI(const string Name,int Default = 0) const {return FindI(Name.c_str(),Default);}; - bool FindB(const char *Name,bool Default = false) const; - bool FindB(const string Name,bool Default = false) const {return FindB(Name.c_str(),Default);}; + int FindI(const char *Name,int const &Default = 0) const; + int FindI(string const &Name,int const &Default = 0) const {return FindI(Name.c_str(),Default);}; + bool FindB(const char *Name,bool const &Default = false) const; + bool FindB(string const &Name,bool const &Default = false) const {return FindB(Name.c_str(),Default);}; string FindAny(const char *Name,const char *Default = 0) const; - inline void Set(const string Name,string Value) {Set(Name.c_str(),Value);}; + inline void Set(const string &Name,const string &Value) {Set(Name.c_str(),Value);}; void CndSet(const char *Name,const string &Value); void Set(const char *Name,const string &Value); - void Set(const char *Name,int Value); + void Set(const char *Name,const int &Value); - inline bool Exists(const string Name) const {return Exists(Name.c_str());}; + inline bool Exists(const string &Name) const {return Exists(Name.c_str());}; bool Exists(const char *Name) const; bool ExistsAny(const char *Name) const; // clear a whole tree - void Clear(const string Name); + void Clear(const string &Name); // remove a certain value from a list (e.g. the list of "APT::Keep-Fds") - void Clear(const string List, string Value); - void Clear(const string List, int Value); + void Clear(string const &List, string const &Value); + void Clear(string const &List, int const &Value); inline const Item *Tree(const char *Name) const {return Lookup(Name);}; @@ -108,11 +109,11 @@ class Configuration extern Configuration *_config; bool ReadConfigFile(Configuration &Conf,const string &FName, - bool AsSectional = false, - unsigned Depth = 0); + bool const &AsSectional = false, + unsigned const &Depth = 0); bool ReadConfigDir(Configuration &Conf,const string &Dir, - bool AsSectional = false, - unsigned Depth = 0); + bool const &AsSectional = false, + unsigned const &Depth = 0); #endif diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc index 4d5fcf71e..f440f9489 100644 --- a/apt-pkg/contrib/mmap.cc +++ b/apt-pkg/contrib/mmap.cc @@ -140,8 +140,10 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop) // DynamicMMap::DynamicMMap - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) : - MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(WorkSpace) +DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &Workspace, + unsigned long const &Grow, unsigned long const &Limit) : + MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(Workspace), + GrowFactor(Grow), Limit(Limit) { if (_error->PendingError() == true) return; @@ -165,32 +167,48 @@ DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) /* We try here to use mmap to reserve some space - this is much more cooler than the fallback solution to simply allocate a char array and could come in handy later than we are able to grow such an mmap */ -DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long WorkSpace) : - MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace) +DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long const &WorkSpace, + unsigned long const &Grow, unsigned long const &Limit) : + MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace), + GrowFactor(Grow), Limit(Limit) { - if (_error->PendingError() == true) - return; + if (_error->PendingError() == true) + return; + + // disable Moveable if we don't grow + if (Grow == 0) + Flags &= ~Moveable; + +#ifndef __linux__ + // kfreebsd doesn't have mremap, so we use the fallback + if ((Flags & Moveable) == Moveable) + Flags |= Fallback; +#endif #ifdef _POSIX_MAPPED_FILES - // Set the permissions. - int Prot = PROT_READ; - int Map = MAP_PRIVATE | MAP_ANONYMOUS; - if ((Flags & ReadOnly) != ReadOnly) - Prot |= PROT_WRITE; - if ((Flags & Public) == Public) - Map = MAP_SHARED | MAP_ANONYMOUS; + if ((Flags & Fallback) != Fallback) { + // Set the permissions. + int Prot = PROT_READ; + int Map = MAP_PRIVATE | MAP_ANONYMOUS; + if ((Flags & ReadOnly) != ReadOnly) + Prot |= PROT_WRITE; + if ((Flags & Public) == Public) + Map = MAP_SHARED | MAP_ANONYMOUS; - // use anonymous mmap() to get the memory - Base = (unsigned char*) mmap(0, WorkSpace, Prot, Map, -1, 0); + // use anonymous mmap() to get the memory + Base = (unsigned char*) mmap(0, WorkSpace, Prot, Map, -1, 0); - if(Base == MAP_FAILED) - _error->Errno("DynamicMMap",_("Couldn't make mmap of %lu bytes"),WorkSpace); -#else - // fallback to a static allocated space - Base = new unsigned char[WorkSpace]; - memset(Base,0,WorkSpace); + if(Base == MAP_FAILED) + _error->Errno("DynamicMMap",_("Couldn't make mmap of %lu bytes"),WorkSpace); + + iSize = 0; + return; + } #endif - iSize = 0; + // fallback to a static allocated space + Base = new unsigned char[WorkSpace]; + memset(Base,0,WorkSpace); + iSize = 0; } /*}}}*/ // DynamicMMap::~DynamicMMap - Destructor /*{{{*/ @@ -311,30 +329,55 @@ unsigned long DynamicMMap::WriteString(const char *String, /*}}}*/ // DynamicMMap::Grow - Grow the mmap /*{{{*/ // --------------------------------------------------------------------- -/* This method will try to grow the mmap we currently use. This doesn't - work most of the time because we can't move the mmap around in the - memory for now as this would require to adjust quite a lot of pointers - but why we should not at least try to grow it before we give up? */ -bool DynamicMMap::Grow() -{ -#if defined(_POSIX_MAPPED_FILES) && defined(__linux__) - unsigned long newSize = WorkSpace + 1024*1024; +/* This method is a wrapper around different methods to (try to) grow + a mmap (or our char[]-fallback). Encounterable environments: + 1. Moveable + !Fallback + linux -> mremap with MREMAP_MAYMOVE + 2. Moveable + !Fallback + !linux -> not possible (forbidden by constructor) + 3. Moveable + Fallback -> realloc + 4. !Moveable + !Fallback + linux -> mremap alone - which will fail in 99,9% + 5. !Moveable + !Fallback + !linux -> not possible (forbidden by constructor) + 6. !Moveable + Fallback -> not possible + [ While Moveable and Fallback stands for the equally named flags and + "linux" indicates a linux kernel instead of a freebsd kernel. ] + So what you can see here is, that a MMAP which want to be growable need + to be moveable to have a real chance but that this method will at least try + the nearly impossible 4 to grow it before it finally give up: Never say never. */ +bool DynamicMMap::Grow() { + if (Limit != 0 && WorkSpace >= Limit) + return _error->Error(_("The size of a MMap has already reached the defined limit of %lu bytes," + "abort the try to grow the MMap."), Limit); - if(Fd != 0) - { - Fd->Seek(newSize - 1); - char C = 0; - Fd->Write(&C,sizeof(C)); - } + unsigned long const newSize = WorkSpace + 1024*1024; - Base = mremap(Base, WorkSpace, newSize, 0); - if(Base == MAP_FAILED) - return false; + if(Fd != 0) { + Fd->Seek(newSize - 1); + char C = 0; + Fd->Write(&C,sizeof(C)); + } + if ((Flags & Fallback) != Fallback) { +#if defined(_POSIX_MAPPED_FILES) && defined(__linux__) + #ifdef MREMAP_MAYMOVE + if ((Flags & Moveable) == Moveable) + Base = mremap(Base, WorkSpace, newSize, MREMAP_MAYMOVE); + else + #endif + Base = mremap(Base, WorkSpace, newSize, 0); - WorkSpace = newSize; - return true; + if(Base == MAP_FAILED) + return false; #else - return false; + return false; #endif + } else { + if ((Flags & Moveable) != Moveable) + return false; + + Base = realloc(Base, newSize); + if (Base == NULL) + return false; + } + + WorkSpace = newSize; + return true; } /*}}}*/ diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h index bde62217d..cd2b15ba2 100644 --- a/apt-pkg/contrib/mmap.h +++ b/apt-pkg/contrib/mmap.h @@ -50,7 +50,7 @@ class MMap public: enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2), - UnMapped = (1<<3)}; + UnMapped = (1<<3), Moveable = (1<<4), Fallback = (1 << 5)}; // Simple accessors inline operator void *() {return Base;}; @@ -82,6 +82,8 @@ class DynamicMMap : public MMap FileFd *Fd; unsigned long WorkSpace; + unsigned long const GrowFactor; + unsigned long const Limit; Pool *Pools; unsigned int PoolCount; @@ -96,8 +98,10 @@ class DynamicMMap : public MMap inline unsigned long WriteString(const string &S) {return WriteString(S.c_str(),S.length());}; void UsePools(Pool &P,unsigned int Count) {Pools = &P; PoolCount = Count;}; - DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace = 2*1024*1024); - DynamicMMap(unsigned long Flags,unsigned long WorkSpace = 2*1024*1024); + DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &WorkSpace = 2*1024*1024, + unsigned long const &Grow = 1024*1024, unsigned long const &Limit = 0); + DynamicMMap(unsigned long Flags,unsigned long const &WorkSpace = 2*1024*1024, + unsigned long const &Grow = 1024*1024, unsigned long const &Limit = 0); virtual ~DynamicMMap(); }; diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 8e8820949..1b9922a31 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -1000,6 +1000,24 @@ 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 + 1; + } while (end != haystack.end() && (++end) != haystack.end()); + return exploded; +} + /*}}}*/ // RegexChoice - Simple regex list/list matcher /*{{{*/ // --------------------------------------------------------------------- /* */ diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index a1e7f3934..e72288f4c 100644 --- a/apt-pkg/contrib/strutl.h +++ b/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; diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index 3b11ad2eb..7379ca997 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -329,10 +329,11 @@ pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const // TranslationsIndex::debTranslationsIndex - Contructor /*{{{*/ // --------------------------------------------------------------------- /* */ -debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section) : - pkgIndexFile(true), URI(URI), Dist(Dist), Section(Section) -{ -} +debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section, + char const * const Translation) : + pkgIndexFile(true), URI(URI), Dist(Dist), Section(Section), + Language(Translation) +{} /*}}}*/ // TranslationIndex::Trans* - Return the URI to the translation files /*{{{*/ // --------------------------------------------------------------------- @@ -365,8 +366,8 @@ string debTranslationsIndex::IndexURI(const char *Type) const bool debTranslationsIndex::GetIndexes(pkgAcquire *Owner) const { if (TranslationsAvailable()) { - string TranslationFile = "Translation-" + LanguageCode(); - new pkgAcqIndexTrans(Owner, IndexURI(LanguageCode().c_str()), + string const TranslationFile = string("Translation-").append(Language); + new pkgAcqIndexTrans(Owner, IndexURI(Language), Info(TranslationFile.c_str()), TranslationFile); } @@ -385,7 +386,7 @@ string debTranslationsIndex::Describe(bool Short) const snprintf(S,sizeof(S),"%s",Info(TranslationFile().c_str()).c_str()); else snprintf(S,sizeof(S),"%s (%s)",Info(TranslationFile().c_str()).c_str(), - IndexFile(LanguageCode().c_str()).c_str()); + IndexFile(Language).c_str()); return S; } /*}}}*/ @@ -407,20 +408,20 @@ string debTranslationsIndex::Info(const char *Type) const return Info; } /*}}}*/ -bool debTranslationsIndex::HasPackages() const +bool debTranslationsIndex::HasPackages() const /*{{{*/ { if(!TranslationsAvailable()) return false; - return FileExists(IndexFile(LanguageCode().c_str())); + return FileExists(IndexFile(Language)); } - + /*}}}*/ // TranslationsIndex::Exists - Check if the index is available /*{{{*/ // --------------------------------------------------------------------- /* */ bool debTranslationsIndex::Exists() const { - return FileExists(IndexFile(LanguageCode().c_str())); + return FileExists(IndexFile(Language)); } /*}}}*/ // TranslationsIndex::Size - Return the size of the index /*{{{*/ @@ -429,7 +430,7 @@ bool debTranslationsIndex::Exists() const unsigned long debTranslationsIndex::Size() const { struct stat S; - if (stat(IndexFile(LanguageCode().c_str()).c_str(),&S) != 0) + if (stat(IndexFile(Language).c_str(),&S) != 0) return 0; return S.st_size; } @@ -440,7 +441,7 @@ unsigned long debTranslationsIndex::Size() const bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const { // Check the translation file, if in use - string TranslationFile = IndexFile(LanguageCode().c_str()); + string TranslationFile = IndexFile(Language); if (TranslationsAvailable() && FileExists(TranslationFile)) { FileFd Trans(TranslationFile,FileFd::ReadOnly); @@ -472,7 +473,7 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const /* */ pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) const { - string FileName = IndexFile(LanguageCode().c_str()); + string FileName = IndexFile(Language); pkgCache::PkgFileIterator File = Cache.FileBegin(); for (; File.end() == false; File++) diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h index b0012c96b..c0e8d7d8e 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@ -77,12 +77,13 @@ class debTranslationsIndex : public pkgIndexFile string URI; string Dist; string Section; + const char * const Language; string Info(const char *Type) const; string IndexFile(const char *Type) const; string IndexURI(const char *Type) const; - inline string TranslationFile() const {return "Translation-" + LanguageCode();}; + inline string TranslationFile() const {return string("Translation-").append(Language);}; public: @@ -99,7 +100,7 @@ class debTranslationsIndex : public pkgIndexFile virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; - debTranslationsIndex(string URI,string Dist,string Section); + debTranslationsIndex(string URI,string Dist,string Section, char const * const Language); }; class debSourcesIndex : public pkgIndexFile diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 25b0953e0..66108d822 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -13,6 +13,7 @@ #include <apt-pkg/deblistparser.h> #include <apt-pkg/error.h> #include <apt-pkg/configuration.h> +#include <apt-pkg/aptconfiguration.h> #include <apt-pkg/strutl.h> #include <apt-pkg/crc-16.h> #include <apt-pkg/md5.h> @@ -128,10 +129,11 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) only describe package properties */ string debListParser::Description() { - if (DescriptionLanguage().empty()) + string const lang = DescriptionLanguage(); + if (lang.empty()) return Section.FindS("Description"); else - return Section.FindS(("Description-" + pkgIndexFile::LanguageCode()).c_str()); + return Section.FindS(string("Description-").append(lang).c_str()); } /*}}}*/ // ListParser::DescriptionLanguage - Return the description lang string /*{{{*/ @@ -141,7 +143,16 @@ string debListParser::Description() assumed to describe original description. */ string debListParser::DescriptionLanguage() { - return Section.FindS("Description").empty() ? pkgIndexFile::LanguageCode() : ""; + if (Section.FindS("Description").empty() == false) + return ""; + + std::vector<string> const lang = APT::Configuration::getLanguages(); + for (std::vector<string>::const_iterator l = lang.begin(); + l != lang.end(); l++) + if (Section.FindS(string("Description-").append(*l).c_str()).empty() == false) + return *l; + + return ""; } /*}}}*/ // ListParser::Description - Return the description_md5 MD5SumValue /*{{{*/ @@ -383,7 +394,8 @@ const char *debListParser::ConvertRelation(const char *I,unsigned int &Op) bit by bit. */ const char *debListParser::ParseDepends(const char *Start,const char *Stop, string &Package,string &Ver, - unsigned int &Op, bool ParseArchFlags) + unsigned int &Op, bool const &ParseArchFlags, + bool const &StripMultiArch) { // Strip off leading space for (;Start != Stop && isspace(*Start) != 0; Start++); @@ -402,7 +414,14 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop, // Stash the package name Package.assign(Start,I - Start); - + + // We don't want to confuse library users which can't handle MultiArch + if (StripMultiArch == true) { + size_t const found = Package.rfind(':'); + if (found != string::npos) + Package = Package.substr(0,found); + } + // Skip white space to the '(' for (;I != Stop && isspace(*I) != 0 ; I++); diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 34bb29c72..1c709229f 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -64,7 +64,8 @@ class debListParser : public pkgCacheGenerator::ListParser static const char *ParseDepends(const char *Start,const char *Stop, string &Package,string &Ver,unsigned int &Op, - bool ParseArchFlags = false); + bool const &ParseArchFlags = false, + bool const &StripMultiArch = false); static const char *ConvertRelation(const char *I,unsigned int &Op); debListParser(FileFd *File); diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index f3ab6960c..520e94a80 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -5,6 +5,7 @@ #include <apt-pkg/strutl.h> #include <apt-pkg/acquire-item.h> #include <apt-pkg/configuration.h> +#include <apt-pkg/aptconfiguration.h> #include <apt-pkg/error.h> using namespace std; @@ -170,13 +171,20 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const 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; - debTranslationsIndex i = debTranslationsIndex(URI,Dist,(*I)->Section); - i.GetIndexes(Owner); + + for (vector<string>::const_iterator l = lang.begin(); + l != lang.end(); l++) + { + if (*l == "none") continue; + debTranslationsIndex i = debTranslationsIndex(URI,Dist,(*I)->Section,(*l).c_str()); + i.GetIndexes(Owner); + } } return true; @@ -202,6 +210,7 @@ vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() 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) @@ -209,7 +218,12 @@ vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() else { Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted())); - Indexes->push_back(new debTranslationsIndex(URI, Dist, (*I)->Section)); + + for (vector<string>::const_iterator l = lang.begin(); + l != lang.end(); l++) { + if (*l == "none") continue; + Indexes->push_back(new debTranslationsIndex(URI,Dist,(*I)->Section,(*l).c_str())); + } } } diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc index 8ed0bb7eb..5b8538a46 100644 --- a/apt-pkg/deb/debrecords.cc +++ b/apt-pkg/deb/debrecords.cc @@ -11,6 +11,7 @@ #include <apt-pkg/debrecords.h> #include <apt-pkg/strutl.h> #include <apt-pkg/error.h> +#include <apt-pkg/aptconfiguration.h> #include <langinfo.h> /*}}}*/ @@ -109,13 +110,18 @@ string debRecordParser::ShortDesc() string debRecordParser::LongDesc() { string orig, dest; - char *codeset = nl_langinfo(CODESET); if (!Section.FindS("Description").empty()) orig = Section.FindS("Description").c_str(); - else - orig = Section.FindS(("Description-" + pkgIndexFile::LanguageCode()).c_str()).c_str(); + else + { + vector<string> const lang = APT::Configuration::getLanguages(); + for (vector<string>::const_iterator l = lang.begin(); + orig.empty() && l != lang.end(); l++) + orig = Section.FindS(string("Description-").append(*l).c_str()); + } + char const * const codeset = nl_langinfo(CODESET); if (strcmp(codeset,"UTF-8") != 0) { UTF8ToCodeset(codeset, orig, &dest); orig = dest; diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc index bde10aa6d..21336e1af 100644 --- a/apt-pkg/deb/debsrcrecords.cc +++ b/apt-pkg/deb/debsrcrecords.cc @@ -54,7 +54,8 @@ const char **debSrcRecordParser::Binaries() package/version records representing the build dependency. The returned array need not be freed and will be reused by the next call to this function */ -bool debSrcRecordParser::BuildDepends(vector<pkgSrcRecords::Parser::BuildDepRec> &BuildDeps, bool ArchOnly) +bool debSrcRecordParser::BuildDepends(vector<pkgSrcRecords::Parser::BuildDepRec> &BuildDeps, + bool const &ArchOnly, bool const &StripMultiArch) { unsigned int I; const char *Start, *Stop; @@ -77,7 +78,7 @@ bool debSrcRecordParser::BuildDepends(vector<pkgSrcRecords::Parser::BuildDepRec> while (1) { Start = debListParser::ParseDepends(Start, Stop, - rec.Package,rec.Version,rec.Op,true); + rec.Package,rec.Version,rec.Op,true, StripMultiArch); if (Start == 0) return _error->Error("Problem parsing dependency: %s", fields[I]); diff --git a/apt-pkg/deb/debsrcrecords.h b/apt-pkg/deb/debsrcrecords.h index a3b5a8286..c39d78bae 100644 --- a/apt-pkg/deb/debsrcrecords.h +++ b/apt-pkg/deb/debsrcrecords.h @@ -30,14 +30,14 @@ class debSrcRecordParser : public pkgSrcRecords::Parser virtual bool Restart() {return Tags.Jump(Sect,0);}; virtual bool Step() {iOffset = Tags.Offset(); return Tags.Step(Sect);}; - virtual bool Jump(unsigned long Off) {iOffset = Off; return Tags.Jump(Sect,Off);}; + virtual bool Jump(unsigned long const &Off) {iOffset = Off; return Tags.Jump(Sect,Off);}; virtual string Package() const {return Sect.FindS("Package");}; virtual string Version() const {return Sect.FindS("Version");}; virtual string Maintainer() const {return Sect.FindS("Maintainer");}; virtual string Section() const {return Sect.FindS("Section");}; virtual const char **Binaries(); - virtual bool BuildDepends(vector<BuildDepRec> &BuildDeps, bool ArchOnly); + virtual bool BuildDepends(vector<BuildDepRec> &BuildDeps, bool const &ArchOnly, bool const &StripMultiArch = true); virtual unsigned long Offset() {return iOffset;}; virtual string AsStr() { @@ -47,7 +47,7 @@ class debSrcRecordParser : public pkgSrcRecords::Parser }; virtual bool Files(vector<pkgSrcRecords::File> &F); - debSrcRecordParser(string File,pkgIndexFile const *Index) + debSrcRecordParser(string const &File,pkgIndexFile const *Index) : Parser(Index), Fd(File,FileFd::ReadOnly), Tags(&Fd,102400), Buffer(0), BufSize(0) {} ~debSrcRecordParser(); diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 8abe3f5c6..5b02cae1d 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1064,7 +1064,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) // wait for input or output here FD_ZERO(&rfds); - if (!stdin_is_dev_null) + if (master >= 0 && !stdin_is_dev_null) FD_SET(0, &rfds); FD_SET(_dpkgin, &rfds); if(master >= 0) diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 37b1c889d..0f30f13c2 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -192,10 +192,10 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) /*{{{*/ Prog->OverallProgress(amt, file_size, 1, _("Reading state information")); } - if(Prog != NULL) - Prog->OverallProgress(file_size, file_size, 1, - _("Reading state information")); } + if(Prog != NULL) + Prog->OverallProgress(file_size, file_size, 1, + _("Reading state information")); } return true; diff --git a/apt-pkg/indexfile.cc b/apt-pkg/indexfile.cc index 5a82b7b2e..37be87055 100644 --- a/apt-pkg/indexfile.cc +++ b/apt-pkg/indexfile.cc @@ -8,9 +8,9 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#include <apt-pkg/configuration.h> #include <apt-pkg/indexfile.h> #include <apt-pkg/error.h> +#include <apt-pkg/aptconfiguration.h> #include <clocale> #include <cstring> @@ -66,34 +66,23 @@ string pkgIndexFile::SourceInfo(pkgSrcRecords::Parser const &Record, return string(); } /*}}}*/ -// IndexFile::TranslationsAvailable - Check if will use Translation /*{{{*/ +// IndexFile::TranslationsAvailable - Check if will use Translation /*{{{*/ // --------------------------------------------------------------------- /* */ -bool pkgIndexFile::TranslationsAvailable() -{ - const string Translation = _config->Find("APT::Acquire::Translation"); - - if (Translation.compare("none") != 0) - return CheckLanguageCode(LanguageCode().c_str()); - else - return false; +bool pkgIndexFile::TranslationsAvailable() { + return (APT::Configuration::getLanguages().empty() != true); } /*}}}*/ -// IndexFile::CheckLanguageCode - Check the Language Code /*{{{*/ +// IndexFile::CheckLanguageCode - Check the Language Code /*{{{*/ // --------------------------------------------------------------------- -/* */ -/* common cases: de_DE, de_DE@euro, de_DE.UTF-8, de_DE.UTF-8@euro, - de_DE.ISO8859-1, tig_ER - more in /etc/gdm/locale.conf -*/ - -bool pkgIndexFile::CheckLanguageCode(const char *Lang) +/* No intern need for this method anymore as the check for correctness + is already done in getLanguages(). Note also that this check is + rather bad (doesn't take three character like ast into account). + TODO: Remove method with next API break */ +__attribute__ ((deprecated)) bool pkgIndexFile::CheckLanguageCode(const char *Lang) { - if (strlen(Lang) == 2 || - strlen(Lang) == 3 || - (strlen(Lang) > 3 && Lang[3] == '_') || - (strlen(Lang) == 5 && Lang[2] == '_')) - return true; + if (strlen(Lang) == 2 || (strlen(Lang) == 5 && Lang[2] == '_')) + return true; if (strcmp(Lang,"C") != 0) _error->Warning("Wrong language code %s", Lang); @@ -101,38 +90,14 @@ bool pkgIndexFile::CheckLanguageCode(const char *Lang) return false; } /*}}}*/ -// IndexFile::LanguageCode - Return the Language Code /*{{{*/ +// IndexFile::LanguageCode - Return the Language Code /*{{{*/ // --------------------------------------------------------------------- -/* return the language code */ -string pkgIndexFile::LanguageCode() -{ - const string Translation = _config->Find("APT::Acquire::Translation"); - - if (Translation.compare("environment") == 0) - { - string lang = std::setlocale(LC_MESSAGES,NULL); - - // we have a mapping of the language codes that contains all the language - // codes that need the country code as well - // (like pt_BR, pt_PT, sv_SE, zh_*, en_*) - const char *need_full_langcode[] = { "cs_", - "en_", - "pt_", - "sv_", - "zh_", - NULL }; - for(const char **s = need_full_langcode;*s != NULL; s++) - if(lang.find(*s) == 0) - return lang.substr(0,5); - - if(lang.find("_") != lang.npos) - return lang.substr(0, lang.find("_")); - else if(lang.find(".") != lang.npos) - return lang.substr(0, lang.find(".")); - else - return lang; - } - else - return Translation; +/* As we have now possibly more than one LanguageCode this method is + supersided by a) private classmembers or b) getLanguages(). + TODO: Remove method with next API break */ +__attribute__ ((deprecated)) string pkgIndexFile::LanguageCode() { + if (TranslationsAvailable() == false) + return ""; + return APT::Configuration::getLanguages()[0]; } /*}}}*/ diff --git a/apt-pkg/init.h b/apt-pkg/init.h index f0757f644..b3e4b147f 100644 --- a/apt-pkg/init.h +++ b/apt-pkg/init.h @@ -22,7 +22,7 @@ // Non-ABI-Breaks should only increase RELEASE number. // See also buildlib/libversion.mak #define APT_PKG_MAJOR 4 -#define APT_PKG_MINOR 8 +#define APT_PKG_MINOR 9 #define APT_PKG_RELEASE 0 extern const char *pkgVersion; diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 4a0f3ee58..038bd7ec4 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -22,11 +22,12 @@ // Include Files /*{{{*/ #include <apt-pkg/pkgcache.h> #include <apt-pkg/policy.h> -#include <apt-pkg/indexfile.h> #include <apt-pkg/version.h> #include <apt-pkg/error.h> #include <apt-pkg/strutl.h> #include <apt-pkg/configuration.h> +#include <apt-pkg/aptconfiguration.h> +#include <apt-pkg/macros.h> #include <apti18n.h> @@ -673,14 +674,22 @@ string pkgCache::PkgFileIterator::RelStr() */ pkgCache::DescIterator pkgCache::VerIterator::TranslatedDescription() const { - pkgCache::DescIterator DescDefault = DescriptionList(); - pkgCache::DescIterator Desc = DescDefault; - for (; Desc.end() == false; Desc++) - if (pkgIndexFile::LanguageCode() == Desc.LanguageCode()) - break; - if (Desc.end() == true) - Desc = DescDefault; - return Desc; + std::vector<string> const lang = APT::Configuration::getLanguages(); + for (std::vector<string>::const_iterator l = lang.begin(); + l != lang.end(); l++) + { + pkgCache::DescIterator DescDefault = DescriptionList(); + pkgCache::DescIterator Desc = DescDefault; + + for (; Desc.end() == false; Desc++) + if (*l == Desc.LanguageCode()) + break; + if (Desc.end() == true) + Desc = DescDefault; + return Desc; + } + + return DescriptionList(); }; /*}}}*/ diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 38733713f..e8a3e1064 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -245,7 +245,7 @@ struct pkgCache::VerFile /*{{{*/ map_ptrloc File; // PackageFile map_ptrloc NextFile; // PkgVerFile map_ptrloc Offset; // File offset - unsigned short Size; + unsigned long Size; }; /*}}}*/ struct pkgCache::DescFile /*{{{*/ @@ -253,7 +253,7 @@ struct pkgCache::DescFile /*{{{*/ map_ptrloc File; // PackageFile map_ptrloc NextFile; // PkgVerFile map_ptrloc Offset; // File offset - unsigned short Size; + unsigned long Size; }; /*}}}*/ struct pkgCache::Version /*{{{*/ diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index a24ab7452..4996007a3 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -121,6 +121,10 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator Pkg) signed Max = GetPriority(Pkg); pkgCache::VerIterator Pref = GetMatch(Pkg); + // Alternatives in case we can not find our package pin (Bug#512318). + signed MaxAlt = 0; + pkgCache::VerIterator PrefAlt; + // no package = no candidate version if (Pkg.end() == true) return Pref; @@ -159,6 +163,11 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator Pkg) { Pref = Ver; Max = Prio; + } + if (Prio > MaxAlt) + { + PrefAlt = Ver; + MaxAlt = Prio; } } @@ -175,6 +184,11 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator Pkg) break; } } + // If we do not find our candidate, use the one with the highest pin. + // This means that if there is a version available with pin > 0; there + // will always be a candidate (Closes: #512318) + if (!Pref.IsGood() && MaxAlt > 0) + Pref = PrefAlt; return Pref; } /*}}}*/ diff --git a/apt-pkg/srcrecords.cc b/apt-pkg/srcrecords.cc index 5e40ae624..46a02b55c 100644 --- a/apt-pkg/srcrecords.cc +++ b/apt-pkg/srcrecords.cc @@ -77,7 +77,7 @@ bool pkgSrcRecords::Restart() /* This searches on both source package names and output binary names and returns the first found. A 'cursor' like system is used to allow this function to be called multiple times to get successive entries */ -pkgSrcRecords::Parser *pkgSrcRecords::Find(const char *Package,bool SrcOnly) +pkgSrcRecords::Parser *pkgSrcRecords::Find(const char *Package,bool const &SrcOnly) { if (Current == Files.end()) return 0; @@ -116,7 +116,7 @@ pkgSrcRecords::Parser *pkgSrcRecords::Find(const char *Package,bool SrcOnly) // Parser::BuildDepType - Convert a build dep to a string /*{{{*/ // --------------------------------------------------------------------- /* */ -const char *pkgSrcRecords::Parser::BuildDepType(unsigned char Type) +const char *pkgSrcRecords::Parser::BuildDepType(unsigned char const &Type) { const char *fields[] = {"Build-Depends", "Build-Depends-Indep", diff --git a/apt-pkg/srcrecords.h b/apt-pkg/srcrecords.h index 99cbc6060..a49533864 100644 --- a/apt-pkg/srcrecords.h +++ b/apt-pkg/srcrecords.h @@ -59,7 +59,7 @@ class pkgSrcRecords virtual bool Restart() = 0; virtual bool Step() = 0; - virtual bool Jump(unsigned long Off) = 0; + virtual bool Jump(unsigned long const &Off) = 0; virtual unsigned long Offset() = 0; virtual string AsStr() = 0; @@ -69,8 +69,8 @@ class pkgSrcRecords virtual string Section() const = 0; virtual const char **Binaries() = 0; // Ownership does not transfer - virtual bool BuildDepends(vector<BuildDepRec> &BuildDeps, bool ArchOnly) = 0; - static const char *BuildDepType(unsigned char Type); + virtual bool BuildDepends(vector<BuildDepRec> &BuildDeps, bool const &ArchOnly, bool const &StripMultiArch = true) = 0; + static const char *BuildDepType(unsigned char const &Type); virtual bool Files(vector<pkgSrcRecords::File> &F) = 0; @@ -90,7 +90,7 @@ class pkgSrcRecords bool Restart(); // Locate a package by name - Parser *Find(const char *Package,bool SrcOnly = false); + Parser *Find(const char *Package,bool const &SrcOnly = false); pkgSrcRecords(pkgSourceList &List); ~pkgSrcRecords(); |