From d6c4a9764d052c9755ab934c97c7a84c48ebd618 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 9 Nov 2009 10:17:19 +0100 Subject: extent the mmap to be able to handle currently not implemented (but planed) growable mmaps --- apt-pkg/contrib/mmap.cc | 127 ++++++++++++++++++++++++++++++++---------------- apt-pkg/contrib/mmap.h | 10 ++-- 2 files changed, 92 insertions(+), 45 deletions(-) (limited to 'apt-pkg') 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(); }; -- cgit v1.2.3 From 6d3176fbe8483df9995e639a49aaf5f6f6fd52ee Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 25 Nov 2009 20:22:36 +0100 Subject: =?UTF-8?q?use=20long=20instead=20of=20short=20for=20{Ver,Desc}Fil?= =?UTF-8?q?e=20size=20in=20pkgcache.h=20patch=20from=20V=C3=ADctor=20Manue?= =?UTF-8?q?l=20J=C3=A1quez=20Leal,=20thanks!=20(Closes:=20#538917)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apt-pkg/pkgcache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') 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 /*{{{*/ -- cgit v1.2.3 From 8a3207f42741ce9ccf68f9a0e6528622f8f6e6c2 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 25 Nov 2009 21:57:51 +0100 Subject: allow also to skip the last patch if target is reached in acquire-item.cc, thanks Bernhard R. Link! (Closes: #545699) --- apt-pkg/acquire-item.cc | 14 +++++++++++--- apt-pkg/acquire-item.h | 5 +++++ 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index afb3daad3..10e80eb56 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -274,7 +274,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(); @@ -342,9 +342,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 diffs) : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash), - available_patches(diffs) + available_patches(diffs), ServerSha1(ServerSha1) { DestFile = _config->FindDir("Dir::State::lists") + "partial/"; @@ -430,6 +431,13 @@ bool pkgAcqIndexDiffs::QueueNextDiff() /*{{{*/ std::clog << "QueueNextDiff: " << FinalFile << " (" << local_sha1 << ")"<::iterator I=available_patches.begin(); @@ -527,7 +535,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 3f073de5b..d862d0fdd 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 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 diffs=vector()); }; /*}}}*/ -- cgit v1.2.3 From ce857f32cf3c73ee67147ea0eafadb5a1c5da952 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 25 Nov 2009 23:24:43 +0100 Subject: another round of method hardening with const& in Configuration --- apt-pkg/contrib/configuration.cc | 24 ++++++++++++------------ apt-pkg/contrib/configuration.h | 37 +++++++++++++++++++------------------ 2 files changed, 31 insertions(+), 30 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc index 4e8586e83..ff49ce857 100644 --- a/apt-pkg/contrib/configuration.cc +++ b/apt-pkg/contrib/configuration.cc @@ -85,7 +85,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; @@ -118,7 +118,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; @@ -245,7 +245,7 @@ vector 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) @@ -262,7 +262,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) @@ -338,7 +338,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) @@ -351,7 +351,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); @@ -361,7 +361,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) @@ -392,7 +392,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) @@ -507,8 +507,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); @@ -835,8 +835,8 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool AsSectional, // ReadConfigDir - Read a directory of config files /*{{{*/ // --------------------------------------------------------------------- /* */ -bool ReadConfigDir(Configuration &Conf,const string &Dir,bool AsSectional, - unsigned Depth) +bool ReadConfigDir(Configuration &Conf,const string &Dir,bool const &AsSectional, + unsigned const &Depth) { DIR *D = opendir(Dir.c_str()); if (D == 0) 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 FindVector(const string &Name) const; + std::vector FindVector(string const &Name) const; std::vector 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 -- cgit v1.2.3 From 45df0ad2aab7d019cec855ba2cfe7ecdd0f8c7c8 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 26 Nov 2009 22:23:08 +0100 Subject: [BREAK] add possibility to download and use multiply Translation files, configurable with Acquire::Languages accessable with APT::Configuration::getLanguages() and as always with documentation in apt.conf. The commit also includes a very very simple testapp. --- apt-pkg/aptconfiguration.cc | 136 +++++++++++++++++++++++++++++++++++++++++++ apt-pkg/aptconfiguration.h | 27 +++++++++ apt-pkg/deb/debindexfile.cc | 29 ++++----- apt-pkg/deb/debindexfile.h | 5 +- apt-pkg/deb/deblistparser.cc | 17 +++++- apt-pkg/deb/debmetaindex.cc | 17 +++++- apt-pkg/deb/debrecords.cc | 12 +++- apt-pkg/indexfile.cc | 61 ++++++------------- apt-pkg/pkgcache.cc | 26 ++++++--- 9 files changed, 253 insertions(+), 77 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 45ae9bed5..899004d9f 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -87,4 +87,140 @@ 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 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 static allCodes; + std::vector 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(); + } + } + + // get the environment language code + // 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('.') != string::npos) ? envMsg.find('.') : (lenShort + 3); + + string envLong = envMsg.substr(0,lenLong); + string const envShort = envLong.substr(0,lenShort); + bool envLongIncluded = true, envShortIncluded = false; + + // first cornercase: LANG=C, so we use only "en" Translation + if (envLong == "C") { + codes.push_back("en"); + return codes; + } + + if (envLong != envShort) { + // 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... + char const *needLong[] = { "cs", "en", "pt", "sv", "zh", NULL }; + 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); + return codes; + } + + // 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") { + if (envLongIncluded == false) + codes.push_back(envLong); + if (envShortIncluded == false) + codes.push_back(envShort); + return codes; + } else if (forceLang != "none") + codes.push_back(forceLang); + return codes; + } + + std::vector const lang = _config->FindVector("Acquire::Languages"); + // the default setting -> "environment, en" + if (lang.empty() == true) { + if (envLongIncluded == false) + codes.push_back(envLong); + if (envShortIncluded == false) + codes.push_back(envShort); + if (envShort != "en") + codes.push_back("en"); + 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::const_iterator l = lang.begin(); + l != lang.end(); l++) { + if (*l == "environment") { + if (envLongIncluded == true && envShortIncluded == true) + continue; + if (envLongIncluded == false) { + envLongIncluded = true; + if (noneSeen == false) + codes.push_back(envLong); + allCodes.push_back(envLong); + } + if (envShortIncluded == false) { + envShortIncluded = true; + if (noneSeen == false) + codes.push_back(envShort); + allCodes.push_back(envShort); + } + continue; + } else if (*l == "none") { + noneSeen = true; + continue; + } else if ((envLongIncluded == true && *l == envLong) || + (envShortIncluded == true && *l == envShort)) + continue; + + if (noneSeen == false) + codes.push_back(*l); + allCodes.push_back(*l); + } + if (All == true) + return allCodes; + else + return codes; +} + /*}}}*/ } diff --git a/apt-pkg/aptconfiguration.h b/apt-pkg/aptconfiguration.h index 6a123adce..f2f04a39b 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 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 static const getLanguages(bool const &All = false, + bool const &Cached = true, char const * const Locale = 0); + /*}}}*/ }; /*}}}*/ diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index ed7633803..5beb83665 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -319,10 +319,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 /*{{{*/ // --------------------------------------------------------------------- @@ -355,8 +356,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); } @@ -375,7 +376,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; } /*}}}*/ @@ -397,20 +398,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 /*{{{*/ @@ -419,7 +420,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; } @@ -430,7 +431,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); @@ -462,7 +463,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 517b771a5..16e6ee332 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -129,10 +130,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 /*{{{*/ @@ -142,7 +144,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 const lang = APT::Configuration::getLanguages(); + for (std::vector::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 /*{{{*/ diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index f3ab6960c..8f28f053b 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -5,6 +5,7 @@ #include #include #include +#include #include using namespace std; @@ -170,13 +171,19 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const new indexRecords (Dist)); // Queue the translations + std::vector const lang = APT::Configuration::getLanguages(true); for (vector::const_iterator I = SectionEntries.begin(); I != SectionEntries.end(); I++) { if((*I)->IsSrc) continue; - debTranslationsIndex i = debTranslationsIndex(URI,Dist,(*I)->Section); - i.GetIndexes(Owner); + + for (vector::const_iterator l = lang.begin(); + l != lang.end(); l++) + { + debTranslationsIndex i = debTranslationsIndex(URI,Dist,(*I)->Section,(*l).c_str()); + i.GetIndexes(Owner); + } } return true; @@ -202,6 +209,7 @@ vector *debReleaseIndex::GetIndexFiles() return Indexes; Indexes = new vector ; + std::vector const lang = APT::Configuration::getLanguages(true); for (vector::const_iterator I = SectionEntries.begin(); I != SectionEntries.end(); I++) { if ((*I)->IsSrc) @@ -209,7 +217,10 @@ vector *debReleaseIndex::GetIndexFiles() else { Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted())); - Indexes->push_back(new debTranslationsIndex(URI, Dist, (*I)->Section)); + + for (vector::const_iterator l = lang.begin(); + l != lang.end(); l++) + 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 #include #include +#include #include /*}}}*/ @@ -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 const lang = APT::Configuration::getLanguages(); + for (vector::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/indexfile.cc b/apt-pkg/indexfile.cc index 08f71feb0..37be87055 100644 --- a/apt-pkg/indexfile.cc +++ b/apt-pkg/indexfile.cc @@ -8,9 +8,9 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#include #include #include +#include #include #include @@ -66,28 +66,20 @@ 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) == 5 && Lang[2] == '_')) return true; @@ -98,31 +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[] = { "pt","sv","zh","en", NULL }; - for(const char **s = need_full_langcode;*s != NULL; s++) - if(lang.find(*s) == 0) - return lang.substr(0,5); - - if(lang.size() > 2) - return lang.substr(0,2); - 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/pkgcache.cc b/apt-pkg/pkgcache.cc index b0ce6e598..997ff51fe 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -22,11 +22,11 @@ // Include Files /*{{{*/ #include #include -#include #include #include #include #include +#include #include @@ -674,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 const lang = APT::Configuration::getLanguages(); + for (std::vector::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(); }; /*}}}*/ -- cgit v1.2.3 From 164994f54fbb2283a0ad320fe34009ee9cd06f8e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 27 Nov 2009 10:10:55 +0100 Subject: use "diff" filetype for .debian.tar.* files (Closes: #554898) in apt-pkg/deb/debsrcrecords.cc as source format v3 uses this name scheme for their "diff" files. --- apt-pkg/deb/debsrcrecords.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc index 2f87c767b..bde10aa6d 100644 --- a/apt-pkg/deb/debsrcrecords.cc +++ b/apt-pkg/deb/debsrcrecords.cc @@ -135,9 +135,15 @@ bool debSrcRecordParser::Files(vector &List) string::size_type Tmp = F.Path.rfind('.',Pos); if (Tmp == string::npos) break; + if (F.Type == "tar") { + // source v3 has extension 'debian.tar.*' instead of 'diff.*' + if (string(F.Path, Tmp+1, Pos-Tmp) == "debian") + F.Type = "diff"; + break; + } F.Type = string(F.Path,Tmp+1,Pos-Tmp); - if (F.Type == "gz" || F.Type == "bz2" || F.Type == "lzma") + if (F.Type == "gz" || F.Type == "bz2" || F.Type == "lzma" || F.Type == "tar") { Pos = Tmp-1; continue; -- cgit v1.2.3 From 41c81fd85d43ed747375d8f1ee7a9b71fb3c7016 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 29 Nov 2009 00:23:26 +0100 Subject: Ignore :qualifiers after package name in build dependencies for now as long we don't understand them (Closes: #558103) --- apt-pkg/deb/deblistparser.cc | 12 ++++++++++-- apt-pkg/deb/deblistparser.h | 3 ++- apt-pkg/deb/debsrcrecords.cc | 5 +++-- apt-pkg/deb/debsrcrecords.h | 6 +++--- apt-pkg/srcrecords.cc | 4 ++-- apt-pkg/srcrecords.h | 8 ++++---- 6 files changed, 24 insertions(+), 14 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 16e6ee332..25a1df3f9 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -395,7 +395,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++); @@ -414,7 +415,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/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 &BuildDeps, bool ArchOnly) +bool debSrcRecordParser::BuildDepends(vector &BuildDeps, + bool const &ArchOnly, bool const &StripMultiArch) { unsigned int I; const char *Start, *Stop; @@ -77,7 +78,7 @@ bool debSrcRecordParser::BuildDepends(vector 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 &BuildDeps, bool ArchOnly); + virtual bool BuildDepends(vector &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 &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/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 &BuildDeps, bool ArchOnly) = 0; - static const char *BuildDepType(unsigned char Type); + virtual bool BuildDepends(vector &BuildDeps, bool const &ArchOnly, bool const &StripMultiArch = true) = 0; + static const char *BuildDepType(unsigned char const &Type); virtual bool Files(vector &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(); -- cgit v1.2.3 From 773e2c1fe5fd1a315ffaaf79f2f2e4a9e975649a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 9 Dec 2009 19:24:03 +0100 Subject: Refactor the cache iterators by using a common base class This should not change the public interface, but it removes the friend connection between the iterators and pkgcache as it is unused. --- apt-pkg/cacheiterators.h | 673 +++++++++++++++++++++-------------------------- apt-pkg/pkgcache.cc | 56 ++-- apt-pkg/pkgcache.h | 9 +- 3 files changed, 320 insertions(+), 418 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 28466cd40..1da5c6f02 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -1,6 +1,5 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: cacheiterators.h,v 1.18.2.1 2004/05/08 22:44:27 mdz Exp $ /* ###################################################################### Cache Iterators - Iterators for navigating the cache structure @@ -30,417 +29,333 @@ /*}}}*/ #ifndef PKGLIB_CACHEITERATORS_H #define PKGLIB_CACHEITERATORS_H - - +// abstract Iterator template /*{{{*/ +/* This template provides the very basic iterator methods we + need to have for doing some walk-over-the-cache magic, */ +template class pkgCache::Iterator { + __attribute__ ((deprecated)) void _dummy(); // FIXME: Who on earth uses this method ??? + + protected: + Str *S; + pkgCache *Owner; + + /** \brief Returns the Pointer for this struct in the owner + * The implementation of this method should be pretty short + * as it will only return the Pointer into the mmap stored + * in the owner but the name of this pointer is different for + * each stucture and we want to abstract here at least for the + * basic methods from the actual structure. + * \return Pointer to the first structure of this type + */ + virtual Str* OwnerPointer() const = 0; + + public: + // Iteration + virtual void operator ++(int) = 0; + virtual void operator ++() = 0; // Should be {operator ++(0);}; + inline bool end() const {return Owner == 0 || S == OwnerPointer();}; + + // Comparison + inline bool operator ==(const Itr &B) const {return S == B.S;}; + inline bool operator !=(const Itr &B) const {return S != B.S;}; + + // Accessors + inline Str *operator ->() {return S;}; + inline Str const *operator ->() const {return S;}; + inline operator Str *() {return S == OwnerPointer() ? 0 : S;}; + inline operator Str const *() const {return S == OwnerPointer() ? 0 : S;}; + inline Str const &operator *() const {return *S;}; + inline pkgCache *Cache() {return Owner;}; + + // Mixed stuff + inline void operator =(const Itr &B) {S = B.S; Owner = B.Owner;}; + inline bool IsGood() const { return S && Owner && ! end();}; + inline unsigned long Index() const {return S - OwnerPointer();}; + + // Constructors - look out for the variable assigning + inline Iterator() : S(0), Owner(0) {}; + inline Iterator(pkgCache &Owner,Str *T = 0) : S(T), Owner(&Owner) {}; +}; + /*}}}*/ // Package Iterator /*{{{*/ -class pkgCache::PkgIterator -{ - friend class pkgCache; - Package *Pkg; - pkgCache *Owner; - long HashIndex; - - protected: - - // This constructor is the 'begin' constructor, never use it. - inline PkgIterator(pkgCache &Owner) : Owner(&Owner), HashIndex(-1) - { - Pkg = Owner.PkgP; - operator ++(0); - }; - - public: - - enum OkState {NeedsNothing,NeedsUnpack,NeedsConfigure}; - - // Iteration - void operator ++(int); - inline void operator ++() {operator ++(0);}; - inline bool end() const {return Owner == 0 || Pkg == Owner->PkgP?true:false;}; - - // Comparison - inline bool operator ==(const PkgIterator &B) const {return Pkg == B.Pkg;}; - inline bool operator !=(const PkgIterator &B) const {return Pkg != B.Pkg;}; - - // Accessors - inline Package *operator ->() {return Pkg;}; - inline Package const *operator ->() const {return Pkg;}; - inline Package const &operator *() const {return *Pkg;}; - inline operator Package *() {return Pkg == Owner->PkgP?0:Pkg;}; - inline operator Package const *() const {return Pkg == Owner->PkgP?0:Pkg;}; - inline pkgCache *Cache() {return Owner;}; - - inline const char *Name() const {return Pkg->Name == 0?0:Owner->StrP + Pkg->Name;}; - inline const char *Section() const {return Pkg->Section == 0?0:Owner->StrP + Pkg->Section;}; - inline bool Purge() const {return Pkg->CurrentState == pkgCache::State::Purge || - (Pkg->CurrentVer == 0 && Pkg->CurrentState == pkgCache::State::NotInstalled);}; - inline VerIterator VersionList() const; - inline VerIterator CurrentVer() const; - inline DepIterator RevDependsList() const; - inline PrvIterator ProvidesList() const; - inline unsigned long Index() const {return Pkg - Owner->PkgP;}; - OkState State() const; - - //Nice printable representation - friend std::ostream& operator<<(std::ostream& out, pkgCache::PkgIterator Pkg); - - const char *CandVersion() const; - const char *CurVersion() const; - - // Constructors - inline PkgIterator(pkgCache &Owner,Package *Trg) : Pkg(Trg), Owner(&Owner), - HashIndex(0) - { - if (Pkg == 0) - Pkg = Owner.PkgP; - }; - inline PkgIterator() : Pkg(0), Owner(0), HashIndex(0) {}; +class pkgCache::PkgIterator: public Iterator { + long HashIndex; + + protected: + inline Package* OwnerPointer() const { + return Owner->PkgP; + }; + + public: + // This constructor is the 'begin' constructor, never use it. + inline PkgIterator(pkgCache &Owner) : Iterator(Owner), HashIndex(-1) { + S = OwnerPointer(); + operator ++(0); + }; + + virtual void operator ++(int); + virtual void operator ++() {operator ++(0);}; + + enum OkState {NeedsNothing,NeedsUnpack,NeedsConfigure}; + + // Accessors + inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;}; + inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;}; + inline bool Purge() const {return S->CurrentState == pkgCache::State::Purge || + (S->CurrentVer == 0 && S->CurrentState == pkgCache::State::NotInstalled);}; + + inline VerIterator VersionList() const; + inline VerIterator CurrentVer() const; + inline DepIterator RevDependsList() const; + inline PrvIterator ProvidesList() const; + OkState State() const; + const char *CandVersion() const; + const char *CurVersion() const; + + //Nice printable representation + friend std::ostream& operator <<(std::ostream& out, PkgIterator i); + + // Constructors + inline PkgIterator(pkgCache &Owner,Package *Trg) : Iterator(Owner, Trg), HashIndex(0) { + if (S == 0) + S = OwnerPointer(); + }; + inline PkgIterator() : Iterator(), HashIndex(0) {}; }; /*}}}*/ // Version Iterator /*{{{*/ -class pkgCache::VerIterator -{ - Version *Ver; - pkgCache *Owner; - - void _dummy(); - - public: - - // Iteration - void operator ++(int) {if (Ver != Owner->VerP) Ver = Owner->VerP + Ver->NextVer;}; - inline void operator ++() {operator ++(0);}; - inline bool end() const {return Owner == 0 || (Ver == Owner->VerP?true:false);}; - inline void operator =(const VerIterator &B) {Ver = B.Ver; Owner = B.Owner;}; - - // Comparison - inline bool operator ==(const VerIterator &B) const {return Ver == B.Ver;}; - inline bool operator !=(const VerIterator &B) const {return Ver != B.Ver;}; - int CompareVer(const VerIterator &B) const; - - // Testing - inline bool IsGood() const { return Ver && Owner && ! end();}; - - // Accessors - inline Version *operator ->() {return Ver;}; - inline Version const *operator ->() const {return Ver;}; - inline Version &operator *() {return *Ver;}; - inline Version const &operator *() const {return *Ver;}; - inline operator Version *() {return Ver == Owner->VerP?0:Ver;}; - inline operator Version const *() const {return Ver == Owner->VerP?0:Ver;}; - inline pkgCache *Cache() {return Owner;}; - - inline const char *VerStr() const {return Ver->VerStr == 0?0:Owner->StrP + Ver->VerStr;}; - inline const char *Section() const {return Ver->Section == 0?0:Owner->StrP + Ver->Section;}; - inline const char *Arch() const {return Ver->Arch == 0?0:Owner->StrP + Ver->Arch;}; - inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Ver->ParentPkg);}; - inline DescIterator DescriptionList() const; - DescIterator TranslatedDescription() const; - inline DepIterator DependsList() const; - inline PrvIterator ProvidesList() const; - inline VerFileIterator FileList() const; - inline unsigned long Index() const {return Ver - Owner->VerP;}; - bool Downloadable() const; - inline const char *PriorityType() {return Owner->Priority(Ver->Priority);}; - string RelStr(); - - bool Automatic() const; - VerFileIterator NewestFile() const; - - inline VerIterator() : Ver(0), Owner(0) {}; - inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Ver(Trg), - Owner(&Owner) - { - if (Ver == 0) - Ver = Owner.VerP; - }; +class pkgCache::VerIterator : public Iterator { + protected: + inline Version* OwnerPointer() const { + return Owner->VerP; + }; + + public: + // Iteration + void operator ++(int) {if (S != Owner->VerP) S = Owner->VerP + S->NextVer;}; + inline void operator ++() {operator ++(0);}; + + // Comparison + int CompareVer(const VerIterator &B) const; + + // Accessors + inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;}; + inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;}; + inline const char *Arch() const {return S->Arch == 0?0:Owner->StrP + S->Arch;}; + inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);}; + + inline DescIterator DescriptionList() const; + DescIterator TranslatedDescription() const; + inline DepIterator DependsList() const; + inline PrvIterator ProvidesList() const; + inline VerFileIterator FileList() const; + bool Downloadable() const; + inline const char *PriorityType() {return Owner->Priority(S->Priority);}; + string RelStr(); + + bool Automatic() const; + VerFileIterator NewestFile() const; + + inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator(Owner, Trg) { + if (S == 0) + S = OwnerPointer(); + }; + inline VerIterator() : Iterator() {}; }; /*}}}*/ // Description Iterator /*{{{*/ -class pkgCache::DescIterator -{ - Description *Desc; - pkgCache *Owner; - - void _dummy(); - - public: - - // Iteration - void operator ++(int) {if (Desc != Owner->DescP) Desc = Owner->DescP + Desc->NextDesc;}; - inline void operator ++() {operator ++(0);}; - inline bool end() const {return Owner == 0 || Desc == Owner->DescP?true:false;}; - inline void operator =(const DescIterator &B) {Desc = B.Desc; Owner = B.Owner;}; - - // Comparison - inline bool operator ==(const DescIterator &B) const {return Desc == B.Desc;}; - inline bool operator !=(const DescIterator &B) const {return Desc != B.Desc;}; - int CompareDesc(const DescIterator &B) const; - - // Accessors - inline Description *operator ->() {return Desc;}; - inline Description const *operator ->() const {return Desc;}; - inline Description &operator *() {return *Desc;}; - inline Description const &operator *() const {return *Desc;}; - inline operator Description *() {return Desc == Owner->DescP?0:Desc;}; - inline operator Description const *() const {return Desc == Owner->DescP?0:Desc;}; - inline pkgCache *Cache() {return Owner;}; - - inline const char *LanguageCode() const {return Owner->StrP + Desc->language_code;}; - inline const char *md5() const {return Owner->StrP + Desc->md5sum;}; - inline DescFileIterator FileList() const; - inline unsigned long Index() const {return Desc - Owner->DescP;}; - - inline DescIterator() : Desc(0), Owner(0) {}; - inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Desc(Trg), - Owner(&Owner) - { - if (Desc == 0) - Desc = Owner.DescP; - }; +class pkgCache::DescIterator : public Iterator { + protected: + inline Description* OwnerPointer() const { + return Owner->DescP; + }; + + public: + // Iteration + void operator ++(int) {if (S != Owner->DescP) S = Owner->DescP + S->NextDesc;}; + inline void operator ++() {operator ++(0);}; + + // Comparison + int CompareDesc(const DescIterator &B) const; + + // Accessors + inline const char *LanguageCode() const {return Owner->StrP + S->language_code;}; + inline const char *md5() const {return Owner->StrP + S->md5sum;}; + inline DescFileIterator FileList() const; + + inline DescIterator() : Iterator() {}; + inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Iterator(Owner, Trg) { + if (S == 0) + S = Owner.DescP; + }; }; /*}}}*/ // Dependency iterator /*{{{*/ -class pkgCache::DepIterator -{ - Dependency *Dep; - enum {DepVer, DepRev} Type; - pkgCache *Owner; - - void _dummy(); - - public: - - // Iteration - void operator ++(int) {if (Dep != Owner->DepP) Dep = Owner->DepP + - (Type == DepVer?Dep->NextDepends:Dep->NextRevDepends);}; - inline void operator ++() {operator ++(0);}; - inline bool end() const {return Owner == 0 || Dep == Owner->DepP?true:false;}; - - // Comparison - inline bool operator ==(const DepIterator &B) const {return Dep == B.Dep;}; - inline bool operator !=(const DepIterator &B) const {return Dep != B.Dep;}; - - // Accessors - inline Dependency *operator ->() {return Dep;}; - inline Dependency const *operator ->() const {return Dep;}; - inline Dependency &operator *() {return *Dep;}; - inline Dependency const &operator *() const {return *Dep;}; - inline operator Dependency *() {return Dep == Owner->DepP?0:Dep;}; - inline operator Dependency const *() const {return Dep == Owner->DepP?0:Dep;}; - inline pkgCache *Cache() {return Owner;}; - - inline const char *TargetVer() const {return Dep->Version == 0?0:Owner->StrP + Dep->Version;}; - inline PkgIterator TargetPkg() {return PkgIterator(*Owner,Owner->PkgP + Dep->Package);}; - inline PkgIterator SmartTargetPkg() {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;}; - inline VerIterator ParentVer() {return VerIterator(*Owner,Owner->VerP + Dep->ParentVer);}; - inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Dep->ParentVer].ParentPkg);}; - inline bool Reverse() {return Type == DepRev;}; - inline unsigned long Index() const {return Dep - Owner->DepP;}; - bool IsCritical(); - void GlobOr(DepIterator &Start,DepIterator &End); - Version **AllTargets(); - bool SmartTargetPkg(PkgIterator &Result); - inline const char *CompType() {return Owner->CompType(Dep->CompareOp);}; - inline const char *DepType() {return Owner->DepType(Dep->Type);}; - - inline DepIterator(pkgCache &Owner,Dependency *Trg,Version * = 0) : - Dep(Trg), Type(DepVer), Owner(&Owner) - { - if (Dep == 0) - Dep = Owner.DepP; - }; - inline DepIterator(pkgCache &Owner,Dependency *Trg,Package *) : - Dep(Trg), Type(DepRev), Owner(&Owner) - { - if (Dep == 0) - Dep = Owner.DepP; - }; - inline DepIterator() : Dep(0), Type(DepVer), Owner(0) {}; +class pkgCache::DepIterator : public Iterator { + enum {DepVer, DepRev} Type; + + protected: + inline Dependency* OwnerPointer() const { + return Owner->DepP; + }; + + public: + // Iteration + void operator ++(int) {if (S != Owner->DepP) S = Owner->DepP + + (Type == DepVer ? S->NextDepends : S->NextRevDepends);}; + inline void operator ++() {operator ++(0);}; + + // Accessors + inline const char *TargetVer() const {return S->Version == 0?0:Owner->StrP + S->Version;}; + inline PkgIterator TargetPkg() {return PkgIterator(*Owner,Owner->PkgP + S->Package);}; + inline PkgIterator SmartTargetPkg() {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;}; + inline VerIterator ParentVer() {return VerIterator(*Owner,Owner->VerP + S->ParentVer);}; + inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->ParentVer].ParentPkg);}; + inline bool Reverse() {return Type == DepRev;}; + bool IsCritical(); + void GlobOr(DepIterator &Start,DepIterator &End); + Version **AllTargets(); + bool SmartTargetPkg(PkgIterator &Result); + inline const char *CompType() {return Owner->CompType(S->CompareOp);}; + inline const char *DepType() {return Owner->DepType(S->Type);}; + + inline DepIterator(pkgCache &Owner, Dependency *Trg, Version* = 0) : + Iterator(Owner, Trg), Type(DepVer) { + if (S == 0) + S = Owner.DepP; + }; + inline DepIterator(pkgCache &Owner, Dependency *Trg, Package*) : + Iterator(Owner, Trg), Type(DepRev) { + if (S == 0) + S = Owner.DepP; + }; + inline DepIterator() : Iterator(), Type(DepVer) {}; }; /*}}}*/ // Provides iterator /*{{{*/ -class pkgCache::PrvIterator -{ - Provides *Prv; - enum {PrvVer, PrvPkg} Type; - pkgCache *Owner; - - void _dummy(); - - public: - - // Iteration - void operator ++(int) {if (Prv != Owner->ProvideP) Prv = Owner->ProvideP + - (Type == PrvVer?Prv->NextPkgProv:Prv->NextProvides);}; - inline void operator ++() {operator ++(0);}; - inline bool end() const {return Owner == 0 || Prv == Owner->ProvideP?true:false;}; - - // Comparison - inline bool operator ==(const PrvIterator &B) const {return Prv == B.Prv;}; - inline bool operator !=(const PrvIterator &B) const {return Prv != B.Prv;}; - - // Accessors - inline Provides *operator ->() {return Prv;}; - inline Provides const *operator ->() const {return Prv;}; - inline Provides &operator *() {return *Prv;}; - inline Provides const &operator *() const {return *Prv;}; - inline operator Provides *() {return Prv == Owner->ProvideP?0:Prv;}; - inline operator Provides const *() const {return Prv == Owner->ProvideP?0:Prv;}; - inline pkgCache *Cache() {return Owner;}; - - inline const char *Name() const {return Owner->StrP + Owner->PkgP[Prv->ParentPkg].Name;}; - inline const char *ProvideVersion() const {return Prv->ProvideVersion == 0?0:Owner->StrP + Prv->ProvideVersion;}; - inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Prv->ParentPkg);}; - inline VerIterator OwnerVer() {return VerIterator(*Owner,Owner->VerP + Prv->Version);}; - inline PkgIterator OwnerPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Prv->Version].ParentPkg);}; - inline unsigned long Index() const {return Prv - Owner->ProvideP;}; - - inline PrvIterator() : Prv(0), Type(PrvVer), Owner(0) {}; - - inline PrvIterator(pkgCache &Owner,Provides *Trg,Version *) : - Prv(Trg), Type(PrvVer), Owner(&Owner) - { - if (Prv == 0) - Prv = Owner.ProvideP; - }; - inline PrvIterator(pkgCache &Owner,Provides *Trg,Package *) : - Prv(Trg), Type(PrvPkg), Owner(&Owner) - { - if (Prv == 0) - Prv = Owner.ProvideP; - }; +class pkgCache::PrvIterator : public Iterator { + enum {PrvVer, PrvPkg} Type; + + protected: + inline Provides* OwnerPointer() const { + return Owner->ProvideP; + }; + + public: + // Iteration + void operator ++(int) {if (S != Owner->ProvideP) S = Owner->ProvideP + + (Type == PrvVer?S->NextPkgProv:S->NextProvides);}; + inline void operator ++() {operator ++(0);}; + + // Accessors + inline const char *Name() const {return Owner->StrP + Owner->PkgP[S->ParentPkg].Name;}; + inline const char *ProvideVersion() const {return S->ProvideVersion == 0?0:Owner->StrP + S->ProvideVersion;}; + inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);}; + inline VerIterator OwnerVer() {return VerIterator(*Owner,Owner->VerP + S->Version);}; + inline PkgIterator OwnerPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->Version].ParentPkg);}; + + inline PrvIterator() : Iterator(), Type(PrvVer) {}; + + inline PrvIterator(pkgCache &Owner, Provides *Trg, Version*) : + Iterator(Owner, Trg), Type(PrvVer) { + if (S == 0) + S = Owner.ProvideP; + }; + inline PrvIterator(pkgCache &Owner, Provides *Trg, Package*) : + Iterator(Owner, Trg), Type(PrvPkg) { + if (S == 0) + S = Owner.ProvideP; + }; }; /*}}}*/ // Package file /*{{{*/ -class pkgCache::PkgFileIterator -{ - pkgCache *Owner; - PackageFile *File; - - public: - - // Iteration - void operator ++(int) {if (File!= Owner->PkgFileP) File = Owner->PkgFileP + File->NextFile;}; - inline void operator ++() {operator ++(0);}; - inline bool end() const {return Owner == 0 || File == Owner->PkgFileP?true:false;}; - - // Comparison - inline bool operator ==(const PkgFileIterator &B) const {return File == B.File;}; - inline bool operator !=(const PkgFileIterator &B) const {return File != B.File;}; - - // Accessors - inline PackageFile *operator ->() {return File;}; - inline PackageFile const *operator ->() const {return File;}; - inline PackageFile const &operator *() const {return *File;}; - inline operator PackageFile *() {return File == Owner->PkgFileP?0:File;}; - inline operator PackageFile const *() const {return File == Owner->PkgFileP?0:File;}; - inline pkgCache *Cache() {return Owner;}; - - inline const char *FileName() const {return File->FileName == 0?0:Owner->StrP + File->FileName;}; - inline const char *Archive() const {return File->Archive == 0?0:Owner->StrP + File->Archive;}; - inline const char *Component() const {return File->Component == 0?0:Owner->StrP + File->Component;}; - inline const char *Version() const {return File->Version == 0?0:Owner->StrP + File->Version;}; - inline const char *Origin() const {return File->Origin == 0?0:Owner->StrP + File->Origin;}; - inline const char *Codename() const {return File->Codename ==0?0:Owner->StrP + File->Codename;}; - inline const char *Label() const {return File->Label == 0?0:Owner->StrP + File->Label;}; - inline const char *Site() const {return File->Site == 0?0:Owner->StrP + File->Site;}; - inline const char *Architecture() const {return File->Architecture == 0?0:Owner->StrP + File->Architecture;}; - inline const char *IndexType() const {return File->IndexType == 0?0:Owner->StrP + File->IndexType;}; - - inline unsigned long Index() const {return File - Owner->PkgFileP;}; - - bool IsOk(); - string RelStr(); - - // Constructors - inline PkgFileIterator() : Owner(0), File(0) {}; - inline PkgFileIterator(pkgCache &Owner) : Owner(&Owner), File(Owner.PkgFileP) {}; - inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Owner(&Owner), File(Trg) {}; +class pkgCache::PkgFileIterator : public Iterator { + protected: + inline PackageFile* OwnerPointer() const { + return Owner->PkgFileP; + }; + + public: + // Iteration + void operator ++(int) {if (S != Owner->PkgFileP) S = Owner->PkgFileP + S->NextFile;}; + inline void operator ++() {operator ++(0);}; + + // Accessors + inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;}; + inline const char *Archive() const {return S->Archive == 0?0:Owner->StrP + S->Archive;}; + inline const char *Component() const {return S->Component == 0?0:Owner->StrP + S->Component;}; + inline const char *Version() const {return S->Version == 0?0:Owner->StrP + S->Version;}; + inline const char *Origin() const {return S->Origin == 0?0:Owner->StrP + S->Origin;}; + inline const char *Codename() const {return S->Codename ==0?0:Owner->StrP + S->Codename;}; + inline const char *Label() const {return S->Label == 0?0:Owner->StrP + S->Label;}; + inline const char *Site() const {return S->Site == 0?0:Owner->StrP + S->Site;}; + inline const char *Architecture() const {return S->Architecture == 0?0:Owner->StrP + S->Architecture;}; + inline const char *IndexType() const {return S->IndexType == 0?0:Owner->StrP + S->IndexType;}; + + bool IsOk(); + string RelStr(); + + // Constructors + inline PkgFileIterator() : Iterator() {}; + inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg = 0) : Iterator(Owner, Trg) {}; }; /*}}}*/ // Version File /*{{{*/ -class pkgCache::VerFileIterator -{ - pkgCache *Owner; - VerFile *FileP; - - public: - - // Iteration - void operator ++(int) {if (FileP != Owner->VerFileP) FileP = Owner->VerFileP + FileP->NextFile;}; - inline void operator ++() {operator ++(0);}; - inline bool end() const {return Owner == 0 || FileP == Owner->VerFileP?true:false;}; - - // Comparison - inline bool operator ==(const VerFileIterator &B) const {return FileP == B.FileP;}; - inline bool operator !=(const VerFileIterator &B) const {return FileP != B.FileP;}; - - // Accessors - inline VerFile *operator ->() {return FileP;}; - inline VerFile const *operator ->() const {return FileP;}; - inline VerFile const &operator *() const {return *FileP;}; - inline operator VerFile *() {return FileP == Owner->VerFileP?0:FileP;}; - inline operator VerFile const *() const {return FileP == Owner->VerFileP?0:FileP;}; - inline pkgCache *Cache() {return Owner;}; - - inline PkgFileIterator File() const {return PkgFileIterator(*Owner,FileP->File + Owner->PkgFileP);}; - inline unsigned long Index() const {return FileP - Owner->VerFileP;}; - - inline VerFileIterator() : Owner(0), FileP(0) {}; - inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Owner(&Owner), FileP(Trg) {}; +class pkgCache::VerFileIterator : public pkgCache::Iterator { + protected: + inline VerFile* OwnerPointer() const { + return Owner->VerFileP; + }; + + public: + // Iteration + void operator ++(int) {if (S != Owner->VerFileP) S = Owner->VerFileP + S->NextFile;}; + inline void operator ++() {operator ++(0);}; + + // Accessors + inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);}; + + inline VerFileIterator() : Iterator() {}; + inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Iterator(Owner, Trg) {}; }; /*}}}*/ // Description File /*{{{*/ -class pkgCache::DescFileIterator -{ - pkgCache *Owner; - DescFile *FileP; - - public: - - // Iteration - void operator ++(int) {if (FileP != Owner->DescFileP) FileP = Owner->DescFileP + FileP->NextFile;}; - inline void operator ++() {operator ++(0);}; - inline bool end() const {return Owner == 0 || FileP == Owner->DescFileP?true:false;}; - - // Comparison - inline bool operator ==(const DescFileIterator &B) const {return FileP == B.FileP;}; - inline bool operator !=(const DescFileIterator &B) const {return FileP != B.FileP;}; - - // Accessors - inline DescFile *operator ->() {return FileP;}; - inline DescFile const *operator ->() const {return FileP;}; - inline DescFile const &operator *() const {return *FileP;}; - inline operator DescFile *() {return FileP == Owner->DescFileP?0:FileP;}; - inline operator DescFile const *() const {return FileP == Owner->DescFileP?0:FileP;}; - inline pkgCache *Cache() {return Owner;}; - - inline PkgFileIterator File() const {return PkgFileIterator(*Owner,FileP->File + Owner->PkgFileP);}; - inline unsigned long Index() const {return FileP - Owner->DescFileP;}; - - inline DescFileIterator() : Owner(0), FileP(0) {}; - inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Owner(&Owner), FileP(Trg) {}; +class pkgCache::DescFileIterator : public Iterator { + protected: + inline DescFile* OwnerPointer() const { + return Owner->DescFileP; + }; + + public: + // Iteration + void operator ++(int) {if (S != Owner->DescFileP) S = Owner->DescFileP + S->NextFile;}; + inline void operator ++() {operator ++(0);}; + + // Accessors + inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);}; + + inline DescFileIterator() : Iterator() {}; + inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Iterator(Owner, Trg) {}; }; /*}}}*/ // Inlined Begin functions cant be in the class because of order problems /*{{{*/ inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const - {return VerIterator(*Owner,Owner->VerP + Pkg->VersionList);}; + {return VerIterator(*Owner,Owner->VerP + S->VersionList);}; inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const - {return VerIterator(*Owner,Owner->VerP + Pkg->CurrentVer);}; + {return VerIterator(*Owner,Owner->VerP + S->CurrentVer);}; inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const - {return DepIterator(*Owner,Owner->DepP + Pkg->RevDepends,Pkg);}; + {return DepIterator(*Owner,Owner->DepP + S->RevDepends,S);}; inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const - {return PrvIterator(*Owner,Owner->ProvideP + Pkg->ProvidesList,Pkg);}; + {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);}; inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const - {return DescIterator(*Owner,Owner->DescP + Ver->DescriptionList);}; + {return DescIterator(*Owner,Owner->DescP + S->DescriptionList);}; inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const - {return PrvIterator(*Owner,Owner->ProvideP + Ver->ProvidesList,Ver);}; + {return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);}; inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const - {return DepIterator(*Owner,Owner->DepP + Ver->DependsList,Ver);}; + {return DepIterator(*Owner,Owner->DepP + S->DependsList,S);}; inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const - {return VerFileIterator(*Owner,Owner->VerFileP + Ver->FileList);}; + {return VerFileIterator(*Owner,Owner->VerFileP + S->FileList);}; inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const - {return DescFileIterator(*Owner,Owner->DescFileP + Desc->FileList);}; + {return DescFileIterator(*Owner,Owner->DescFileP + S->FileList);}; /*}}}*/ #endif diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 997ff51fe..2f8bde6f7 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -242,26 +242,20 @@ const char *pkgCache::Priority(unsigned char Prio) return 0; } /*}}}*/ -// Bases for iterator classes /*{{{*/ -void pkgCache::VerIterator::_dummy() {} -void pkgCache::DepIterator::_dummy() {} -void pkgCache::PrvIterator::_dummy() {} -void pkgCache::DescIterator::_dummy() {} - /*}}}*/ // PkgIterator::operator ++ - Postfix incr /*{{{*/ // --------------------------------------------------------------------- /* This will advance to the next logical package in the hash table. */ void pkgCache::PkgIterator::operator ++(int) { // Follow the current links - if (Pkg != Owner->PkgP) - Pkg = Owner->PkgP + Pkg->NextPackage; + if (S != Owner->PkgP) + S = Owner->PkgP + S->NextPackage; // Follow the hash table - while (Pkg == Owner->PkgP && (HashIndex+1) < (signed)_count(Owner->HeaderP->HashTable)) + while (S == Owner->PkgP && (HashIndex+1) < (signed)_count(Owner->HeaderP->HashTable)) { HashIndex++; - Pkg = Owner->PkgP + Owner->HeaderP->HashTable[HashIndex]; + S = Owner->PkgP + Owner->HeaderP->HashTable[HashIndex]; } }; /*}}}*/ @@ -270,12 +264,12 @@ void pkgCache::PkgIterator::operator ++(int) /* By this we mean if it is either cleanly installed or cleanly removed. */ pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const { - if (Pkg->InstState == pkgCache::State::ReInstReq || - Pkg->InstState == pkgCache::State::HoldReInstReq) + if (S->InstState == pkgCache::State::ReInstReq || + S->InstState == pkgCache::State::HoldReInstReq) return NeedsUnpack; - if (Pkg->CurrentState == pkgCache::State::UnPacked || - Pkg->CurrentState == pkgCache::State::HalfConfigured) + if (S->CurrentState == pkgCache::State::UnPacked || + S->CurrentState == pkgCache::State::HalfConfigured) // we leave triggers alone complettely. dpkg deals with // them in a hard-to-predict manner and if they get // resolved by dpkg before apt run dpkg --configure on @@ -284,8 +278,8 @@ pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const //Pkg->CurrentState == pkgCache::State::TriggersPending) return NeedsConfigure; - if (Pkg->CurrentState == pkgCache::State::HalfInstalled || - Pkg->InstState != pkgCache::State::Ok) + if (S->CurrentState == pkgCache::State::HalfInstalled || + S->InstState != pkgCache::State::Ok) return NeedsUnpack; return NeedsNothing; @@ -347,11 +341,11 @@ operator<<(ostream& out, pkgCache::PkgIterator Pkg) conflicts (including dpkg's Breaks fields). */ bool pkgCache::DepIterator::IsCritical() { - if (Dep->Type == pkgCache::Dep::Conflicts || - Dep->Type == pkgCache::Dep::DpkgBreaks || - Dep->Type == pkgCache::Dep::Obsoletes || - Dep->Type == pkgCache::Dep::Depends || - Dep->Type == pkgCache::Dep::PreDepends) + if (S->Type == pkgCache::Dep::Conflicts || + S->Type == pkgCache::Dep::DpkgBreaks || + S->Type == pkgCache::Dep::Obsoletes || + S->Type == pkgCache::Dep::Depends || + S->Type == pkgCache::Dep::PreDepends) return true; return false; } @@ -430,12 +424,12 @@ pkgCache::Version **pkgCache::DepIterator::AllTargets() // Walk along the actual package providing versions for (VerIterator I = DPkg.VersionList(); I.end() == false; I++) { - if (Owner->VS->CheckDep(I.VerStr(),Dep->CompareOp,TargetVer()) == false) + if (Owner->VS->CheckDep(I.VerStr(),S->CompareOp,TargetVer()) == false) continue; - if ((Dep->Type == pkgCache::Dep::Conflicts || - Dep->Type == pkgCache::Dep::DpkgBreaks || - Dep->Type == pkgCache::Dep::Obsoletes) && + if ((S->Type == pkgCache::Dep::Conflicts || + S->Type == pkgCache::Dep::DpkgBreaks || + S->Type == pkgCache::Dep::Obsoletes) && ParentPkg() == I.ParentPkg()) continue; @@ -447,12 +441,12 @@ pkgCache::Version **pkgCache::DepIterator::AllTargets() // Follow all provides for (PrvIterator I = DPkg.ProvidesList(); I.end() == false; I++) { - if (Owner->VS->CheckDep(I.ProvideVersion(),Dep->CompareOp,TargetVer()) == false) + if (Owner->VS->CheckDep(I.ProvideVersion(),S->CompareOp,TargetVer()) == false) continue; - if ((Dep->Type == pkgCache::Dep::Conflicts || - Dep->Type == pkgCache::Dep::DpkgBreaks || - Dep->Type == pkgCache::Dep::Obsoletes) && + if ((S->Type == pkgCache::Dep::Conflicts || + S->Type == pkgCache::Dep::DpkgBreaks || + S->Type == pkgCache::Dep::Obsoletes) && ParentPkg() == I.OwnerPkg()) continue; @@ -490,7 +484,7 @@ void pkgCache::DepIterator::GlobOr(DepIterator &Start,DepIterator &End) End = *this; for (bool LastOR = true; end() == false && LastOR == true;) { - LastOR = (Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; + LastOR = (S->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; (*this)++; if (LastOR == true) End = (*this); @@ -640,7 +634,7 @@ bool pkgCache::PkgFileIterator::IsOk() if (stat(FileName(),&Buf) != 0) return false; - if (Buf.st_size != (signed)File->Size || Buf.st_mtime != File->mtime) + if (Buf.st_size != (signed)S->Size || Buf.st_mtime != S->mtime) return false; return true; diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index e8a3e1064..359f8a590 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -43,6 +43,7 @@ class pkgCache /*{{{*/ struct DescFile; // Iterators + template class Iterator; class PkgIterator; class VerIterator; class DescIterator; @@ -51,14 +52,6 @@ class pkgCache /*{{{*/ class PkgFileIterator; class VerFileIterator; class DescFileIterator; - friend class PkgIterator; - friend class VerIterator; - friend class DescInterator; - friend class DepIterator; - friend class PrvIterator; - friend class PkgFileIterator; - friend class VerFileIterator; - friend class DescFileIterator; class Namespace; -- cgit v1.2.3 From 7d15572bc3124b15c043e38bdc3d90bcc94f108a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 19 Dec 2009 14:25:20 +0100 Subject: add optional gcc features as deprecated, unused and (un)likely --- apt-pkg/contrib/system.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/system.h b/apt-pkg/contrib/system.h index 7ec3d7feb..f68df6265 100644 --- a/apt-pkg/contrib/system.h +++ b/apt-pkg/contrib/system.h @@ -55,4 +55,26 @@ #define CLRFLAG(v,f) ((v) &=~FLAG(f)) #define CHKFLAG(v,f) ((v) & FLAG(f) ? true : false) +// some nice optional GNUC features +#if __GNUC__ >= 3 + #define __must_check __attribute__ ((warn_unused_result)) + #define __deprecated __attribute__ ((deprecated)) + /* likely() and unlikely() can be used to mark boolean expressions + as (not) likely true which will help the compiler to optimise */ + #define likely(x) __builtin_expect (!!(x), 1) + #define unlikely(x) __builtin_expect (!!(x), 0) +#else + #define __must_check /* no warn_unused_result */ + #define __deprecated /* no deprecated */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif + +// cold functions are unlikely() to be called +#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 + #define __cold __attribute__ ((__cold__)) +#else + #define __cold /* no cold marker */ +#endif + #endif -- cgit v1.2.3 From 201d1fa0d25deeda77c2570ee5342eaf18499699 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 19 Dec 2009 14:27:21 +0100 Subject: mark the Error/Warning method as __cold --- apt-pkg/contrib/error.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h index a3be6a575..d92e40e9c 100644 --- a/apt-pkg/contrib/error.h +++ b/apt-pkg/contrib/error.h @@ -52,6 +52,7 @@ #endif #include +#include using std::string; @@ -71,13 +72,13 @@ class GlobalError public: // Call to generate an error from a library call. - bool Errno(const char *Function,const char *Description,...) APT_MFORMAT2; - bool WarningE(const char *Function,const char *Description,...) APT_MFORMAT2; + bool Errno(const char *Function,const char *Description,...) APT_MFORMAT2 __cold; + bool WarningE(const char *Function,const char *Description,...) APT_MFORMAT2 __cold; /* A warning should be considered less severe than an error, and may be ignored by the client. */ - bool Error(const char *Description,...) APT_MFORMAT1; - bool Warning(const char *Description,...) APT_MFORMAT1; + bool Error(const char *Description,...) APT_MFORMAT1 __cold; + bool Warning(const char *Description,...) APT_MFORMAT1 __cold; // Simple accessors inline bool PendingError() {return PendingFlag;}; -- cgit v1.2.3 From 5bf15716398fdb767ca6249a0155219b88d7ae60 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 19 Dec 2009 16:25:56 +0100 Subject: Implement the first step toward Multi-Arch by setting up a Group infrastructor for packages. APT is now aware of the fact that a package A in architecture X can't satisfy a dependency on package A in architecture Y - to handle these packages are now identified by name and architecture, so different architectures of the same package are handled internally as completly different packages. This is great for pinning, dependency checking and in many other situations, but sometimes we need to know which archs are available for a given package: Here Groups come to our rescue! --- apt-pkg/cacheiterators.h | 37 ++++++++++++-- apt-pkg/deb/deblistparser.cc | 40 +++++++++++----- apt-pkg/deb/deblistparser.h | 1 + apt-pkg/pkgcache.cc | 112 ++++++++++++++++++++++++++++++++++++------- apt-pkg/pkgcache.h | 30 ++++++++++-- apt-pkg/pkgcachegen.cc | 111 +++++++++++++++++++++++++++++------------- apt-pkg/pkgcachegen.h | 6 ++- 7 files changed, 267 insertions(+), 70 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 1da5c6f02..35d3aa228 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -31,10 +31,8 @@ #define PKGLIB_CACHEITERATORS_H // abstract Iterator template /*{{{*/ /* This template provides the very basic iterator methods we - need to have for doing some walk-over-the-cache magic, */ + need to have for doing some walk-over-the-cache magic */ template class pkgCache::Iterator { - __attribute__ ((deprecated)) void _dummy(); // FIXME: Who on earth uses this method ??? - protected: Str *S; pkgCache *Owner; @@ -75,6 +73,35 @@ template class pkgCache::Iterator { // Constructors - look out for the variable assigning inline Iterator() : S(0), Owner(0) {}; inline Iterator(pkgCache &Owner,Str *T = 0) : S(T), Owner(&Owner) {}; +}; + /*}}}*/ +// Group Iterator /*{{{*/ +/* Packages with the same name are collected in a Group so someone only + interest in package names can iterate easily over the names, so the + different architectures can be treated as of the "same" package + (apt internally treat them as totally different packages) */ +class pkgCache::GrpIterator: public Iterator { + protected: + inline Group* OwnerPointer() const { + return Owner->GrpP; + }; + + public: + void operator ++(int) {if (S != Owner->GrpP) S = Owner->GrpP + S->Next;}; + virtual void operator ++() {operator ++(0);}; + + inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;}; + inline PkgIterator PackageList() const; + PkgIterator FindPkg(string Arch = "any"); + PkgIterator NextPkg(PkgIterator const &Pkg); + + // Constructors + inline GrpIterator(pkgCache &Owner, Group *Trg) : Iterator(Owner, Trg) { + if (S == 0) + S = OwnerPointer(); + }; + inline GrpIterator() : Iterator() {}; + }; /*}}}*/ // Package Iterator /*{{{*/ @@ -103,6 +130,8 @@ class pkgCache::PkgIterator: public Iterator { inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;}; inline bool Purge() const {return S->CurrentState == pkgCache::State::Purge || (S->CurrentVer == 0 && S->CurrentState == pkgCache::State::NotInstalled);}; + inline const char *Arch() const {return S->Arch == 0?0:Owner->StrP + S->Arch;}; + inline GrpIterator Group() const { return GrpIterator(*Owner, Owner->GrpP + S->Group);}; inline VerIterator VersionList() const; inline VerIterator CurrentVer() const; @@ -339,6 +368,8 @@ class pkgCache::DescFileIterator : public Iterator { }; /*}}}*/ // Inlined Begin functions cant be in the class because of order problems /*{{{*/ +inline pkgCache::PkgIterator pkgCache::GrpIterator::PackageList() const + {return PkgIterator(*Owner,Owner->PkgP + S->FirstPackage);}; inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const {return VerIterator(*Owner,Owner->VerP + S->VersionList);}; inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 25a1df3f9..fe68aec0b 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -53,12 +53,25 @@ unsigned long debListParser::UniqFindTagWrite(const char *Tag) // ListParser::Package - Return the package name /*{{{*/ // --------------------------------------------------------------------- /* This is to return the name of the package this section describes */ -string debListParser::Package() -{ - string Result = Section.FindS("Package"); - if (Result.empty() == true) - _error->Error("Encountered a section with no Package: header"); - return Result; +string debListParser::Package() { + string const Result = Section.FindS("Package"); + if(unlikely(Result.empty() == true)) + _error->Error("Encountered a section with no Package: header"); + return Result; +} + /*}}}*/ +// ListParser::Architecture - Return the package arch /*{{{*/ +// --------------------------------------------------------------------- +/* 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 */ +string debListParser::Architecture() { + string const Result = Section.FindS("Architecture"); + if (Result.empty() == true) + return Arch; + if (Result == "all") + return Arch; + return Result; } /*}}}*/ // ListParser::Version - Return the version string /*{{{*/ @@ -78,8 +91,10 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) { // Parse the section Ver->Section = UniqFindTagWrite("Section"); - Ver->Arch = UniqFindTagWrite("Architecture"); - + + // Parse the architecture + Ver->Arch = WriteUniqString(Architecture()); + // Archive Size Ver->Size = (unsigned)Section.FindI("Size"); @@ -537,6 +552,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver, return true; string Package; + string const pkgArch = Ver.Arch(); string Version; unsigned int Op; @@ -546,7 +562,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver, if (Start == 0) return _error->Error("Problem parsing dependency %s",Tag); - if (NewDepends(Ver,Package,Version,Op,Type) == false) + if (NewDepends(Ver,Package,pkgArch,Version,Op,Type) == false) return false; if (Start == Stop) break; @@ -619,6 +635,7 @@ bool debListParser::Step() if (Section.Find("Architecture",Start,Stop) == false) return true; + //FIXME: Accept different Architectures here if (stringcmp(Arch,Start,Stop) == 0) return true; @@ -641,8 +658,9 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI, if (Tags.Step(Section) == false) return false; - //mvo: I don't think we need to fill that in (it's unused since apt-0.6) - //FileI->Architecture = WriteUniqString(Arch); + // FIXME: Do we need it now for multi-arch? + // mvo: I don't think we need to fill that in (it's unused since apt-0.6) +// FileI->Architecture = WriteUniqString(Arch); // apt-secure does no longer download individual (per-section) Release // file. to provide Component pinning we use the section name now diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 1c709229f..5f91e073e 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -46,6 +46,7 @@ class debListParser : public pkgCacheGenerator::ListParser // These all operate against the current section virtual string Package(); + virtual string Architecture(); virtual string Version(); virtual bool NewVersion(pkgCache::VerIterator Ver); virtual string Description(); diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 2f8bde6f7..2b5f53f6f 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -79,7 +79,8 @@ pkgCache::Header::Header() StringList = 0; VerSysName = 0; Architecture = 0; - memset(HashTable,0,sizeof(HashTable)); + memset(PkgHashTable,0,sizeof(PkgHashTable)); + memset(GrpHashTable,0,sizeof(GrpHashTable)); memset(Pools,0,sizeof(Pools)); } /*}}}*/ @@ -118,6 +119,7 @@ bool pkgCache::ReMap() { // Apply the typecasts. HeaderP = (Header *)Map.Data(); + GrpP = (Group *)Map.Data(); PkgP = (Package *)Map.Data(); VerFileP = (VerFile *)Map.Data(); DescFileP = (DescFile *)Map.Data(); @@ -165,7 +167,7 @@ unsigned long pkgCache::sHash(const string &Str) const unsigned long Hash = 0; for (string::const_iterator I = Str.begin(); I != Str.end(); I++) Hash = 5*Hash + tolower_ascii(*I); - return Hash % _count(HeaderP->HashTable); + return Hash % _count(HeaderP->PkgHashTable); } unsigned long pkgCache::sHash(const char *Str) const @@ -173,24 +175,40 @@ unsigned long pkgCache::sHash(const char *Str) const unsigned long Hash = 0; for (const char *I = Str; *I != 0; I++) Hash = 5*Hash + tolower_ascii(*I); - return Hash % _count(HeaderP->HashTable); + return Hash % _count(HeaderP->PkgHashTable); } /*}}}*/ // Cache::FindPkg - Locate a package by name /*{{{*/ // --------------------------------------------------------------------- /* Returns 0 on error, pointer to the package otherwise */ -pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) -{ - // Look at the hash bucket - Package *Pkg = PkgP + HeaderP->HashTable[Hash(Name)]; - for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage) - { - if (Pkg->Name != 0 && StrP[Pkg->Name] == Name[0] && - stringcasecmp(Name,StrP + Pkg->Name) == 0) - return PkgIterator(*this,Pkg); - } - return PkgIterator(*this,0); +pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string Arch) { + /* We make a detour via the GrpIterator here as + on a multi-arch environment a group is easier to + find than a package (less entries in the buckets) */ + pkgCache::GrpIterator Grp = FindGrp(Name); + if (Grp.end() == true) + return PkgIterator(*this,0); + + return Grp.FindPkg(Arch); +} + /*}}}*/ +// Cache::FindGrp - Locate a group by name /*{{{*/ +// --------------------------------------------------------------------- +/* Returns End-Pointer on error, pointer to the group otherwise */ +pkgCache::GrpIterator pkgCache::FindGrp(const string &Name) { + if (unlikely(Name.empty() == true)) + return GrpIterator(*this,0); + + // Look at the hash bucket for the group + Group *Grp = GrpP + HeaderP->GrpHashTable[sHash(Name)]; + for (; Grp != GrpP; Grp = GrpP + Grp->Next) { + if (Grp->Name != 0 && StrP[Grp->Name] == Name[0] && + stringcasecmp(Name, StrP + Grp->Name) == 0) + return GrpIterator(*this, Grp); + } + + return GrpIterator(*this,0); } /*}}}*/ // Cache::CompTypeDeb - Return a string describing the compare type /*{{{*/ @@ -242,6 +260,68 @@ const char *pkgCache::Priority(unsigned char Prio) return 0; } /*}}}*/ +// GrpIterator::FindPkg - Locate a package by arch /*{{{*/ +// --------------------------------------------------------------------- +/* Returns an End-Pointer on error, pointer to the package otherwise */ +pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) { + if (unlikely(IsGood() == false || S->FirstPackage == 0)) + return PkgIterator(*Owner, 0); + + static string const myArch = _config->Find("APT::Architecture"); + /* Most of the time the package for our native architecture is + the one we add at first to the cache, but this would be the + last one we check, so we do it now. */ + if (Arch == "native" || Arch == myArch) { + Arch = myArch; + pkgCache::Package *Pkg = Owner->PkgP + S->LastPackage; + if (stringcasecmp(Arch, Owner->StrP + Pkg->Arch) == 0) + return PkgIterator(*Owner, Pkg); + } + + /* If we accept any package we simply return the "first" + package in this group (the last one added). */ + if (Arch == "any") + return PkgIterator(*Owner, Owner->PkgP + S->FirstPackage); + + /* Iterate over the list to find the matching arch + unfortunately this list includes "package noise" + (= different packages with same calculated hash), + so we need to check the name also */ + for (pkgCache::Package *Pkg = PackageList(); Pkg != Owner->PkgP; + Pkg = Owner->PkgP + Pkg->NextPackage) { + if (S->Name == Pkg->Name && + stringcasecmp(Arch, Owner->StrP + Pkg->Arch) == 0) + return PkgIterator(*Owner, Pkg); + if ((Owner->PkgP + S->LastPackage) == Pkg) + break; + } + + return PkgIterator(*Owner, 0); +} + /*}}}*/ +// GrpIterator::NextPkg - Locate the next package in the group /*{{{*/ +// --------------------------------------------------------------------- +/* Returns an End-Pointer on error, pointer to the package otherwise. + We can't simply ++ to the next as the list of packages includes + "package noise" (= packages with the same hash value but different name) */ +pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const &LastPkg) { + if (unlikely(IsGood() == false || S->FirstPackage == 0 || + LastPkg.end() == true)) + return PkgIterator(*Owner, 0); + + // Iterate over the list to find the next package + pkgCache::Package *Pkg = Owner->PkgP + LastPkg.Index(); + Pkg = Owner->PkgP + Pkg->NextPackage; + for (; Pkg != Owner->PkgP; Pkg = Owner->PkgP + Pkg->NextPackage) { + if (S->Name == Pkg->Name) + return PkgIterator(*Owner, Pkg); + if ((Owner->PkgP + S->LastPackage) == Pkg) + break; + } + + return PkgIterator(*Owner, 0); +} + /*}}}*/ // PkgIterator::operator ++ - Postfix incr /*{{{*/ // --------------------------------------------------------------------- /* This will advance to the next logical package in the hash table. */ @@ -252,10 +332,10 @@ void pkgCache::PkgIterator::operator ++(int) S = Owner->PkgP + S->NextPackage; // Follow the hash table - while (S == Owner->PkgP && (HashIndex+1) < (signed)_count(Owner->HeaderP->HashTable)) + while (S == Owner->PkgP && (HashIndex+1) < (signed)_count(Owner->HeaderP->PkgHashTable)) { HashIndex++; - S = Owner->PkgP + Owner->HeaderP->HashTable[HashIndex]; + S = Owner->PkgP + Owner->HeaderP->PkgHashTable[HashIndex]; } }; /*}}}*/ diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 359f8a590..b3d2752d2 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -32,6 +32,7 @@ class pkgCache /*{{{*/ public: // Cache element predeclarations struct Header; + struct Group; struct Package; struct PackageFile; struct Version; @@ -44,6 +45,7 @@ class pkgCache /*{{{*/ // Iterators template class Iterator; + class GrpIterator; class PkgIterator; class VerIterator; class DescIterator; @@ -97,6 +99,7 @@ class pkgCache /*{{{*/ // Pointers to the arrays of items Header *HeaderP; + Group *GrpP; Package *PkgP; VerFile *VerFileP; DescFile *DescFileP; @@ -121,7 +124,9 @@ class pkgCache /*{{{*/ const char *Priority(unsigned char Priority); // Accessors - PkgIterator FindPkg(const string &Name); + GrpIterator FindGrp(const string &Name); + PkgIterator FindPkg(const string &Name, string Arch = "native"); + Header &Head() {return *HeaderP;}; inline PkgIterator PkgBegin(); inline PkgIterator PkgEnd(); @@ -161,6 +166,7 @@ struct pkgCache::Header unsigned short DescFileSz; // Structure counts + unsigned long GroupCount; unsigned long PackageCount; unsigned long VersionCount; unsigned long DescriptionCount; @@ -180,22 +186,36 @@ struct pkgCache::Header /* Allocation pools, there should be one of these for each structure excluding the header */ - DynamicMMap::Pool Pools[8]; + DynamicMMap::Pool Pools[9]; - // Rapid package name lookup - map_ptrloc HashTable[2*1048]; + // Rapid package and group name lookup + // Notice: Increase only both table sizes as the + // hashmethod assume the size of the Pkg one + map_ptrloc PkgHashTable[2*1048]; + map_ptrloc GrpHashTable[2*1048]; bool CheckSizes(Header &Against) const; Header(); }; /*}}}*/ +struct pkgCache::Group { /*{{{*/ + map_ptrloc Name; // Stringtable + + // Linked List + map_ptrloc FirstPackage;// Package + map_ptrloc LastPackage; // Package + map_ptrloc Next; // Group +}; + /*}}}*/ struct pkgCache::Package /*{{{*/ { // Pointers map_ptrloc Name; // Stringtable + map_ptrloc Arch; // StringTable (StringItem) map_ptrloc VersionList; // Version map_ptrloc CurrentVer; // Version map_ptrloc Section; // StringTable (StringItem) + map_ptrloc Group; // Group the Package belongs to // Linked list map_ptrloc NextPackage; // Package @@ -254,7 +274,7 @@ struct pkgCache::Version /*{{{*/ map_ptrloc VerStr; // Stringtable map_ptrloc Section; // StringTable (StringItem) map_ptrloc Arch; // StringTable - + // Lists map_ptrloc FileList; // VerFile map_ptrloc NextVer; // Version diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 68180c702..c37f6f48e 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -108,12 +108,12 @@ bool pkgCacheGenerator::MergeList(ListParser &List, while (List.Step() == true) { // Get a pointer to the package structure - string PackageName = List.Package(); + string const PackageName = List.Package(); if (PackageName.empty() == true) return false; - + pkgCache::PkgIterator Pkg; - if (NewPackage(Pkg,PackageName) == false) + if (NewPackage(Pkg, PackageName, List.Architecture()) == false) return _error->Error(_("Error occurred while processing %s (NewPackage)"),PackageName.c_str()); Counter++; if (Counter % 100 == 0 && Progress != 0) @@ -323,33 +323,71 @@ bool pkgCacheGenerator::MergeFileProvides(ListParser &List) return true; } /*}}}*/ +// CacheGenerator::NewGroup - Add a new group /*{{{*/ +// --------------------------------------------------------------------- +/* This creates a new group structure and adds it to the hash table */ +bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name) { + Grp = Cache.FindGrp(Name); + if (Grp.end() == false) + return true; + + // Get a structure + unsigned long const Group = Map.Allocate(sizeof(pkgCache::Group)); + if (unlikely(Group == 0)) + return false; + + Grp = pkgCache::GrpIterator(Cache, Cache.GrpP + Group); + Grp->Name = Map.WriteString(Name); + if (unlikely(Grp->Name == 0)) + return false; + + // Insert it into the hash table + unsigned long const Hash = Cache.Hash(Name); + Grp->Next = Cache.HeaderP->GrpHashTable[Hash]; + Cache.HeaderP->GrpHashTable[Hash] = Group; + + Cache.HeaderP->GroupCount++; + + return true; +} + /*}}}*/ // CacheGenerator::NewPackage - Add a new package /*{{{*/ // --------------------------------------------------------------------- /* This creates a new package structure and adds it to the hash table */ -bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name) -{ - Pkg = Cache.FindPkg(Name); - if (Pkg.end() == false) - return true; +bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name, + const string &Arch) { + pkgCache::GrpIterator Grp; + if (unlikely(NewGroup(Grp, Name) == false)) + return false; + + Pkg = Grp.FindPkg(Arch); + if (Pkg.end() == false) + return true; // Get a structure - unsigned long Package = Map.Allocate(sizeof(pkgCache::Package)); - if (Package == 0) + unsigned long const Package = Map.Allocate(sizeof(pkgCache::Package)); + if (unlikely(Package == 0)) return false; - Pkg = pkgCache::PkgIterator(Cache,Cache.PkgP + Package); - + // Insert it into the hash table - unsigned long Hash = Cache.Hash(Name); - Pkg->NextPackage = Cache.HeaderP->HashTable[Hash]; - Cache.HeaderP->HashTable[Hash] = Package; - - // Set the name and the ID - Pkg->Name = Map.WriteString(Name); - if (Pkg->Name == 0) + unsigned long const Hash = Cache.Hash(Name); + Pkg->NextPackage = Cache.HeaderP->PkgHashTable[Hash]; + Cache.HeaderP->PkgHashTable[Hash] = Package; + + // remember the packages in the group + Grp->FirstPackage = Package; + if (Grp->LastPackage == 0) + Grp->LastPackage = Package; + + // Set the name, arch and the ID + Pkg->Name = Grp->Name; + Pkg->Group = Grp.Index(); + Pkg->Arch = WriteUniqString(Arch.c_str()); + if (unlikely(Pkg->Arch == 0)) return false; Pkg->ID = Cache.HeaderP->PackageCount++; - + return true; } /*}}}*/ @@ -474,6 +512,7 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, version and to the package that it is pointing to. */ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, const string &PackageName, + const string &Arch, const string &Version, unsigned int Op, unsigned int Type) @@ -481,8 +520,8 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, pkgCache &Cache = Owner->Cache; // Get a structure - unsigned long Dependency = Owner->Map.Allocate(sizeof(pkgCache::Dependency)); - if (Dependency == 0) + unsigned long const Dependency = Owner->Map.Allocate(sizeof(pkgCache::Dependency)); + if (unlikely(Dependency == 0)) return false; // Fill it in @@ -492,11 +531,17 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, Dep->CompareOp = Op; Dep->ID = Cache.HeaderP->DependsCount++; - // Locate the target package - pkgCache::PkgIterator Pkg; - if (Owner->NewPackage(Pkg,PackageName) == false) + pkgCache::GrpIterator Grp; + if (unlikely(Owner->NewGroup(Grp, PackageName) == false)) return false; - + + // Locate the target package + pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch); + if (Pkg.end() == true) { + if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false)) + return false; + } + // Probe the reverse dependency list for a version string that matches if (Version.empty() == false) { @@ -504,7 +549,7 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, if (I->Version != 0 && I.TargetVer() == Version) Dep->Version = I->Version;*/ if (Dep->Version == 0) - if ((Dep->Version = WriteString(Version)) == 0) + if (unlikely((Dep->Version = WriteString(Version)) == 0)) return false; } @@ -524,7 +569,7 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, } // Is it a file dependency? - if (PackageName[0] == '/') + if (unlikely(PackageName[0] == '/')) FoundFileDeps = true; Dep->NextDepends = *OldDepLast; @@ -544,12 +589,12 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver, pkgCache &Cache = Owner->Cache; // We do not add self referencing provides - if (Ver.ParentPkg().Name() == PackageName) + if (unlikely(Ver.ParentPkg().Name() == PackageName)) return true; // Get a structure - unsigned long Provides = Owner->Map.Allocate(sizeof(pkgCache::Provides)); - if (Provides == 0) + unsigned long const Provides = Owner->Map.Allocate(sizeof(pkgCache::Provides)); + if (unlikely(Provides == 0)) return false; Cache.HeaderP->ProvidesCount++; @@ -558,12 +603,12 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver, Prv->Version = Ver.Index(); Prv->NextPkgProv = Ver->ProvidesList; Ver->ProvidesList = Prv.Index(); - if (Version.empty() == false && (Prv->ProvideVersion = WriteString(Version)) == 0) + if (Version.empty() == false && unlikely((Prv->ProvideVersion = WriteString(Version)) == 0)) return false; // Locate the target package pkgCache::PkgIterator Pkg; - if (Owner->NewPackage(Pkg,PackageName) == false) + if (unlikely(Owner->NewPackage(Pkg,PackageName,string(Ver.Arch())) == false)) return false; // Link it to the package diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index 108b34207..4a2419b24 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -51,7 +51,8 @@ class pkgCacheGenerator /*{{{*/ // Flag file dependencies bool FoundFileDeps; - bool NewPackage(pkgCache::PkgIterator &Pkg,const string &PkgName); + bool NewGroup(pkgCache::GrpIterator &Grp,const string &Name); + bool NewPackage(pkgCache::PkgIterator &Pkg,const string &Name, const string &Arch); bool NewFileVer(pkgCache::VerIterator &Ver,ListParser &List); bool NewFileDesc(pkgCache::DescIterator &Desc,ListParser &List); unsigned long NewVersion(pkgCache::VerIterator &Ver,const string &VerStr,unsigned long Next); @@ -96,7 +97,7 @@ class pkgCacheGenerator::ListParser inline unsigned long WriteUniqString(const char *S,unsigned int Size) {return Owner->WriteUniqString(S,Size);}; inline unsigned long WriteString(const string &S) {return Owner->Map.WriteString(S);}; inline unsigned long WriteString(const char *S,unsigned int Size) {return Owner->Map.WriteString(S,Size);}; - bool NewDepends(pkgCache::VerIterator Ver,const string &Package, + bool NewDepends(pkgCache::VerIterator Ver,const string &Package, const string &Arch, const string &Version,unsigned int Op, unsigned int Type); bool NewProvides(pkgCache::VerIterator Ver,const string &Package, @@ -106,6 +107,7 @@ class pkgCacheGenerator::ListParser // These all operate against the current section virtual string Package() = 0; + virtual string Architecture() = 0; virtual string Version() = 0; virtual bool NewVersion(pkgCache::VerIterator Ver) = 0; virtual string Description() = 0; -- cgit v1.2.3 From 5dd4c8b811d9c7bc33e50254811f5bc0fc37f872 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 23 Dec 2009 12:38:19 +0100 Subject: 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). --- apt-pkg/aptconfiguration.cc | 25 ++++ apt-pkg/aptconfiguration.h | 16 +++ apt-pkg/cdrom.cc | 34 ++--- apt-pkg/clean.cc | 6 +- apt-pkg/contrib/strutl.cc | 17 +++ apt-pkg/contrib/strutl.h | 1 + apt-pkg/deb/debindexfile.cc | 15 ++- apt-pkg/deb/debindexfile.h | 4 +- apt-pkg/deb/deblistparser.cc | 57 ++++++--- apt-pkg/deb/deblistparser.h | 2 +- apt-pkg/deb/debmetaindex.cc | 292 +++++++++++++++++++++++++++---------------- apt-pkg/deb/debmetaindex.h | 28 +++-- apt-pkg/metaindex.h | 4 +- apt-pkg/pkgcache.cc | 8 +- apt-pkg/sourcelist.cc | 81 ++++++------ apt-pkg/sourcelist.h | 8 +- apt-pkg/versionmatch.cc | 8 +- apt-pkg/versionmatch.h | 2 + 18 files changed, 394 insertions(+), 214 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 899004d9f..1ec526646 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -223,4 +224,28 @@ std::vector const Configuration::getLanguages(bool const &All, return codes; } /*}}}*/ +// getArchitectures - Return Vector of prefered Architectures /*{{{*/ +std::vector const Configuration::getArchitectures(bool const &Cached) { + using std::string; + + std::vector 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 const archs = getArchitectures(true); + return (std::find(archs.begin(), archs.end(), Arch) != archs.end()); +} + /*}}}*/ } diff --git a/apt-pkg/aptconfiguration.h b/apt-pkg/aptconfiguration.h index f2f04a39b..b6650e20c 100644 --- a/apt-pkg/aptconfiguration.h +++ b/apt-pkg/aptconfiguration.h @@ -66,6 +66,22 @@ public: /*{{{*/ std::vector 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 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); + /*}}}*/ }; /*}}}*/ diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc index 72d8e4d41..271bca409 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -6,6 +6,8 @@ #include #include #include +#include + #include #include #include @@ -216,33 +218,23 @@ int pkgCdrom::Score(string Path) /* Here we drop everything that is not this machines arch */ bool pkgCdrom::DropBinaryArch(vector &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; diff --git a/apt-pkg/clean.cc b/apt-pkg/clean.cc index 0d1dfbf74..629afd7cf 100644 --- a/apt-pkg/clean.cc +++ b/apt-pkg/clean.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -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 diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 4c05f2df8..bed51881f 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/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 ExplodeString(string const &haystack, char const &split) { + string::const_iterator start = haystack.begin(); + string::const_iterator end = start; + vector 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 /*{{{*/ // --------------------------------------------------------------------- /* */ diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index 2b2e147fb..3bdb65b4d 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 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 5beb83665..73d72c729 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/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()); diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h index c0e8d7d8e..766e8b214 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/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 diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index fe68aec0b..b57eca813 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/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(); } diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 5f91e073e..cba4f8e5d 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/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 diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 8f28f053b..eb01a0156 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -8,9 +8,11 @@ #include #include +#include + 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_iterator I = SectionEntries.begin(); - I != SectionEntries.end(); I++) - delete *I; +debReleaseIndex::~debReleaseIndex() { + for (map >::const_iterator A = ArchEntries.begin(); + A != ArchEntries.end(); ++A) + for (vector::const_iterator S = A->second.begin(); + S != A->second.end(); ++S) + delete *S; } -vector * debReleaseIndex::ComputeIndexTargets() const -{ - vector * IndexTargets = new vector ; - for (vector ::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 * debReleaseIndex::ComputeIndexTargets() const { + vector * IndexTargets = new vector ; + + map >::const_iterator const src = ArchEntries.find("source"); + if (src != ArchEntries.end()) { + vector const SectionEntries = src->second; + for (vector::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 >::const_iterator a = ArchEntries.begin(); + a != ArchEntries.end(); ++a) { + if (a->first == "source") + continue; + for (vector ::const_iterator I = a->second.begin(); + I != a->second.end(); ++I) { + 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 const lang = APT::Configuration::getLanguages(true); - for (vector::const_iterator I = SectionEntries.begin(); - I != SectionEntries.end(); I++) { - - if((*I)->IsSrc) - continue; - - for (vector::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 const lang = APT::Configuration::getLanguages(true); + map > sections; + for (map >::const_iterator a = ArchEntries.begin(); + a != ArchEntries.end(); ++a) { + if (a->first == "source") + continue; + for (vector::const_iterator I = a->second.begin(); + I != a->second.end(); I++) + sections[(*I)->Section].insert(lang.begin(), lang.end()); + } + + for (map >::const_iterator s = sections.begin(); + s != sections.end(); ++s) + for (set::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 *debReleaseIndex::GetIndexFiles() -{ - if (Indexes != NULL) - return Indexes; - - Indexes = new vector ; - std::vector const lang = APT::Configuration::getLanguages(true); - for (vector::const_iterator I = SectionEntries.begin(); - I != SectionEntries.end(); I++) { - if ((*I)->IsSrc) - Indexes->push_back(new debSourcesIndex (URI, Dist, (*I)->Section, IsTrusted())); - else - { - Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted())); - - for (vector::const_iterator l = lang.begin(); - l != lang.end(); l++) - Indexes->push_back(new debTranslationsIndex(URI,Dist,(*I)->Section,(*l).c_str())); - } - } +vector *debReleaseIndex::GetIndexFiles() { + if (Indexes != NULL) + return Indexes; + + Indexes = new vector ; + map >::const_iterator const src = ArchEntries.find("source"); + if (src != ArchEntries.end()) { + vector const SectionEntries = src->second; + for (vector::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 const lang = APT::Configuration::getLanguages(true); + map > sections; + for (map >::const_iterator a = ArchEntries.begin(); + a != ArchEntries.end(); ++a) { + if (a->first == "source") + continue; + for (vector::const_iterator I = a->second.begin(); + I != a->second.end(); I++) { + Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted(), a->first)); + sections[(*I)->Section].insert(lang.begin(), lang.end()); + } + } + + for (map >::const_iterator s = sections.begin(); + s != sections.end(); ++s) + for (set::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 const &Archs, const debSectionEntry *Entry) { + for (vector::const_iterator a = Archs.begin(); + a != Archs.end(); ++a) + ArchEntries[*a].push_back(new debSectionEntry(Entry->Section, Entry->IsSrc)); + delete Entry; } -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 >::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 &List,string URI, - string Dist,string Section, - bool IsSrc) const + bool CreateItemInternal(vector &List, string const &URI, + string const &Dist, string const &Section, + bool const &IsSrc, map const &Options) const { - for (vector::const_iterator I = List.begin(); + map::const_iterator const arch = Options.find("arch"); + vector const Archs = + (arch != Options.end()) ? ExplodeString(arch->second) : + APT::Configuration::getArchitectures(); + + for (vector::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 &List,string URI, - string Dist,string Section) const + bool CreateItem(vector &List, string const &URI, + string const &Dist, string const &Section, + std::map const &Options) const { - return CreateItemInternal(List, URI, Dist, Section, false); + return CreateItemInternal(List, URI, Dist, Section, false, Options); } debSLTypeDeb() @@ -294,10 +367,11 @@ class debSLTypeDebSrc : public debSLTypeDebian { public: - bool CreateItem(vector &List,string URI, - string Dist,string Section) const + bool CreateItem(vector &List, string const &URI, + string const &Dist, string const &Section, + std::map const &Options) const { - return CreateItemInternal(List, URI, Dist, Section, true); + return CreateItemInternal(List, URI, Dist, Section, true, Options); } debSLTypeDebSrc() diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h index 8e6a1463b..360fa5419 100644 --- a/apt-pkg/deb/debmetaindex.h +++ b/apt-pkg/deb/debmetaindex.h @@ -5,40 +5,44 @@ #include #include +#include + 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 SectionEntries; + std::map > 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 * 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 *GetIndexFiles(); virtual bool IsTrusted() const; + void PushSectionEntry(vector const &Archs, const debSectionEntry *Entry); + void PushSectionEntry(string const &Arch, const debSectionEntry *Entry); void PushSectionEntry(const debSectionEntry *Entry); }; diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h index 779b6ab14..1d2140799 100644 --- a/apt-pkg/metaindex.h +++ b/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 *GetIndexFiles() = 0; virtual bool IsTrusted() const = 0; diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 2b5f53f6f..c945c59bf 100644 --- a/apt-pkg/pkgcache.cc +++ b/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; } /*}}}*/ diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 4b3abe918..6b7a299d6 100644 --- a/apt-pkg/sourcelist.cc +++ b/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 &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 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 &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 &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_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; diff --git a/apt-pkg/sourcelist.h b/apt-pkg/sourcelist.h index b9e4389ed..e15314a5e 100644 --- a/apt-pkg/sourcelist.h +++ b/apt-pkg/sourcelist.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -57,9 +58,10 @@ class pkgSourceList bool FixupURI(string &URI) const; virtual bool ParseLine(vector &List, const char *Buffer, - unsigned long CurLine,string File) const; - virtual bool CreateItem(vector &List,string URI, - string Dist,string Section) const = 0; + unsigned long const &CurLine,string const &File) const; + virtual bool CreateItem(vector &List,string const &URI, + string const &Dist,string const &Section, + std::map const &Options) const = 0; Type(); virtual ~Type() {}; }; diff --git a/apt-pkg/versionmatch.cc b/apt-pkg/versionmatch.cc index b4d1d4696..e5f0fafd2 100644 --- a/apt-pkg/versionmatch.cc +++ b/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; } diff --git a/apt-pkg/versionmatch.h b/apt-pkg/versionmatch.h index a8f3c84ac..a8da072ae 100644 --- a/apt-pkg/versionmatch.h +++ b/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 -- cgit v1.2.3 From 25396fb06350344996a20d05423562f08a4165db Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 27 Dec 2009 19:39:47 +0100 Subject: Split ListParser::NewDepends into two methods to use these new method for creating the dependencies needed for our groups: For now for all groups only one package can be installed at the same time which conflicts with each other packages in the group. The exceptions are architecture all package. Also, the Multi-Arch field is now parsed, but not used for now. --- apt-pkg/cacheiterators.h | 14 ++++- apt-pkg/deb/deblistparser.cc | 24 ++++++++ apt-pkg/pkgcache.cc | 27 +++++++++ apt-pkg/pkgcache.h | 12 +++- apt-pkg/pkgcachegen.cc | 133 ++++++++++++++++++++++++++++++++----------- apt-pkg/pkgcachegen.h | 6 +- 6 files changed, 176 insertions(+), 40 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 35d3aa228..33d2ed6be 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -81,13 +81,21 @@ template class pkgCache::Iterator { different architectures can be treated as of the "same" package (apt internally treat them as totally different packages) */ class pkgCache::GrpIterator: public Iterator { + long HashIndex; + protected: inline Group* OwnerPointer() const { return Owner->GrpP; }; public: - void operator ++(int) {if (S != Owner->GrpP) S = Owner->GrpP + S->Next;}; + // This constructor is the 'begin' constructor, never use it. + inline GrpIterator(pkgCache &Owner) : Iterator(Owner), HashIndex(-1) { + S = OwnerPointer(); + operator ++(0); + }; + + virtual void operator ++(int); virtual void operator ++() {operator ++(0);}; inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;}; @@ -96,11 +104,11 @@ class pkgCache::GrpIterator: public Iterator { PkgIterator NextPkg(PkgIterator const &Pkg); // Constructors - inline GrpIterator(pkgCache &Owner, Group *Trg) : Iterator(Owner, Trg) { + inline GrpIterator(pkgCache &Owner, Group *Trg) : Iterator(Owner, Trg), HashIndex(0) { if (S == 0) S = OwnerPointer(); }; - inline GrpIterator() : Iterator() {}; + inline GrpIterator() : Iterator(), HashIndex(0) {}; }; /*}}}*/ diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index b57eca813..f683de423 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -104,6 +104,30 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) // Parse the architecture Ver->Arch = WriteUniqString(Architecture()); + // Parse multi-arch + if (Section.FindS("Architecture") == "all") + /* Arch all packages can't have a Multi-Arch field, + but we need a special treatment for them nonetheless */ + Ver->MultiArch = pkgCache::Version::All; + else + { + string const MultiArch = Section.FindS("Multi-Arch"); + if (MultiArch.empty() == true) + Ver->MultiArch = pkgCache::Version::None; + else if (MultiArch == "same") + Ver->MultiArch = pkgCache::Version::Same; + else if (MultiArch == "foreign") + Ver->MultiArch = pkgCache::Version::Foreign; + else if (MultiArch == "allowed") + Ver->MultiArch = pkgCache::Version::Allowed; + else + { + _error->Warning("Unknown Multi-Arch type »%s« for package »%s«", + MultiArch.c_str(), Section.FindS("Package").c_str()); + Ver->MultiArch = pkgCache::Version::None; + } + } + // Archive Size Ver->Size = (unsigned)Section.FindI("Size"); diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index c945c59bf..1e4c7edb3 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -182,6 +182,16 @@ unsigned long pkgCache::sHash(const char *Str) const // Cache::FindPkg - Locate a package by name /*{{{*/ // --------------------------------------------------------------------- /* Returns 0 on error, pointer to the package otherwise */ +pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) { + size_t const found = Name.find(':'); + if (found == string::npos) + return FindPkg(Name, "native"); + return FindPkg(Name.substr(0, found), Name.substr(found+1, string::npos)); +} + /*}}}*/ +// Cache::FindPkg - Locate a package by name /*{{{*/ +// --------------------------------------------------------------------- +/* Returns 0 on error, pointer to the package otherwise */ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string Arch) { /* We make a detour via the GrpIterator here as on a multi-arch environment a group is easier to @@ -322,6 +332,23 @@ pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const return PkgIterator(*Owner, 0); } /*}}}*/ +// GrpIterator::operator ++ - Postfix incr /*{{{*/ +// --------------------------------------------------------------------- +/* This will advance to the next logical group in the hash table. */ +void pkgCache::GrpIterator::operator ++(int) +{ + // Follow the current links + if (S != Owner->GrpP) + S = Owner->GrpP + S->Next; + + // Follow the hash table + while (S == Owner->GrpP && (HashIndex+1) < (signed)_count(Owner->HeaderP->GrpHashTable)) + { + HashIndex++; + S = Owner->GrpP + Owner->HeaderP->GrpHashTable[HashIndex]; + } +}; + /*}}}*/ // PkgIterator::operator ++ - Postfix incr /*{{{*/ // --------------------------------------------------------------------- /* This will advance to the next logical package in the hash table. */ diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index b3d2752d2..5f50001d0 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -125,9 +125,12 @@ class pkgCache /*{{{*/ // Accessors GrpIterator FindGrp(const string &Name); - PkgIterator FindPkg(const string &Name, string Arch = "native"); + PkgIterator FindPkg(const string &Name); + PkgIterator FindPkg(const string &Name, string Arch); Header &Head() {return *HeaderP;}; + inline GrpIterator GrpBegin(); + inline GrpIterator GrpEnd(); inline PkgIterator PkgBegin(); inline PkgIterator PkgEnd(); inline PkgFileIterator FileBegin(); @@ -274,7 +277,8 @@ struct pkgCache::Version /*{{{*/ map_ptrloc VerStr; // Stringtable map_ptrloc Section; // StringTable (StringItem) map_ptrloc Arch; // StringTable - + enum {None, All, Foreign, Same, Allowed} MultiArch; + // Lists map_ptrloc FileList; // VerFile map_ptrloc NextVer; // Version @@ -337,6 +341,10 @@ struct pkgCache::StringItem /*{{{*/ /*}}}*/ #include +inline pkgCache::GrpIterator pkgCache::GrpBegin() + {return GrpIterator(*this);}; +inline pkgCache::GrpIterator pkgCache::GrpEnd() + {return GrpIterator(*this,GrpP);}; inline pkgCache::PkgIterator pkgCache::PkgBegin() {return PkgIterator(*this);}; inline pkgCache::PkgIterator pkgCache::PkgEnd() diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index c37f6f48e..2a4a30349 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,7 @@ typedef vector::iterator FileIterator; // CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/ // --------------------------------------------------------------------- -/* We set the diry flag and make sure that is written to the disk */ +/* We set the dirty flag and make sure that is written to the disk */ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) : Map(*pMap), Cache(pMap,false), Progress(Prog), FoundFileDeps(0) @@ -506,21 +507,58 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, return Description; } /*}}}*/ -// ListParser::NewDepends - Create a dependency element /*{{{*/ +// CacheGenerator::FinishCache - do various finish operations /*{{{*/ +// --------------------------------------------------------------------- +/* This prepares the Cache for delivery */ +bool pkgCacheGenerator::FinishCache(OpProgress &Progress) { + // FIXME: add progress reporting for this operation + // Do we have different architectures in your groups ? + vector archs = APT::Configuration::getArchitectures(); + if (archs.size() > 1) { + // Create Conflicts in between the group + for (pkgCache::GrpIterator G = GetCache().GrpBegin(); G.end() != true; G++) { + string const PkgName = G.Name(); + for (pkgCache::PkgIterator P = G.PackageList(); P.end() != true; P = G.NextPkg(P)) { + for (pkgCache::VerIterator V = P.VersionList(); V.end() != true; V++) { + // Arch all packages are "co-installable" + if (V->MultiArch == pkgCache::Version::All) + continue; + string const Arch = V.Arch(); + map_ptrloc *OldDepLast = NULL; + for (vector::const_iterator A = archs.begin(); A != archs.end(); ++A) { + if (*A == Arch) + continue; + /* We allow only one installed arch at the time + per group, therefore each group member conflicts + with all other group members */ + pkgCache::PkgIterator D = G.FindPkg(*A); + if (D.end() == true) + continue; + // Conflicts: ${self}:other + NewDepends(D, V, "", + pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts, + OldDepLast); + } + } + } + } + } + return true; +} + /*}}}*/ +// CacheGenerator::NewDepends - Create a dependency element /*{{{*/ // --------------------------------------------------------------------- /* This creates a dependency element in the tree. It is linked to the version and to the package that it is pointing to. */ -bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, - const string &PackageName, - const string &Arch, - const string &Version, - unsigned int Op, - unsigned int Type) +bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, + pkgCache::VerIterator &Ver, + string const &Version, + unsigned int const &Op, + unsigned int const &Type, + map_ptrloc *OldDepLast) { - pkgCache &Cache = Owner->Cache; - // Get a structure - unsigned long const Dependency = Owner->Map.Allocate(sizeof(pkgCache::Dependency)); + unsigned long const Dependency = Map.Allocate(sizeof(pkgCache::Dependency)); if (unlikely(Dependency == 0)) return false; @@ -530,17 +568,6 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, Dep->Type = Type; Dep->CompareOp = Op; Dep->ID = Cache.HeaderP->DependsCount++; - - pkgCache::GrpIterator Grp; - if (unlikely(Owner->NewGroup(Grp, PackageName) == false)) - return false; - - // Locate the target package - pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch); - if (Pkg.end() == true) { - if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false)) - return false; - } // Probe the reverse dependency list for a version string that matches if (Version.empty() == false) @@ -549,29 +576,23 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, if (I->Version != 0 && I.TargetVer() == Version) Dep->Version = I->Version;*/ if (Dep->Version == 0) - if (unlikely((Dep->Version = WriteString(Version)) == 0)) + if (unlikely((Dep->Version = Map.WriteString(Version)) == 0)) return false; } - + // Link it to the package Dep->Package = Pkg.Index(); Dep->NextRevDepends = Pkg->RevDepends; Pkg->RevDepends = Dep.Index(); - - /* Link it to the version (at the end of the list) - Caching the old end point speeds up generation substantially */ - if (OldDepVer != Ver) + + // Do we know where to link the Dependency to? + if (OldDepLast == NULL) { OldDepLast = &Ver->DependsList; for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++) OldDepLast = &D->NextDepends; - OldDepVer = Ver; } - // Is it a file dependency? - if (unlikely(PackageName[0] == '/')) - FoundFileDeps = true; - Dep->NextDepends = *OldDepLast; *OldDepLast = Dep.Index(); OldDepLast = &Dep->NextDepends; @@ -579,6 +600,41 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, return true; } /*}}}*/ +// ListParser::NewDepends - Create the environment for a new dependency /*{{{*/ +// --------------------------------------------------------------------- +/* This creates a Group and the Package to link this dependency to if + needed and handles also the caching of the old endpoint */ +bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, + const string &PackageName, + const string &Arch, + const string &Version, + unsigned int Op, + unsigned int Type) +{ + pkgCache::GrpIterator Grp; + if (unlikely(Owner->NewGroup(Grp, PackageName) == false)) + return false; + + // Locate the target package + pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch); + if (Pkg.end() == true) { + if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false)) + return false; + } + + // Is it a file dependency? + if (unlikely(PackageName[0] == '/')) + FoundFileDeps = true; + + /* Caching the old end point speeds up generation substantially */ + if (OldDepVer != Ver) { + OldDepLast = NULL; + OldDepVer = Ver; + } + + return Owner->NewDepends(Pkg, Ver, Version, Op, Type, OldDepLast); +} + /*}}}*/ // ListParser::NewProvides - Create a Provides element /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -925,6 +981,9 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, if (BuildCache(Gen,Progress,CurrentSize,TotalSize, Files.begin()+EndOfSource,Files.end()) == false) return false; + + // FIXME: move me to a better place + Gen.FinishCache(Progress); } else { @@ -965,6 +1024,9 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, if (BuildCache(Gen,Progress,CurrentSize,TotalSize, Files.begin()+EndOfSource,Files.end()) == false) return false; + + // FIXME: move me to a better place + Gen.FinishCache(Progress); } if (_error->PendingError() == true) @@ -1010,7 +1072,10 @@ bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap) if (BuildCache(Gen,Progress,CurrentSize,TotalSize, Files.begin()+EndOfSource,Files.end()) == false) return false; - + + // FIXME: move me to a better place + Gen.FinishCache(Progress); + if (_error->PendingError() == true) return false; *OutMap = Map.UnGuard(); diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index 4a2419b24..53f09b991 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -55,6 +55,9 @@ class pkgCacheGenerator /*{{{*/ bool NewPackage(pkgCache::PkgIterator &Pkg,const string &Name, const string &Arch); bool NewFileVer(pkgCache::VerIterator &Ver,ListParser &List); bool NewFileDesc(pkgCache::DescIterator &Desc,ListParser &List); + bool NewDepends(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver, + string const &Version, unsigned int const &Op, + unsigned int const &Type, map_ptrloc *OldDepLast); unsigned long NewVersion(pkgCache::VerIterator &Ver,const string &VerStr,unsigned long Next); map_ptrloc NewDescription(pkgCache::DescIterator &Desc,const string &Lang,const MD5SumValue &md5sum,map_ptrloc Next); @@ -73,7 +76,8 @@ class pkgCacheGenerator /*{{{*/ bool HasFileDeps() {return FoundFileDeps;}; bool MergeFileProvides(ListParser &List); - + bool FinishCache(OpProgress &Progress); + pkgCacheGenerator(DynamicMMap *Map,OpProgress *Progress); ~pkgCacheGenerator(); }; -- cgit v1.2.3 From 02dceb31f77f0812c76334a1758631c7cf9544a3 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 2 Jan 2010 00:22:31 +0100 Subject: add configuration PDiffs::Limit-options (FileLimit and SizeLimit) to not download too many or too big patches (Closes: #554349) --- apt-pkg/acquire-item.cc | 62 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 13 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 10e80eb56..4f0abbb91 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -219,19 +219,19 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ if(TF.Step(Tags) == true) { - string local_sha1; bool found = false; DiffInfo d; string size; - string tmp = Tags.FindS("SHA1-Current"); + string const tmp = Tags.FindS("SHA1-Current"); std::stringstream ss(tmp); - ss >> ServerSha1; + ss >> ServerSha1 >> size; + unsigned long const ServerSize = atol(size.c_str()); FileFd fd(CurrentPackagesFile, FileFd::ReadOnly); SHA1Summation SHA1; SHA1.AddFD(fd.Fd(), fd.Size()); - local_sha1 = string(SHA1.Result()); + string const local_sha1 = SHA1.Result(); if(local_sha1 == ServerSha1) { @@ -248,20 +248,56 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ std::clog << "SHA1-Current: " << ServerSha1 << std::endl; // check the historie and see what patches we need - string history = Tags.FindS("SHA1-History"); + string const history = Tags.FindS("SHA1-History"); std::stringstream hist(history); - while(hist >> d.sha1 >> size >> d.file) + while(hist >> d.sha1 >> size >> d.file) { - d.size = atoi(size.c_str()); // read until the first match is found + // from that point on, we probably need all diffs if(d.sha1 == local_sha1) found=true; - // from that point on, we probably need all diffs - if(found) + else if (found == false) + continue; + + if(Debug) + std::clog << "Need to get diff: " << d.file << std::endl; + available_patches.push_back(d); + } + + if (available_patches.empty() == false) + { + // patching with too many files is rather slow compared to a fast download + unsigned long const fileLimit = _config->FindI("Acquire::PDiffs::FileLimit", 0); + if (fileLimit != 0 && fileLimit < available_patches.size()) + { + if (Debug) + std::clog << "Need " << available_patches.size() << " diffs (Limit is " << fileLimit + << ") so fallback to complete download" << std::endl; + return false; + } + + // see if the patches are too big + found = false; // it was true and it will be true again at the end + d = *available_patches.begin(); + string const firstPatch = d.file; + unsigned long patchesSize = 0; + std::stringstream patches(Tags.FindS("SHA1-Patches")); + while(patches >> d.sha1 >> size >> d.file) + { + if (firstPatch == d.file) + found = true; + else if (found == false) + continue; + + patchesSize += atol(size.c_str()); + } + unsigned long const sizeLimit = ServerSize * _config->FindI("Acquire::PDiffs::SizeLimit", 100); + if (sizeLimit > 0 && (sizeLimit/100) < patchesSize) { - if(Debug) - std::clog << "Need to get diff: " << d.file << std::endl; - available_patches.push_back(d); + if (Debug) + std::clog << "Need " << patchesSize << " bytes (Limit is " << sizeLimit/100 + << ") so fallback to complete download" << std::endl; + return false; } } } @@ -270,7 +306,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ if(found) { // queue the diffs - string::size_type last_space = Description.rfind(" "); + string::size_type const last_space = Description.rfind(" "); if(last_space != string::npos) Description.erase(last_space, Description.size()-last_space); new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc, -- cgit v1.2.3 From 749eb4cf0416b1eb7a950bbfce2937f04ab0b6ab Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 2 Jan 2010 17:19:07 +0100 Subject: =?UTF-8?q?Fix=20the=20following=20gcc-4.5=20buildfailure=20in=20p?= =?UTF-8?q?kgcache.cc=20by=20following=20the=20suggestion:=20pkgcache.cc:?= =?UTF-8?q?=20In=20member=20function=20=E2=80=98const=20char*=20pkgCache::?= =?UTF-8?q?PkgIterator::CandVersion()=20const=E2=80=99:=20pkgcache.cc:301:?= =?UTF-8?q?51:=20error:=20cannot=20call=20constructor=20=E2=80=98pkgPolicy?= =?UTF-8?q?::pkgPolicy=E2=80=99=20directly=20pkgcache.cc:301:51:=20note:?= =?UTF-8?q?=20for=20a=20function-style=20cast,=20remove=20the=20redundant?= =?UTF-8?q?=20=E2=80=98::pkgPolicy=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apt-pkg/pkgcache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 997ff51fe..eb7e4957a 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -298,7 +298,7 @@ const char * pkgCache::PkgIterator::CandVersion() const { //TargetVer is empty, so don't use it. - VerIterator version = pkgPolicy::pkgPolicy(Owner).GetCandidateVer(*this); + VerIterator version = pkgPolicy(Owner).GetCandidateVer(*this); if (version.IsGood()) return version.VerStr(); return 0; -- cgit v1.2.3 From e7001c62dbd3b2a2d5b857c782dd855d525c2524 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 2 Jan 2010 17:38:04 +0100 Subject: fix another mistake spotted by lintian: I: apt: spelling-error-in-binary ./usr/lib/libapt-pkg-libc6.9-6.so.4.8.0 Alot A lot --- apt-pkg/indexcopy.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc index 57c9f95ca..53eb11172 100644 --- a/apt-pkg/indexcopy.cc +++ b/apt-pkg/indexcopy.cc @@ -275,7 +275,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector &List, _error->Warning("No valid records were found."); if (NotFound + WrongSize > 10) - _error->Warning("Alot of entries were discarded, something may be wrong.\n"); + _error->Warning("A lot of entries were discarded, something may be wrong.\n"); return true; @@ -847,7 +847,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/ _error->Warning("No valid records were found."); if (NotFound + WrongSize > 10) - _error->Warning("Alot of entries were discarded, something may be wrong.\n"); + _error->Warning("A lot of entries were discarded, something may be wrong.\n"); return true; -- cgit v1.2.3 From 52643bec17df4e36a9bd27183886e2c0c7a8ebd8 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 3 Jan 2010 19:37:34 +0100 Subject: Add a GetListOfFilesInDir() helper method which replaces the old code copies used to load the various parts-files --- apt-pkg/contrib/configuration.cc | 39 ++------------------------------- apt-pkg/contrib/fileutl.cc | 47 ++++++++++++++++++++++++++++++++++++++++ apt-pkg/contrib/fileutl.h | 3 +++ apt-pkg/policy.cc | 37 +++---------------------------- apt-pkg/sourcelist.cc | 43 +----------------------------------- 5 files changed, 56 insertions(+), 113 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc index ff49ce857..89aa854a3 100644 --- a/apt-pkg/contrib/configuration.cc +++ b/apt-pkg/contrib/configuration.cc @@ -22,14 +22,8 @@ #include #include -#include #include #include - -#include -#include -#include -#include using namespace std; /*}}}*/ @@ -837,37 +831,8 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio /* */ bool ReadConfigDir(Configuration &Conf,const string &Dir,bool const &AsSectional, unsigned const &Depth) -{ - DIR *D = opendir(Dir.c_str()); - if (D == 0) - return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str()); - - vector List; - - for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D)) - { - if (Ent->d_name[0] == '.') - continue; - - // Skip bad file names ala run-parts - const char *C = Ent->d_name; - for (; *C != 0; C++) - if (isalpha(*C) == 0 && isdigit(*C) == 0 && *C != '_' && *C != '-') - break; - if (*C != 0) - continue; - - // Make sure it is a file and not something else - string File = flCombine(Dir,Ent->d_name); - struct stat St; - if (stat(File.c_str(),&St) != 0 || S_ISREG(St.st_mode) == 0) - continue; - - List.push_back(File); - } - closedir(D); - - sort(List.begin(),List.end()); +{ + vector const List = GetListOfFilesInDir(Dir, "", true); // Read the files for (vector::const_iterator I = List.begin(); I != List.end(); I++) diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 4240d9f49..3adab8fe7 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -34,9 +34,11 @@ #include #include #include +#include #include #include #include +#include /*}}}*/ using namespace std; @@ -195,6 +197,51 @@ bool FileExists(string File) return true; } /*}}}*/ +// GetListOfFilesInDir - returns a vector of files in the given dir /*{{{*/ +// --------------------------------------------------------------------- +/* If an extension is given only files with this extension are included + in the returned vector, otherwise every "normal" file is included. */ +std::vector GetListOfFilesInDir(string const &Dir, string const &Ext, + bool const &SortList) { + std::vector List; + DIR *D = opendir(Dir.c_str()); + if (D == 0) { + _error->Errno("opendir",_("Unable to read %s"),Dir.c_str()); + return List; + } + + for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D)) { + if (Ent->d_name[0] == '.') + continue; + + if (Ext.empty() == false && flExtension(Ent->d_name) != Ext) + continue; + + // Skip bad file names ala run-parts + const char *C = Ent->d_name; + for (; *C != 0; ++C) + if (isalpha(*C) == 0 && isdigit(*C) == 0 + && *C != '_' && *C != '-' && *C != '.') + break; + + if (*C != 0) + continue; + + // Make sure it is a file and not something else + string const File = flCombine(Dir,Ent->d_name); + struct stat St; + if (stat(File.c_str(),&St) != 0 || S_ISREG(St.st_mode) == 0) + continue; + + List.push_back(File); + } + closedir(D); + + if (SortList == true) + std::sort(List.begin(),List.end()); + return List; +} + /*}}}*/ // SafeGetCWD - This is a safer getcwd that returns a dynamic string /*{{{*/ // --------------------------------------------------------------------- /* We return / on failure. */ diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 73b5ea3be..3cbf67fbb 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -23,6 +23,7 @@ #include +#include using std::string; @@ -81,6 +82,8 @@ bool RunScripts(const char *Cnf); bool CopyFile(FileFd &From,FileFd &To); int GetLock(string File,bool Errors = true); bool FileExists(string File); +std::vector GetListOfFilesInDir(string const &Dir, string const &Ext, + bool const &SortList); string SafeGetCWD(); void SetCloseExec(int Fd,bool Close); void SetNonBlock(int Fd,bool Block); diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index 81fdb0431..393181b6d 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -27,14 +27,12 @@ #include #include #include +#include #include #include - + #include -#include -#include -#include #include #include /*}}}*/ @@ -282,36 +280,7 @@ bool ReadPinDir(pkgPolicy &Plcy,string Dir) return true; } - DIR *D = opendir(Dir.c_str()); - if (D == 0) - return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str()); - - vector List; - - for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D)) - { - if (Ent->d_name[0] == '.') - continue; - - // Skip bad file names ala run-parts - const char *C = Ent->d_name; - for (; *C != 0; C++) - if (isalpha(*C) == 0 && isdigit(*C) == 0 && *C != '_' && *C != '-') - break; - if (*C != 0) - continue; - - // Make sure it is a file and not something else - string File = flCombine(Dir,Ent->d_name); - struct stat St; - if (stat(File.c_str(),&St) != 0 || S_ISREG(St.st_mode) == 0) - continue; - - List.push_back(File); - } - closedir(D); - - sort(List.begin(),List.end()); + vector const List = GetListOfFilesInDir(Dir, "", true); // Read the files for (vector::const_iterator I = List.begin(); I != List.end(); I++) diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 4b3abe918..929259961 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -17,13 +17,6 @@ #include #include - -// CNC:2003-03-03 - This is needed for ReadDir stuff. -#include -#include -#include -#include -#include /*}}}*/ using namespace std; @@ -322,41 +315,7 @@ bool pkgSourceList::GetIndexes(pkgAcquire *Owner, bool GetAll) const /* */ bool pkgSourceList::ReadSourceDir(string Dir) { - DIR *D = opendir(Dir.c_str()); - if (D == 0) - return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str()); - - vector List; - - for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D)) - { - if (Ent->d_name[0] == '.') - continue; - - // CNC:2003-12-02 Only accept .list files as valid sourceparts - if (flExtension(Ent->d_name) != "list") - continue; - - // Skip bad file names ala run-parts - const char *C = Ent->d_name; - for (; *C != 0; C++) - if (isalpha(*C) == 0 && isdigit(*C) == 0 - && *C != '_' && *C != '-' && *C != '.') - break; - if (*C != 0) - continue; - - // Make sure it is a file and not something else - string File = flCombine(Dir,Ent->d_name); - struct stat St; - if (stat(File.c_str(),&St) != 0 || S_ISREG(St.st_mode) == 0) - continue; - - List.push_back(File); - } - closedir(D); - - sort(List.begin(),List.end()); + vector const List = GetListOfFilesInDir(Dir, "list", true); // Read the files for (vector::const_iterator I = List.begin(); I != List.end(); I++) -- cgit v1.2.3 From e29a6bb14dcc004d174ad8502b76623139fbee06 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 16 Jan 2010 23:09:42 +0100 Subject: Fix the newly introduced method GetListOfFilesInDir to not accept every file if no extension is enforced (= restore old behaviour). (Closes: #565213) This commit includes also: * apt-pkg/policy.cc: - accept also partfiles with "pref" file extension as valid * apt-pkg/contrib/configuration.cc: - accept also partfiles with "conf" file extension as valid * doc/apt.conf.5.xml: - reorder description and split out syntax - add partfile name convention (Closes: #558348) * doc/apt_preferences.conf.5.xml: - describe partfile name convention also here And a lovely test application of course. --- apt-pkg/contrib/configuration.cc | 2 +- apt-pkg/contrib/fileutl.cc | 84 +++++++++++++++++++++++++++++++++++++--- apt-pkg/contrib/fileutl.h | 5 +++ apt-pkg/policy.cc | 2 +- 4 files changed, 86 insertions(+), 7 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc index 80b089fac..7588b041c 100644 --- a/apt-pkg/contrib/configuration.cc +++ b/apt-pkg/contrib/configuration.cc @@ -832,7 +832,7 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio bool ReadConfigDir(Configuration &Conf,const string &Dir, bool const &AsSectional, unsigned const &Depth) { - vector const List = GetListOfFilesInDir(Dir, "", true); + vector const List = GetListOfFilesInDir(Dir, "conf", true, true); // Read the files for (vector::const_iterator I = List.begin(); I != List.end(); I++) diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index cce8a4512..da32983f1 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -202,8 +202,37 @@ bool FileExists(string File) /* If an extension is given only files with this extension are included in the returned vector, otherwise every "normal" file is included. */ std::vector GetListOfFilesInDir(string const &Dir, string const &Ext, - bool const &SortList) + bool const &SortList) { + return GetListOfFilesInDir(Dir, Ext, SortList, false); +} +std::vector GetListOfFilesInDir(string const &Dir, string const &Ext, + bool const &SortList, bool const &AllowNoExt) +{ + std::vector ext; + ext.reserve(2); + if (Ext.empty() == false) + ext.push_back(Ext); + if (AllowNoExt == true && ext.empty() == false) + ext.push_back(""); + return GetListOfFilesInDir(Dir, ext, SortList); +} +std::vector GetListOfFilesInDir(string const &Dir, std::vector const &Ext, + bool const &SortList) +{ + // Attention debuggers: need to be set with the environment config file! + bool const Debug = _config->FindB("Debug::GetListOfFilesInDir", false); + if (Debug == true) + { + std::clog << "Accept in " << Dir << " only files with the following " << Ext.size() << " extensions:" << std::endl; + if (Ext.empty() == true) + std::clog << "\tNO extension" << std::endl; + else + for (std::vector::const_iterator e = Ext.begin(); + e != Ext.end(); ++e) + std::clog << '\t' << (e->empty() == true ? "NO" : *e) << " extension" << std::endl; + } + std::vector List; DIR *D = opendir(Dir.c_str()); if (D == 0) @@ -214,28 +243,73 @@ std::vector GetListOfFilesInDir(string const &Dir, string const &Ext, for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D)) { + // skip "hidden" files if (Ent->d_name[0] == '.') continue; - if (Ext.empty() == false && flExtension(Ent->d_name) != Ext) - continue; + // check for accepted extension: + // no extension given -> periods are bad as hell! + // extensions given -> "" extension allows no extension + if (Ext.empty() == false) + { + string d_ext = flExtension(Ent->d_name); + if (d_ext == Ent->d_name) // no extension + { + if (std::find(Ext.begin(), Ext.end(), "") == Ext.end()) + { + if (Debug == true) + std::clog << "Bad file: " << Ent->d_name << " → no extension" << std::endl; + continue; + } + } + else if (std::find(Ext.begin(), Ext.end(), d_ext) == Ext.end()) + { + if (Debug == true) + std::clog << "Bad file: " << Ent->d_name << " → bad extension »" << flExtension(Ent->d_name) << "«" << std::endl; + continue; + } + } - // Skip bad file names ala run-parts + // Skip bad filenames ala run-parts const char *C = Ent->d_name; for (; *C != 0; ++C) if (isalpha(*C) == 0 && isdigit(*C) == 0 - && *C != '_' && *C != '-' && *C != '.') + && *C != '_' && *C != '-') { + // no required extension -> dot is a bad character + if (*C == '.' && Ext.empty() == false) + continue; break; + } + // we don't reach the end of the name -> bad character included if (*C != 0) + { + if (Debug == true) + std::clog << "Bad file: " << Ent->d_name << " → bad character »" + << *C << "« in filename (period allowed: " << (Ext.empty() ? "no" : "yes") << ")" << std::endl; continue; + } + + // skip filenames which end with a period. These are never valid + if (*(C - 1) == '.') + { + if (Debug == true) + std::clog << "Bad file: " << Ent->d_name << " → Period as last character" << std::endl; + continue; + } // Make sure it is a file and not something else string const File = flCombine(Dir,Ent->d_name); struct stat St; if (stat(File.c_str(),&St) != 0 || S_ISREG(St.st_mode) == 0) + { + if (Debug == true) + std::clog << "Bad file: " << Ent->d_name << " → stat says not a good file" << std::endl; continue; + } + if (Debug == true) + std::clog << "Accept file: " << Ent->d_name << " in " << Dir << std::endl; List.push_back(File); } closedir(D); diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 2807c29d9..85a94898c 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -82,8 +82,13 @@ bool RunScripts(const char *Cnf); bool CopyFile(FileFd &From,FileFd &To); int GetLock(string File,bool Errors = true); bool FileExists(string File); +// FIXME: next ABI-Break: merge the two method-headers std::vector GetListOfFilesInDir(string const &Dir, string const &Ext, bool const &SortList); +std::vector GetListOfFilesInDir(string const &Dir, string const &Ext, + bool const &SortList, bool const &AllowNoExt); +std::vector GetListOfFilesInDir(string const &Dir, std::vector const &Ext, + bool const &SortList); string SafeGetCWD(); void SetCloseExec(int Fd,bool Close); void SetNonBlock(int Fd,bool Block); diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index 393181b6d..f9901bc9a 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -280,7 +280,7 @@ bool ReadPinDir(pkgPolicy &Plcy,string Dir) return true; } - vector const List = GetListOfFilesInDir(Dir, "", true); + vector const List = GetListOfFilesInDir(Dir, "pref", true, true); // Read the files for (vector::const_iterator I = List.begin(); I != List.end(); I++) -- cgit v1.2.3 From 3ad676a1420f65b4de3d1742c09f6e7e3966652c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 19 Jan 2010 13:08:01 +0100 Subject: * apt-pkg/deb/dpkgpm.cc: - don't segfault if term.log file can't be opened. Thanks Sam Brightman for the patch! (Closes: #475770) --- apt-pkg/deb/dpkgpm.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index d1a275a47..565f01b84 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -561,15 +561,16 @@ bool pkgDPkgPM::OpenLog() if (!logfile_name.empty()) { term_out = fopen(logfile_name.c_str(),"a"); + if (term_out == NULL) + return _error->WarningE(_("Could not open file '%s'"), logfile_name.c_str()); + chmod(logfile_name.c_str(), 0600); // output current time char outstr[200]; time_t t = time(NULL); struct tm *tmp = localtime(&t); strftime(outstr, sizeof(outstr), "%F %T", tmp); - fprintf(term_out, "\nLog started: "); - fprintf(term_out, "%s", outstr); - fprintf(term_out, "\n"); + fprintf(term_out, "\nLog started: %s\n", outstr); } return true; } -- cgit v1.2.3 From d16aade9b781538ad5d6d79eda7b69ff075aad85 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 20 Jan 2010 14:18:12 +0100 Subject: * apt-pkg/contrib/strutl.cc: - fix malloc asseration fail with ja_JP.eucJP locale in apt-cache search. Thanks Kusanagi Kouichi! (Closes: #548884) --- apt-pkg/contrib/strutl.cc | 49 +++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 4c05f2df8..2913fbf44 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -43,9 +43,10 @@ bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest) { iconv_t cd; const char *inbuf; - char *inptr, *outbuf, *outptr; - size_t insize, outsize; - + char *inptr, *outbuf; + size_t insize, bufsize; + dest->clear(); + cd = iconv_open(codeset, "UTF-8"); if (cd == (iconv_t)(-1)) { // Something went wrong @@ -55,33 +56,49 @@ bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest) else perror("iconv_open"); - // Clean the destination string - *dest = ""; - return false; } - insize = outsize = orig.size(); + insize = bufsize = orig.size(); inbuf = orig.data(); inptr = (char *)inbuf; - outbuf = new char[insize+1]; - outptr = outbuf; + outbuf = new char[bufsize]; + size_t lastError = -1; while (insize != 0) { + char *outptr = outbuf; + size_t outsize = bufsize; size_t const err = iconv(cd, &inptr, &insize, &outptr, &outsize); + dest->append(outbuf, outptr - outbuf); if (err == (size_t)(-1)) { - insize--; - outsize++; - inptr++; - *outptr = '?'; - outptr++; + switch (errno) + { + case EILSEQ: + insize--; + inptr++; + // replace a series of unknown multibytes with a single "?" + if (lastError != insize) { + lastError = insize - 1; + dest->append("?"); + } + break; + case EINVAL: + insize = 0; + break; + case E2BIG: + if (outptr == outbuf) + { + bufsize *= 2; + delete[] outbuf; + outbuf = new char[bufsize]; + } + break; + } } } - *outptr = '\0'; - *dest = outbuf; delete[] outbuf; iconv_close(cd); -- cgit v1.2.3 From 3d43e5390d83a95b08d09e8b811523f2d99a092c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 22 Jan 2010 08:27:20 +0100 Subject: add a few gcc helpers, including [un]likely() and __deprecated --- apt-pkg/contrib/system.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/system.h b/apt-pkg/contrib/system.h index 7ec3d7feb..b57093b93 100644 --- a/apt-pkg/contrib/system.h +++ b/apt-pkg/contrib/system.h @@ -55,4 +55,26 @@ #define CLRFLAG(v,f) ((v) &=~FLAG(f)) #define CHKFLAG(v,f) ((v) & FLAG(f) ? true : false) +// some nice optional GNUC features +#if __GNUC__ >= 3 + #define __must_check __attribute__ ((warn_unused_result)) + #define __deprecated __attribute__ ((deprecated)) + /* likely() and unlikely() can be used to mark boolean expressions + as (not) likely true which will help the compiler to optimise */ + #define likely(x) __builtin_expect (!!(x), 1) + #define unlikely(x) __builtin_expect (!!(x), 0) +#else + #define __must_check /* no warn_unused_result */ + #define __deprecated /* no deprecated */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif + +// cold functions are unlikely() to be called +#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 + #define __cold __attribute__ ((__cold__)) +#else + #define __cold /* no cold marker */ +#endif + #endif -- cgit v1.2.3 From 2a75daa6be0647be3cc405f0ad9ed4f9f8638429 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 22 Jan 2010 08:38:09 +0100 Subject: mark the Error methods as __cold --- apt-pkg/contrib/error.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h index a3be6a575..86aa9eca3 100644 --- a/apt-pkg/contrib/error.h +++ b/apt-pkg/contrib/error.h @@ -53,6 +53,8 @@ #include +#include + using std::string; class GlobalError @@ -71,13 +73,13 @@ class GlobalError public: // Call to generate an error from a library call. - bool Errno(const char *Function,const char *Description,...) APT_MFORMAT2; - bool WarningE(const char *Function,const char *Description,...) APT_MFORMAT2; + bool Errno(const char *Function,const char *Description,...) APT_MFORMAT2 __cold; + bool WarningE(const char *Function,const char *Description,...) APT_MFORMAT2 __cold; /* A warning should be considered less severe than an error, and may be ignored by the client. */ - bool Error(const char *Description,...) APT_MFORMAT1; - bool Warning(const char *Description,...) APT_MFORMAT1; + bool Error(const char *Description,...) APT_MFORMAT1 __cold; + bool Warning(const char *Description,...) APT_MFORMAT1 __cold; // Simple accessors inline bool PendingError() {return PendingFlag;}; -- cgit v1.2.3 From 5c0d3668dd2b6852812502f33d64b1644c2b137a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 30 Jan 2010 22:19:57 +0100 Subject: * apt-pkg/contrib/macros.h: - move the header system.h with a new name to the public domain, to be able to use it in other headers (Closes: #567662) --- apt-pkg/contrib/error.h | 2 +- apt-pkg/contrib/hashes.cc | 4 +-- apt-pkg/contrib/macros.h | 79 +++++++++++++++++++++++++++++++++++++++++++ apt-pkg/contrib/md5.cc | 3 +- apt-pkg/contrib/sha1.cc | 2 +- apt-pkg/contrib/system.h | 80 -------------------------------------------- apt-pkg/deb/deblistparser.cc | 3 +- apt-pkg/makefile | 6 ++-- apt-pkg/pkgcache.cc | 2 +- apt-pkg/pkgcachegen.cc | 2 +- 10 files changed, 89 insertions(+), 94 deletions(-) create mode 100644 apt-pkg/contrib/macros.h delete mode 100644 apt-pkg/contrib/system.h (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h index 86aa9eca3..31413b2dc 100644 --- a/apt-pkg/contrib/error.h +++ b/apt-pkg/contrib/error.h @@ -53,7 +53,7 @@ #include -#include +#include using std::string; diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index b43771ea7..985d89d90 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -14,9 +14,9 @@ #include #include #include - +#include + #include -#include #include #include /*}}}*/ diff --git a/apt-pkg/contrib/macros.h b/apt-pkg/contrib/macros.h new file mode 100644 index 000000000..e53eb32df --- /dev/null +++ b/apt-pkg/contrib/macros.h @@ -0,0 +1,79 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + Macros Header - Various useful macro definitions + + This source is placed in the Public Domain, do with it what you will + It was originally written by Brian C. White. + + ##################################################################### */ + /*}}}*/ +// Private header +#ifndef MACROS_H +#define MACROS_H + +// MIN_VAL(SINT16) will return -0x8000 and MAX_VAL(SINT16) = 0x7FFF +#define MIN_VAL(t) (((t)(-1) > 0) ? (t)( 0) : (t)(((1L<<(sizeof(t)*8-1)) ))) +#define MAX_VAL(t) (((t)(-1) > 0) ? (t)(-1) : (t)(((1L<<(sizeof(t)*8-1))-1))) + +// Min/Max functions +#if !defined(MIN) +#if defined(__HIGHC__) +#define MIN(x,y) _min(x,y) +#define MAX(x,y) _max(x,y) +#endif + +// GNU C++ has a min/max operator +#if defined(__GNUG__) +#define MIN(A,B) ((A) ? (B)) +#endif + +/* Templates tend to mess up existing code that uses min/max because of the + strict matching requirements */ +#if !defined(MIN) +#define MIN(A,B) ((A) < (B)?(A):(B)) +#define MAX(A,B) ((A) > (B)?(A):(B)) +#endif +#endif + +/* Bound functions, bound will return the value b within the limits a-c + bounv will change b so that it is within the limits of a-c. */ +#define _bound(a,b,c) MIN(c,MAX(b,a)) +#define _boundv(a,b,c) b = _bound(a,b,c) +#define ABS(a) (((a) < (0)) ?-(a) : (a)) + +/* Usefull count macro, use on an array of things and it will return the + number of items in the array */ +#define _count(a) (sizeof(a)/sizeof(a[0])) + +// Flag Macros +#define FLAG(f) (1L << (f)) +#define SETFLAG(v,f) ((v) |= FLAG(f)) +#define CLRFLAG(v,f) ((v) &=~FLAG(f)) +#define CHKFLAG(v,f) ((v) & FLAG(f) ? true : false) + +// some nice optional GNUC features +#if __GNUC__ >= 3 + #define __must_check __attribute__ ((warn_unused_result)) + #define __deprecated __attribute__ ((deprecated)) + /* likely() and unlikely() can be used to mark boolean expressions + as (not) likely true which will help the compiler to optimise */ + #define likely(x) __builtin_expect (!!(x), 1) + #define unlikely(x) __builtin_expect (!!(x), 0) +#else + #define __must_check /* no warn_unused_result */ + #define __deprecated /* no deprecated */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif + +// cold functions are unlikely() to be called +#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 + #define __cold __attribute__ ((__cold__)) +#else + #define __cold /* no cold marker */ +#endif + +#endif diff --git a/apt-pkg/contrib/md5.cc b/apt-pkg/contrib/md5.cc index 2bfd70f1b..c0fa8493d 100644 --- a/apt-pkg/contrib/md5.cc +++ b/apt-pkg/contrib/md5.cc @@ -37,14 +37,13 @@ // Include Files /*{{{*/ #include #include +#include #include #include #include // For htonl #include #include -#include - /*}}}*/ // byteSwap - Swap bytes in a buffer /*{{{*/ diff --git a/apt-pkg/contrib/sha1.cc b/apt-pkg/contrib/sha1.cc index b70f31dc6..eae52d52f 100644 --- a/apt-pkg/contrib/sha1.cc +++ b/apt-pkg/contrib/sha1.cc @@ -31,12 +31,12 @@ // Include Files /*{{{*/ #include #include +#include #include #include #include #include -#include /*}}}*/ // SHA1Transform - Alters an existing SHA-1 hash /*{{{*/ diff --git a/apt-pkg/contrib/system.h b/apt-pkg/contrib/system.h deleted file mode 100644 index b57093b93..000000000 --- a/apt-pkg/contrib/system.h +++ /dev/null @@ -1,80 +0,0 @@ -// -*- mode: cpp; mode: fold -*- -// Description /*{{{*/ -// $Id: system.h,v 1.3 1999/12/10 23:40:29 jgg Exp $ -/* ###################################################################### - - System Header - Usefull private definitions - - This source is placed in the Public Domain, do with it what you will - It was originally written by Brian C. White. - - ##################################################################### */ - /*}}}*/ -// Private header -#ifndef SYSTEM_H -#define SYSTEM_H - -// MIN_VAL(SINT16) will return -0x8000 and MAX_VAL(SINT16) = 0x7FFF -#define MIN_VAL(t) (((t)(-1) > 0) ? (t)( 0) : (t)(((1L<<(sizeof(t)*8-1)) ))) -#define MAX_VAL(t) (((t)(-1) > 0) ? (t)(-1) : (t)(((1L<<(sizeof(t)*8-1))-1))) - -// Min/Max functions -#if !defined(MIN) -#if defined(__HIGHC__) -#define MIN(x,y) _min(x,y) -#define MAX(x,y) _max(x,y) -#endif - -// GNU C++ has a min/max operator -#if defined(__GNUG__) -#define MIN(A,B) ((A) ? (B)) -#endif - -/* Templates tend to mess up existing code that uses min/max because of the - strict matching requirements */ -#if !defined(MIN) -#define MIN(A,B) ((A) < (B)?(A):(B)) -#define MAX(A,B) ((A) > (B)?(A):(B)) -#endif -#endif - -/* Bound functions, bound will return the value b within the limits a-c - bounv will change b so that it is within the limits of a-c. */ -#define _bound(a,b,c) MIN(c,MAX(b,a)) -#define _boundv(a,b,c) b = _bound(a,b,c) -#define ABS(a) (((a) < (0)) ?-(a) : (a)) - -/* Usefull count macro, use on an array of things and it will return the - number of items in the array */ -#define _count(a) (sizeof(a)/sizeof(a[0])) - -// Flag Macros -#define FLAG(f) (1L << (f)) -#define SETFLAG(v,f) ((v) |= FLAG(f)) -#define CLRFLAG(v,f) ((v) &=~FLAG(f)) -#define CHKFLAG(v,f) ((v) & FLAG(f) ? true : false) - -// some nice optional GNUC features -#if __GNUC__ >= 3 - #define __must_check __attribute__ ((warn_unused_result)) - #define __deprecated __attribute__ ((deprecated)) - /* likely() and unlikely() can be used to mark boolean expressions - as (not) likely true which will help the compiler to optimise */ - #define likely(x) __builtin_expect (!!(x), 1) - #define unlikely(x) __builtin_expect (!!(x), 0) -#else - #define __must_check /* no warn_unused_result */ - #define __deprecated /* no deprecated */ - #define likely(x) (x) - #define unlikely(x) (x) -#endif - -// cold functions are unlikely() to be called -#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 - #define __cold __attribute__ ((__cold__)) -#else - #define __cold /* no cold marker */ -#endif - -#endif diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 25a1df3f9..66108d822 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -17,10 +17,9 @@ #include #include #include +#include #include - -#include /*}}}*/ static debListParser::WordList PrioList[] = {{"important",pkgCache::State::Important}, diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 3d6209658..bdd49c089 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -24,7 +24,8 @@ SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \ contrib/cdromutl.cc contrib/crc-16.cc contrib/netrc.cc \ contrib/fileutl.cc HEADERS = mmap.h error.h configuration.h fileutl.h cmndline.h netrc.h\ - md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha256.h hashes.h + md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha256.h hashes.h \ + macros.h # Source code for the core main library SOURCE+= pkgcache.cc version.cc depcache.cc \ @@ -53,7 +54,4 @@ HEADERS+= debversion.h debsrcrecords.h dpkgpm.h debrecords.h \ HEADERS := $(addprefix apt-pkg/,$(HEADERS)) -# Private header files -HEADERS+= system.h - include $(LIBRARY_H) diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index eb7e4957a..038bd7ec4 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -35,7 +36,6 @@ #include #include -#include /*}}}*/ using std::string; diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index f988c1018..3eeb18cae 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -32,7 +33,6 @@ #include #include #include -#include /*}}}*/ typedef vector::iterator FileIterator; -- cgit v1.2.3 From 8f3d83eeaec58e9347fe4c61dae18686782f94ca Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 30 Jan 2010 22:30:29 +0100 Subject: cleanup the error header a bit by moving the printf-macros out and remove the using std::string --- apt-pkg/contrib/error.h | 30 +++++++----------------------- apt-pkg/contrib/macros.h | 9 +++++++++ 2 files changed, 16 insertions(+), 23 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h index 31413b2dc..90747ff7e 100644 --- a/apt-pkg/contrib/error.h +++ b/apt-pkg/contrib/error.h @@ -40,28 +40,15 @@ #ifndef PKGLIB_ERROR_H #define PKGLIB_ERROR_H - - -#ifdef __GNUG__ -// Methods have a hidden this parameter that is visible to this attribute -#define APT_MFORMAT1 __attribute__ ((format (printf, 2, 3))) -#define APT_MFORMAT2 __attribute__ ((format (printf, 3, 4))) -#else -#define APT_MFORMAT1 -#define APT_MFORMAT2 -#endif - -#include - #include -using std::string; +#include class GlobalError { struct Item { - string Text; + std::string Text; bool Error; Item *Next; }; @@ -73,18 +60,18 @@ class GlobalError public: // Call to generate an error from a library call. - bool Errno(const char *Function,const char *Description,...) APT_MFORMAT2 __cold; - bool WarningE(const char *Function,const char *Description,...) APT_MFORMAT2 __cold; + bool Errno(const char *Function,const char *Description,...) __like_printf_2 __cold; + bool WarningE(const char *Function,const char *Description,...) __like_printf_2 __cold; /* A warning should be considered less severe than an error, and may be ignored by the client. */ - bool Error(const char *Description,...) APT_MFORMAT1 __cold; - bool Warning(const char *Description,...) APT_MFORMAT1 __cold; + bool Error(const char *Description,...) __like_printf_1 __cold; + bool Warning(const char *Description,...) __like_printf_1 __cold; // Simple accessors inline bool PendingError() {return PendingFlag;}; inline bool empty() {return List == 0;}; - bool PopMessage(string &Text); + bool PopMessage(std::string &Text); void Discard(); // Usefull routine to dump to cerr @@ -97,7 +84,4 @@ class GlobalError GlobalError *_GetErrorObj(); #define _error _GetErrorObj() -#undef APT_MFORMAT1 -#undef APT_MFORMAT2 - #endif diff --git a/apt-pkg/contrib/macros.h b/apt-pkg/contrib/macros.h index e53eb32df..9aeb77b81 100644 --- a/apt-pkg/contrib/macros.h +++ b/apt-pkg/contrib/macros.h @@ -76,4 +76,13 @@ #define __cold /* no cold marker */ #endif +#ifdef __GNUG__ +// Methods have a hidden this parameter that is visible to this attribute + #define __like_printf_1 __attribute__ ((format (printf, 2, 3))) + #define __like_printf_2 __attribute__ ((format (printf, 3, 4))) +#else + #define __like_printf_1 + #define __like_printf_2 +#endif + #endif -- cgit v1.2.3 From 857e9c13d8d9808fcd1ac8ff3469f6c0b90b7fea Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 7 Feb 2010 12:38:13 +0100 Subject: Drop the Arch information from the Version structure as we can get the information from the parent package now --- apt-pkg/cacheiterators.h | 2 +- apt-pkg/deb/deblistparser.cc | 10 +++++++--- apt-pkg/deb/deblistparser.h | 1 + apt-pkg/pkgcache.cc | 4 ++-- apt-pkg/pkgcache.h | 1 - apt-pkg/pkgcachegen.h | 1 + 6 files changed, 12 insertions(+), 7 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 33d2ed6be..d8e044f88 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -178,7 +178,7 @@ class pkgCache::VerIterator : public Iterator { // Accessors inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;}; inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;}; - inline const char *Arch() const {return S->Arch == 0?0:Owner->StrP + S->Arch;}; + inline const char *Arch() const {return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;}; inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);}; inline DescIterator DescriptionList() const; diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index f683de423..26841d3d2 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -83,6 +83,13 @@ string debListParser::Architecture() { return Result; } /*}}}*/ +// ListParser::ArchitectureAll /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debListParser::ArchitectureAll() { + return Section.FindS("Architecture") == "all"; +} + /*}}}*/ // ListParser::Version - Return the version string /*{{{*/ // --------------------------------------------------------------------- /* This is to return the string describing the version in debian form, @@ -101,9 +108,6 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) // Parse the section Ver->Section = UniqFindTagWrite("Section"); - // Parse the architecture - Ver->Arch = WriteUniqString(Architecture()); - // Parse multi-arch if (Section.FindS("Architecture") == "all") /* Arch all packages can't have a Multi-Arch field, diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index cba4f8e5d..8da051530 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -47,6 +47,7 @@ class debListParser : public pkgCacheGenerator::ListParser // These all operate against the current section virtual string Package(); virtual string Architecture(); + virtual bool ArchitectureAll(); virtual string Version(); virtual bool NewVersion(pkgCache::VerIterator Ver); virtual string Description(); diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 1e4c7edb3..7d98869ea 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -399,7 +399,7 @@ const char * pkgCache::PkgIterator::CandVersion() const { //TargetVer is empty, so don't use it. - VerIterator version = pkgPolicy::pkgPolicy(Owner).GetCandidateVer(*this); + VerIterator version = pkgPolicy(Owner).GetCandidateVer(*this); if (version.IsGood()) return version.VerStr(); return 0; @@ -727,7 +727,7 @@ string pkgCache::VerIterator::RelStr() Res += File.Site(); } } - if (S->Arch != 0) + if (S->ParentPkg != 0) Res.append(" [").append(Arch()).append("]"); return Res; } diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 5f50001d0..5edeedfd1 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -276,7 +276,6 @@ struct pkgCache::Version /*{{{*/ { map_ptrloc VerStr; // Stringtable map_ptrloc Section; // StringTable (StringItem) - map_ptrloc Arch; // StringTable enum {None, All, Foreign, Same, Allowed} MultiArch; // Lists diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index 53f09b991..ca5d74a9f 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -112,6 +112,7 @@ class pkgCacheGenerator::ListParser // These all operate against the current section virtual string Package() = 0; virtual string Architecture() = 0; + virtual bool ArchitectureAll() = 0; virtual string Version() = 0; virtual bool NewVersion(pkgCache::VerIterator Ver) = 0; virtual string Description() = 0; -- cgit v1.2.3 From eef21b9f52adc2170a3a3ffd0258a19810cacfd7 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 7 Feb 2010 19:26:02 +0100 Subject: fix progress reporting while reading extended_states file --- apt-pkg/depcache.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index ec7a5de64..5943d858a 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; -- cgit v1.2.3 From 8b32e9209ecfab776f064e3c4ccab249307ae49d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 10 Feb 2010 17:42:39 +0100 Subject: Pre-MultiArch a package which depends on a package with architecture "all" can be sure that a package comeing in as a dependency of this package will be of the same architecture as itself (or all). We don't want to break this, so internal an arch all package is represented as many arch depending packages. The only problem we have now is that we only know that a arch all package is installed or not - we don't know for which architecture it was installed: So we will look at all these broken arch all pseudo packages and "remove" them. --- apt-pkg/depcache.cc | 93 +++++++++++++++++++++++++++++++++++++++++++++++--- apt-pkg/depcache.h | 12 ++++--- apt-pkg/pkgcachegen.cc | 16 +++++++-- 3 files changed, 110 insertions(+), 11 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 228750b74..b04181d76 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -596,6 +597,57 @@ void pkgDepCache::UpdateVerState(PkgIterator Pkg) } } /*}}}*/ +// DepCache::RemovePseudoInstalledPkg - MultiArch helper for Update() /*{{{*/ +// --------------------------------------------------------------------- +/* We "install" arch all packages for all archs if it is installed. Many + of these will be broken. This method will look at these broken Pkg and + "remove" it. */ +bool pkgDepCache::RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set &recheck) { + if (unlikely(Pkg->CurrentVer == 0)) + return false; + + VerIterator V = Pkg.CurrentVer(); + if (V->MultiArch != Version::All) + return false; + + unsigned char const DepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy); + if ((DepState & DepInstMin) == DepInstMin) + return false; + + // Dependencies for this arch all are not statisfied + // so we installed it only for our convenience: get right of it now. + RemoveSizes(Pkg); + RemoveStates(Pkg); + + Pkg->CurrentVer = 0; + PkgState[Pkg->ID].InstallVer = 0; + + AddStates(Pkg); + Update(Pkg); + AddSizes(Pkg); + + // After the remove previously satisfied pseudo pkg could be now + // no longer satisfied, so we need to recheck the reverse dependencies + for (DepIterator d = Pkg.RevDependsList(); d.end() != true; ++d) + { + PkgIterator const P = d.ParentPkg(); + if (P->CurrentVer != 0) + recheck.insert(P.Index()); + } + + if (V.end() != true) + for (PrvIterator Prv = V.ProvidesList(); Prv.end() != true; Prv++) + for (DepIterator d = Prv.ParentPkg().RevDependsList(); + d.end() != true; ++d) + { + PkgIterator const P = d.ParentPkg(); + if (P->CurrentVer != 0) + recheck.insert(P.Index()); + } + + return true; +} + /*}}}*/ // DepCache::Update - Figure out all the state information /*{{{*/ // --------------------------------------------------------------------- /* This will figure out the state of all the packages and all the @@ -609,9 +661,13 @@ void pkgDepCache::Update(OpProgress *Prog) iKeepCount = 0; iBrokenCount = 0; iBadCount = 0; - + + std::set recheck; + // Perform the depends pass int Done = 0; + bool const checkMultiArch = APT::Configuration::getArchitectures().size() > 1; + unsigned long killed = 0; for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++) { if (Prog != 0 && Done%20 == 0) @@ -619,7 +675,7 @@ void pkgDepCache::Update(OpProgress *Prog) for (VerIterator V = I.VersionList(); V.end() != true; V++) { unsigned char Group = 0; - + for (DepIterator D = V.DependsList(); D.end() != true; D++) { // Build the dependency state. @@ -637,16 +693,43 @@ void pkgDepCache::Update(OpProgress *Prog) D->Type == Dep::DpkgBreaks || D->Type == Dep::Obsoletes) State = ~State; - } + } } - // Compute the pacakge dependency state and size additions + // Compute the package dependency state and size additions AddSizes(I); UpdateVerState(I); AddStates(I); + + if (checkMultiArch != true || I->CurrentVer == 0) + continue; + + VerIterator const V = I.CurrentVer(); + if (V->MultiArch != Version::All) + continue; + + recheck.insert(I.Index()); + --Done; // no progress if we need to recheck the package } - if (Prog != 0) + if (checkMultiArch == true) { + /* FIXME: recheck breaks proper progress reporting as we don't know + how many packages we need to recheck. To lower the effect + a bit we increase with a kill, but we should do something more clever… */ + for(std::set::const_iterator p = recheck.begin(); + p != recheck.end(); ++p) { + if (Prog != 0 && Done%20 == 0) + Prog->Progress(Done); + PkgIterator P = PkgIterator(*Cache, Cache->PkgP + *p); + if (RemovePseudoInstalledPkg(P, recheck) == true) { + ++killed; + ++Done; + } + recheck.erase(p); + } + } + + if (Prog != 0) Prog->Progress(Done); readStateFile(Prog); diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 0306861a1..63cd954ad 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -46,6 +46,7 @@ #include #include +#include class pkgDepCache : protected pkgCache::Namespace { @@ -442,9 +443,6 @@ class pkgDepCache : protected pkgCache::Namespace virtual bool IsDeleteOk(const PkgIterator &Pkg,bool Purge = false, unsigned long Depth = 0, bool FromUser = true); - // This is for debuging - void Update(OpProgress *Prog = 0); - // read persistent states bool readStateFile(OpProgress *prog); bool writeStateFile(OpProgress *prog, bool InstalledOnly=false); @@ -460,9 +458,15 @@ class pkgDepCache : protected pkgCache::Namespace inline unsigned long BadCount() {return iBadCount;}; bool Init(OpProgress *Prog); - + // Generate all state information + void Update(OpProgress *Prog = 0); + pkgDepCache(pkgCache *Cache,Policy *Plcy = 0); virtual ~pkgDepCache(); + + private: + // Helper for Update(OpProgress) to remove pseudoinstalled arch all packages + bool RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set &recheck); }; #endif diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 2a4a30349..a4ca9dfe4 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -108,13 +108,24 @@ bool pkgCacheGenerator::MergeList(ListParser &List, unsigned int Counter = 0; while (List.Step() == true) { - // Get a pointer to the package structure string const PackageName = List.Package(); if (PackageName.empty() == true) return false; + /* As we handle Arch all packages as architecture bounded + we add all information to every (simulated) arch package */ + std::vector genArch; + if (List.ArchitectureAll() == true) + genArch = APT::Configuration::getArchitectures(); + else + genArch.push_back(List.Architecture()); + + for (std::vector::const_iterator arch = genArch.begin(); + arch != genArch.end(); ++arch) + { + // Get a pointer to the package structure pkgCache::PkgIterator Pkg; - if (NewPackage(Pkg, PackageName, List.Architecture()) == false) + if (NewPackage(Pkg, PackageName, *arch) == false) return _error->Error(_("Error occurred while processing %s (NewPackage)"),PackageName.c_str()); Counter++; if (Counter % 100 == 0 && Progress != 0) @@ -257,6 +268,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List, if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false) return _error->Error(_("Error occurred while processing %s (NewFileDesc2)"),PackageName.c_str()); + } } FoundFileDeps |= List.HasFileDeps(); -- cgit v1.2.3 From 302578f3b286540a327c822d8be3ccbb4fa47d0a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 10 Feb 2010 21:23:39 +0100 Subject: Create implicit dependencies needed for Multi-Arch handling --- apt-pkg/pkgcachegen.cc | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index a4ca9dfe4..037c0cb63 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -532,11 +532,14 @@ bool pkgCacheGenerator::FinishCache(OpProgress &Progress) { string const PkgName = G.Name(); for (pkgCache::PkgIterator P = G.PackageList(); P.end() != true; P = G.NextPkg(P)) { for (pkgCache::VerIterator V = P.VersionList(); V.end() != true; V++) { - // Arch all packages are "co-installable" - if (V->MultiArch == pkgCache::Version::All) - continue; string const Arch = V.Arch(); map_ptrloc *OldDepLast = NULL; + /* MultiArch handling introduces a lot of implicit Dependencies: + - MultiArch: same → Co-Installable if they have the same version + - Architecture: all → Need to be Co-Installable for internal reasons + - All others conflict with all other group members */ + bool const coInstall = (V->MultiArch == pkgCache::Version::All || + V->MultiArch == pkgCache::Version::Same); for (vector::const_iterator A = archs.begin(); A != archs.end(); ++A) { if (*A == Arch) continue; @@ -546,10 +549,24 @@ bool pkgCacheGenerator::FinishCache(OpProgress &Progress) { pkgCache::PkgIterator D = G.FindPkg(*A); if (D.end() == true) continue; - // Conflicts: ${self}:other - NewDepends(D, V, "", - pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts, - OldDepLast); + if (coInstall == true) { + // Replaces: ${self}:other ( << ${binary:Version}) + NewDepends(D, V, V.VerStr(), + pkgCache::Dep::Less, pkgCache::Dep::Replaces, + OldDepLast); + // Breaks: ${self}:other (!= ${binary:Version}) + NewDepends(D, V, V.VerStr(), + pkgCache::Dep::Less, pkgCache::Dep::DpkgBreaks, + OldDepLast); + NewDepends(D, V, V.VerStr(), + pkgCache::Dep::Greater, pkgCache::Dep::DpkgBreaks, + OldDepLast); + } else { + // Conflicts: ${self}:other + NewDepends(D, V, "", + pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts, + OldDepLast); + } } } } -- cgit v1.2.3 From 67e0766f0eab85ce1aeacee75fc6b200f36996c9 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 10 Feb 2010 22:45:58 +0100 Subject: Foreign Versions add an implicit Provides to the other packages in the group --- apt-pkg/deb/deblistparser.cc | 55 +++++++++++++++++++++++++++++--------------- apt-pkg/pkgcachegen.cc | 7 +++--- apt-pkg/pkgcachegen.h | 4 ++-- 3 files changed, 42 insertions(+), 24 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 26841d3d2..b6082cdd5 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -618,29 +618,46 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver) { const char *Start; const char *Stop; - if (Section.Find("Provides",Start,Stop) == false) - return true; - - string Package; - string Version; - unsigned int Op; - - while (1) + if (Section.Find("Provides",Start,Stop) == true) { - Start = ParseDepends(Start,Stop,Package,Version,Op); - if (Start == 0) - return _error->Error("Problem parsing Provides line"); - if (Op != pkgCache::Dep::NoOp) { - _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str()); - } else { - if (NewProvides(Ver,Package,Version) == false) - return false; + string Package; + string Version; + string const Arch = Ver.Arch(); + unsigned int Op; + + while (1) + { + Start = ParseDepends(Start,Stop,Package,Version,Op); + if (Start == 0) + return _error->Error("Problem parsing Provides line"); + if (Op != pkgCache::Dep::NoOp) { + _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str()); + } else { + if (NewProvides(Ver, Package, Arch, Version) == false) + return false; + } + + if (Start == Stop) + break; } + } - if (Start == Stop) - break; + if (Ver->MultiArch != pkgCache::Version::Foreign) + return true; + + std::vector const archs = APT::Configuration::getArchitectures(); + if (archs.size() <= 1) + return true; + + string const Package = Ver.ParentPkg().Name(); + string const Version = Ver.VerStr(); + for (std::vector::const_iterator a = archs.begin(); + a != archs.end(); ++a) + { + if (NewProvides(Ver, Package, *a, Version) == false) + return false; } - + return true; } /*}}}*/ diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 037c0cb63..ebda325f7 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -668,13 +668,14 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, // --------------------------------------------------------------------- /* */ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver, - const string &PackageName, + const string &PkgName, + const string &PkgArch, const string &Version) { pkgCache &Cache = Owner->Cache; // We do not add self referencing provides - if (unlikely(Ver.ParentPkg().Name() == PackageName)) + if (Ver.ParentPkg().Name() == PkgName && PkgArch == Ver.Arch()) return true; // Get a structure @@ -693,7 +694,7 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver, // Locate the target package pkgCache::PkgIterator Pkg; - if (unlikely(Owner->NewPackage(Pkg,PackageName,string(Ver.Arch())) == false)) + if (unlikely(Owner->NewPackage(Pkg,PkgName, PkgArch) == false)) return false; // Link it to the package diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index ca5d74a9f..46d0cd893 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -104,8 +104,8 @@ class pkgCacheGenerator::ListParser bool NewDepends(pkgCache::VerIterator Ver,const string &Package, const string &Arch, const string &Version,unsigned int Op, unsigned int Type); - bool NewProvides(pkgCache::VerIterator Ver,const string &Package, - const string &Version); + bool NewProvides(pkgCache::VerIterator Ver,const string &PkgName, + const string &PkgArch, const string &Version); public: -- cgit v1.2.3 From 4d174dc84ea184b5afa81abb3b94e2ef3380ece8 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 11 Feb 2010 12:19:48 +0100 Subject: Add Multi-Arch: allowed support by creating an implicit provide of name:any for such packages, so dependencies in this style can be easily resolved. --- apt-pkg/deb/deblistparser.cc | 6 ++++++ apt-pkg/pkgcache.cc | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index b6082cdd5..3726a6a04 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -642,6 +642,12 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver) } } + if (Ver->MultiArch == pkgCache::Version::Allowed) + { + string const Package = string(Ver.ParentPkg().Name()).append(":").append("any"); + NewProvides(Ver, Package, "any", Ver.VerStr()); + } + if (Ver->MultiArch != pkgCache::Version::Foreign) return true; diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 7d98869ea..2d4ee1010 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -186,7 +186,10 @@ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) { size_t const found = Name.find(':'); if (found == string::npos) return FindPkg(Name, "native"); - return FindPkg(Name.substr(0, found), Name.substr(found+1, string::npos)); + string const Arch = Name.substr(found+1); + if (Arch == "any") + return FindPkg(Name, "any"); + return FindPkg(Name.substr(0, found), Arch); } /*}}}*/ // Cache::FindPkg - Locate a package by name /*{{{*/ -- cgit v1.2.3 From c5dac10c3dd6d8f54d97d3105803d07fa891fcd4 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 11 Feb 2010 18:20:02 +0100 Subject: Arch() on a MultiArch:all version should return "all" to be compatible with previous usecases. You now need to requested with Arch(true) the return of the architecture this version (and pseudo package) was created for. --- apt-pkg/cacheiterators.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index d8e044f88..e8cf28496 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -178,7 +178,16 @@ class pkgCache::VerIterator : public Iterator { // Accessors inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;}; inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;}; - inline const char *Arch() const {return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;}; + inline const char *Arch() const { + if(S->MultiArch == pkgCache::Version::All) + return "all"; + return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch; + }; + inline const char *Arch(bool const pseudo) const { + if(pseudo == false) + return Arch(); + return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch; + }; inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);}; inline DescIterator DescriptionList() const; -- cgit v1.2.3 From 803ea2a87f81252b2c0d541b8502ed206ce57c84 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 12 Feb 2010 00:04:31 +0100 Subject: Add yet another pseudo package which isn't as pseudo as the others: Arch all packages are now represented by arch depending packages which all depend on a package with the same name and the special arch "all". This packages has NO dependencies, but beside this the same information. It is the only package which has a size, the arch depending ones all have a zero size. While the arch depending pseudo packages are used for dependency resolution the arch "all" package is used for downloading and ordering of the package. --- apt-pkg/algorithms.cc | 52 ++++++++++++++++++++++++++++++++++++++++---- apt-pkg/cacheiterators.h | 1 + apt-pkg/deb/deblistparser.cc | 22 +++++++++++++++++-- apt-pkg/depcache.cc | 4 ++++ apt-pkg/depcache.h | 1 + apt-pkg/orderlist.cc | 4 ++++ apt-pkg/packagemanager.cc | 23 +++++++++++++++----- apt-pkg/pkgcache.cc | 12 ++++++++++ apt-pkg/pkgcache.h | 2 +- apt-pkg/pkgcachegen.cc | 20 +++++++++++++---- 10 files changed, 124 insertions(+), 17 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 34da745de..c905cffa9 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -83,13 +83,28 @@ void pkgSimulate::Describe(PkgIterator Pkg,ostream &out,bool Current,bool Candid bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/) { // Adapt the iterator - PkgIterator Pkg = Sim.FindPkg(iPkg.Name()); + PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch()); Flags[Pkg->ID] = 1; cout << "Inst "; Describe(Pkg,cout,true,true); Sim.MarkInstall(Pkg,false); - + + if (strcmp(Pkg.Arch(),"all") == 0) + { + pkgCache::GrpIterator G = Pkg.Group(); + pkgCache::GrpIterator iG = iPkg.Group(); + for (pkgCache::PkgIterator P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P)) + { + if (strcmp(P.Arch(), "all") == 0) + continue; + if (iG.FindPkg(P.Arch())->CurrentVer == 0) + continue; + Flags[P->ID] = 1; + Sim.MarkInstall(P, false); + } + } + // Look for broken conflicts+predepends. for (PkgIterator I = Sim.PkgBegin(); I.end() == false; I++) { @@ -131,9 +146,22 @@ bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/) bool pkgSimulate::Configure(PkgIterator iPkg) { // Adapt the iterator - PkgIterator Pkg = Sim.FindPkg(iPkg.Name()); + PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch()); Flags[Pkg->ID] = 2; + + if (strcmp(Pkg.Arch(),"all") == 0) + { + pkgCache::GrpIterator G = Pkg.Group(); + for (pkgCache::PkgIterator P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P)) + { + if (strcmp(P.Arch(), "all") == 0) + continue; + if (Flags[P->ID] == 1) + Flags[P->ID] = 2; + } + } + // Sim.MarkInstall(Pkg,false); if (Sim[Pkg].InstBroken() == true) { @@ -181,10 +209,26 @@ bool pkgSimulate::Configure(PkgIterator iPkg) bool pkgSimulate::Remove(PkgIterator iPkg,bool Purge) { // Adapt the iterator - PkgIterator Pkg = Sim.FindPkg(iPkg.Name()); + PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch()); Flags[Pkg->ID] = 3; Sim.MarkDelete(Pkg); + + if (strcmp(Pkg.Arch(),"all") == 0) + { + pkgCache::GrpIterator G = Pkg.Group(); + pkgCache::GrpIterator iG = iPkg.Group(); + for (pkgCache::PkgIterator P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P)) + { + if (strcmp(P.Arch(), "all") == 0) + continue; + if (iG.FindPkg(P.Arch())->CurrentVer == 0) + continue; + Flags[P->ID] = 3; + Sim.MarkDelete(P); + } + } + if (Purge == true) cout << "Purg "; else diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index e8cf28496..43cbe1377 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -200,6 +200,7 @@ class pkgCache::VerIterator : public Iterator { string RelStr(); bool Automatic() const; + bool Pseudo() const; VerFileIterator NewestFile() const; inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator(Owner, Trg) { diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 3726a6a04..b3d95164a 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -148,6 +148,24 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) Ver->Priority = pkgCache::State::Extra; } + if (Ver->MultiArch == pkgCache::Version::All) + { + /* We maintain a "pseudo" arch=all package for architecture all versions + on which these versions can depend on. This pseudo package is many used + for downloading/installing: The other pseudo-packages will degenerate + to a NOP in the download/install step - this package will ensure that + it is downloaded only one time and installed only one time -- even if + the architecture bound versions coming in and out on regular basis. */ + if (strcmp(Ver.Arch(true),"all") == 0) + return true; + else + { + // our pseudo packages have no size to not confuse the fetcher + Ver->Size = 0; + Ver->InstalledSize = 0; + } + } + if (ParseDepends(Ver,"Depends",pkgCache::Dep::Depends) == false) return false; if (ParseDepends(Ver,"Pre-Depends",pkgCache::Dep::PreDepends) == false) @@ -593,7 +611,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver, return true; string Package; - string const pkgArch = Ver.Arch(); + string const pkgArch = Ver.Arch(true); string Version; unsigned int Op; @@ -622,7 +640,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver) { string Package; string Version; - string const Arch = Ver.Arch(); + string const Arch = Ver.Arch(true); unsigned int Op; while (1) diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index b04181d76..e817adb77 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -896,6 +896,10 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge, AddStates(Pkg); Update(Pkg); AddSizes(Pkg); + + // if we remove the pseudo package, we also need to remove the "real" + if (Pkg->CurrentVer != 0 && Pkg.CurrentVer().Pseudo() == true) + MarkDelete(Pkg.Group().FindPkg("all"), rPurge, Depth+1, FromUser); } /*}}}*/ // DepCache::IsDeleteOk - check if it is ok to remove this package /*{{{*/ diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 63cd954ad..ab1021a44 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -333,6 +333,7 @@ class pkgDepCache : protected pkgCache::Namespace inline Header &Head() {return *Cache->HeaderP;}; inline PkgIterator PkgBegin() {return Cache->PkgBegin();}; inline PkgIterator FindPkg(string const &Name) {return Cache->FindPkg(Name);}; + inline PkgIterator FindPkg(string const &Name, string const &Arch) {return Cache->FindPkg(Name, Arch);}; inline pkgCache &GetCache() {return *Cache;}; inline pkgVersioningSystem &VS() {return *Cache->VS;}; diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc index 0ee2e2bc8..2e7618b55 100644 --- a/apt-pkg/orderlist.cc +++ b/apt-pkg/orderlist.cc @@ -126,6 +126,10 @@ bool pkgOrderList::IsMissing(PkgIterator Pkg) if (FileList[Pkg->ID].empty() == false) return false; + + if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == true) + return false; + return true; } /*}}}*/ diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 1ab3203a1..08e7fc00f 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -80,7 +80,10 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, // Skip already processed packages if (List->IsNow(Pkg) == false) continue; - + + if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == true) + continue; + new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache), FileNames[Pkg->ID]); } @@ -277,8 +280,10 @@ bool pkgPackageManager::ConfigureAll() for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++) { PkgIterator Pkg(Cache,*I); - - if (ConfigurePkgs == true && Configure(Pkg) == false) + + if (ConfigurePkgs == true && + pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false && + Configure(Pkg) == false) return false; List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); @@ -310,7 +315,9 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg) { PkgIterator Pkg(Cache,*I); - if (ConfigurePkgs == true && Configure(Pkg) == false) + if (ConfigurePkgs == true && + pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false && + Configure(Pkg) == false) return false; List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); @@ -457,7 +464,10 @@ bool pkgPackageManager::SmartRemove(PkgIterator Pkg) return true; List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); - return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge); + + if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false) + return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge); + return true; } /*}}}*/ // PM::SmartUnPack - Install helper /*{{{*/ @@ -565,7 +575,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) P.end() == false; P++) CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion()); - if (Install(Pkg,FileNames[Pkg->ID]) == false) + if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false && + Install(Pkg,FileNames[Pkg->ID]) == false) return false; List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 2d4ee1010..04a2c7234 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -649,6 +649,18 @@ bool pkgCache::VerIterator::Automatic() const return false; } /*}}}*/ +// VerIterator::Pseudo - Check if this version is a pseudo one /*{{{*/ +// --------------------------------------------------------------------- +/* Sometimes you have the need to express dependencies with versions + which doesn't really exist or exist multiply times for "different" + packages. We need these versions for dependency resolution but they + are a problem everytime we need to download/install something. */ +bool pkgCache::VerIterator::Pseudo() const +{ + return (S->MultiArch == pkgCache::Version::All && + strcmp(Arch(true),"all") != 0); +} + /*}}}*/ // VerIterator::NewestFile - Return the newest file version relation /*{{{*/ // --------------------------------------------------------------------- /* This looks at the version numbers associated with all of the sources diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 5edeedfd1..012caac76 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -357,7 +357,7 @@ inline pkgCache::PkgFileIterator pkgCache::FileEnd() class pkgCache::Namespace /*{{{*/ { public: - + typedef pkgCache::GrpIterator GrpIterator; typedef pkgCache::PkgIterator PkgIterator; typedef pkgCache::VerIterator VerIterator; typedef pkgCache::DescIterator DescIterator; diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index ebda325f7..c1b546a00 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -115,9 +115,10 @@ bool pkgCacheGenerator::MergeList(ListParser &List, /* As we handle Arch all packages as architecture bounded we add all information to every (simulated) arch package */ std::vector genArch; - if (List.ArchitectureAll() == true) + if (List.ArchitectureAll() == true) { genArch = APT::Configuration::getArchitectures(); - else + genArch.push_back("all"); + } else genArch.push_back(List.Architecture()); for (std::vector::const_iterator arch = genArch.begin(); @@ -531,8 +532,11 @@ bool pkgCacheGenerator::FinishCache(OpProgress &Progress) { for (pkgCache::GrpIterator G = GetCache().GrpBegin(); G.end() != true; G++) { string const PkgName = G.Name(); for (pkgCache::PkgIterator P = G.PackageList(); P.end() != true; P = G.NextPkg(P)) { + if (strcmp(P.Arch(),"all") == 0) + continue; + pkgCache::PkgIterator allPkg; for (pkgCache::VerIterator V = P.VersionList(); V.end() != true; V++) { - string const Arch = V.Arch(); + string const Arch = V.Arch(true); map_ptrloc *OldDepLast = NULL; /* MultiArch handling introduces a lot of implicit Dependencies: - MultiArch: same → Co-Installable if they have the same version @@ -540,6 +544,8 @@ bool pkgCacheGenerator::FinishCache(OpProgress &Progress) { - All others conflict with all other group members */ bool const coInstall = (V->MultiArch == pkgCache::Version::All || V->MultiArch == pkgCache::Version::Same); + if (V->MultiArch == pkgCache::Version::All && allPkg.end() == true) + allPkg = G.FindPkg("all"); for (vector::const_iterator A = archs.begin(); A != archs.end(); ++A) { if (*A == Arch) continue; @@ -561,6 +567,12 @@ bool pkgCacheGenerator::FinishCache(OpProgress &Progress) { NewDepends(D, V, V.VerStr(), pkgCache::Dep::Greater, pkgCache::Dep::DpkgBreaks, OldDepLast); + if (V->MultiArch == pkgCache::Version::All) { + // Depend on ${self}:all which does depend on nothing + NewDepends(allPkg, V, V.VerStr(), + pkgCache::Dep::Equals, pkgCache::Dep::Depends, + OldDepLast); + } } else { // Conflicts: ${self}:other NewDepends(D, V, "", @@ -675,7 +687,7 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver, pkgCache &Cache = Owner->Cache; // We do not add self referencing provides - if (Ver.ParentPkg().Name() == PkgName && PkgArch == Ver.Arch()) + if (Ver.ParentPkg().Name() == PkgName && PkgArch == Ver.Arch(true)) return true; // Get a structure -- cgit v1.2.3 From 42d71ab5fe58953a680bd300a99d173e23430d7c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 12 Feb 2010 17:17:16 +0100 Subject: In SingleArch environments we don't need the arch "all" pseudo package for handling arch:all packages, so we create only one package and stop calling it a pseudo package. --- apt-pkg/deb/deblistparser.cc | 2 +- apt-pkg/pkgcache.cc | 9 +++++++-- apt-pkg/pkgcachegen.cc | 3 ++- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index b3d95164a..1948aedf3 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -158,7 +158,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) the architecture bound versions coming in and out on regular basis. */ if (strcmp(Ver.Arch(true),"all") == 0) return true; - else + else if (Ver.Pseudo() == true) { // our pseudo packages have no size to not confuse the fetcher Ver->Size = 0; diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 04a2c7234..d4268b31c 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -657,8 +657,13 @@ bool pkgCache::VerIterator::Automatic() const are a problem everytime we need to download/install something. */ bool pkgCache::VerIterator::Pseudo() const { - return (S->MultiArch == pkgCache::Version::All && - strcmp(Arch(true),"all") != 0); + if (S->MultiArch == pkgCache::Version::All && + strcmp(Arch(true),"all") != 0) + { + GrpIterator const Grp = ParentPkg().Group(); + return (Grp->LastPackage != Grp->FirstPackage); + } + return false; } /*}}}*/ // VerIterator::NewestFile - Return the newest file version relation /*{{{*/ diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index c1b546a00..6d103c6b6 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -117,7 +117,8 @@ bool pkgCacheGenerator::MergeList(ListParser &List, std::vector genArch; if (List.ArchitectureAll() == true) { genArch = APT::Configuration::getArchitectures(); - genArch.push_back("all"); + if (genArch.size() != 1) + genArch.push_back("all"); } else genArch.push_back(List.Architecture()); -- cgit v1.2.3 From 4cc6f8dc52144f773b96ee99070d1be0821b984e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 13 Feb 2010 01:59:22 +0100 Subject: * apt-pkg/deb/dpkgpm.cc: - stdin redirected to /dev/null takes all CPU (Closes: #569488) Thanks to Aurelien Jarno for providing (again) a patch! --- apt-pkg/deb/dpkgpm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 565f01b84..3dca2b209 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1005,7 +1005,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) -- cgit v1.2.3 From ee60a63480f7d1a963d7ef2a8e399d0f9b651d71 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 14 Feb 2010 22:24:55 +0100 Subject: Pseudo() doesn't work in the Cache generation step as the check if only one package is in the group will generate false positives - as the others will (maybe) added a little time later in the process. --- apt-pkg/deb/deblistparser.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index bfc0e762e..84eab44a7 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -155,9 +155,10 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) to a NOP in the download/install step - this package will ensure that it is downloaded only one time and installed only one time -- even if the architecture bound versions coming in and out on regular basis. */ + bool const static multiArch = APT::Configuration::getArchitectures().size() > 1; if (strcmp(Ver.Arch(true),"all") == 0) return true; - else if (Ver.Pseudo() == true) + else if (multiArch == true) { // our pseudo packages have no size to not confuse the fetcher Ver->Size = 0; -- cgit v1.2.3 From 83742b3cf4b541fd61533dfecdc97e0e4502a7a4 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 14 Feb 2010 23:34:56 +0100 Subject: Add support for the LANGUAGE environment variable --- apt-pkg/aptconfiguration.cc | 91 +++++++++++++++++++++++++++++---------------- apt-pkg/aptconfiguration.h | 2 +- apt-pkg/contrib/strutl.cc | 2 +- 3 files changed, 61 insertions(+), 34 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 0fe84db74..f1989599b 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -8,10 +8,11 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#include #include #include +#include #include +#include #include #include @@ -97,7 +98,7 @@ const Configuration::getCompressionTypes(bool const &Cached) { will result in "de_DE, de, en". The special word "none" is the stopcode for the not-All code vector */ std::vector const Configuration::getLanguages(bool const &All, - bool const &Cached, char const * const Locale) { + bool const &Cached, char const ** const Locale) { using std::string; // The detection is boring and has a lot of cornercases, @@ -118,27 +119,29 @@ std::vector const Configuration::getLanguages(bool const &All, } } - // get the environment language code + // 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); + 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('.') != string::npos) ? envMsg.find('.') : (lenShort + 3); + 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, envShortIncluded = false; + bool envLongIncluded = true; // first cornercase: LANG=C, so we use only "en" Translation if (envLong == "C") { codes.push_back("en"); + allCodes = codes; 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) { - // 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... - char const *needLong[] = { "cs", "en", "pt", "sv", "zh", NULL }; for (char const **l = needLong; *l != NULL; l++) if (envShort.compare(*l) == 0) { envLongIncluded = false; @@ -156,33 +159,64 @@ std::vector const Configuration::getLanguages(bool const &All, if (oldAcquire.empty() == false && oldAcquire != "environment") { if (oldAcquire != "none") codes.push_back(oldAcquire); + allCodes = codes; 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 environment; + // take care of LC_MESSAGES + if (envLongIncluded == false) + environment.push_back(envLong); + environment.push_back(envShort); + // take care of LANGUAGE + string envLang = Locale == 0 ? getenv("LANGUAGE") : *(Locale+1); + if (envLang.empty() == false) { + std::vector env = ExplodeString(envLang,':'); + short addedLangs = 0; // add a maximum of 3 fallbacks from the environment + for (std::vector::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") { - if (envLongIncluded == false) - codes.push_back(envLong); - if (envShortIncluded == false) - codes.push_back(envShort); - return codes; + codes = environment; } else if (forceLang != "none") codes.push_back(forceLang); + allCodes = codes; return codes; } std::vector const lang = _config->FindVector("Acquire::Languages"); // the default setting -> "environment, en" if (lang.empty() == true) { - if (envLongIncluded == false) - codes.push_back(envLong); - if (envShortIncluded == false) - codes.push_back(envShort); + codes = environment; if (envShort != "en") codes.push_back("en"); + allCodes = codes; return codes; } @@ -192,26 +226,19 @@ std::vector const Configuration::getLanguages(bool const &All, for (std::vector::const_iterator l = lang.begin(); l != lang.end(); l++) { if (*l == "environment") { - if (envLongIncluded == true && envShortIncluded == true) - continue; - if (envLongIncluded == false) { - envLongIncluded = true; - if (noneSeen == false) - codes.push_back(envLong); - allCodes.push_back(envLong); - } - if (envShortIncluded == false) { - envShortIncluded = true; + for (std::vector::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(envShort); - allCodes.push_back(envShort); + codes.push_back(*e); + allCodes.push_back(*e); } continue; } else if (*l == "none") { noneSeen = true; continue; - } else if ((envLongIncluded == true && *l == envLong) || - (envShortIncluded == true && *l == envShort)) + } else if (std::find(allCodes.begin(), allCodes.end(), *l) != allCodes.end()) continue; if (noneSeen == false) diff --git a/apt-pkg/aptconfiguration.h b/apt-pkg/aptconfiguration.h index b6650e20c..dd339d841 100644 --- a/apt-pkg/aptconfiguration.h +++ b/apt-pkg/aptconfiguration.h @@ -64,7 +64,7 @@ public: /*{{{*/ * \return a vector of (all) Language Codes in the prefered usage order */ std::vector static const getLanguages(bool const &All = false, - bool const &Cached = true, char const * const Locale = 0); + bool const &Cached = true, char const ** const Locale = 0); /** \brief Returns a vector of Architectures we support * diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index b285a9f2e..d3d6e2739 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -1012,7 +1012,7 @@ vector ExplodeString(string const &haystack, char const &split) { do { for (; end != haystack.end() && *end != split; ++end); exploded.push_back(string(start, end)); - start = end; + start = end + 1; } while (end != haystack.end() && (++end) != haystack.end()); return exploded; } -- cgit v1.2.3 From 1a31359bfe4fdbf9ac1a25ab0b9f013d37099ac4 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 15 Feb 2010 13:05:53 +0100 Subject: * aptconfiguration.cc: - include all existing Translation files in the Cache (Closes: 564137) Previously if APT was executed with a different LC_* all these invocations needed to rebuild the Cache as too many files were included or missing: Now the lists-directory is checked for Translation-files and all these included in getLanguages() regardless of the environment setting (after a "none" so APT will not use them for displaying information). --- apt-pkg/aptconfiguration.cc | 78 +++++++++++++++++++++++++++++++++++++++++---- apt-pkg/deb/debmetaindex.cc | 5 ++- 2 files changed, 76 insertions(+), 7 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index f1989599b..429219cbd 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -14,9 +14,12 @@ #include #include -#include -#include +#include +#include + #include +#include +#include /*}}}*/ namespace APT { // getCompressionTypes - Return Vector of usbale compressiontypes /*{{{*/ @@ -119,6 +122,37 @@ std::vector const Configuration::getLanguages(bool const &All, } } + // 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 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 @@ -134,7 +168,11 @@ std::vector const Configuration::getLanguages(bool const &All, if (envLong == "C") { codes.push_back("en"); allCodes = codes; - return 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 @@ -159,8 +197,16 @@ std::vector const Configuration::getLanguages(bool const &All, if (oldAcquire.empty() == false && oldAcquire != "environment") { if (oldAcquire != "none") codes.push_back(oldAcquire); + codes.push_back("en"); allCodes = codes; - return codes; + for (std::vector::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, @@ -207,7 +253,14 @@ std::vector const Configuration::getLanguages(bool const &All, } else if (forceLang != "none") codes.push_back(forceLang); allCodes = codes; - return codes; + for (std::vector::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 const lang = _config->FindVector("Acquire::Languages"); @@ -217,7 +270,14 @@ std::vector const Configuration::getLanguages(bool const &All, if (envShort != "en") codes.push_back("en"); allCodes = codes; - return codes; + for (std::vector::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 @@ -245,6 +305,12 @@ std::vector const Configuration::getLanguages(bool const &All, codes.push_back(*l); allCodes.push_back(*l); } + + for (std::vector::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 diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index eb01a0156..0e4e6df9e 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -214,6 +214,7 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const s != sections.end(); ++s) for (set::const_iterator l = s->second.begin(); l != s->second.end(); l++) { + if (*l == "none") continue; debTranslationsIndex i = debTranslationsIndex(URI,Dist,s->first,(*l).c_str()); i.GetIndexes(Owner); } @@ -268,8 +269,10 @@ vector *debReleaseIndex::GetIndexFiles() { for (map >::const_iterator s = sections.begin(); s != sections.end(); ++s) for (set::const_iterator l = s->second.begin(); - l != s->second.end(); l++) + l != s->second.end(); l++) { + if (*l == "none") continue; Indexes->push_back(new debTranslationsIndex(URI,Dist,s->first,(*l).c_str())); + } return Indexes; } -- cgit v1.2.3 From 897165afb4681cff0e3a4bcb65f21b6d67718fbe Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 18 Feb 2010 00:04:26 +0100 Subject: * apt-pkg/deb/dpkgpm.cc: - stdin redirected to /dev/null takes all CPU (Closes: #569488) Thanks to Aurelien Jarno for providing (again) a patch! --- apt-pkg/deb/dpkgpm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 565f01b84..3dca2b209 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1005,7 +1005,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) -- cgit v1.2.3 From d7cf5923a093e89ab5aac0bf8cd1c3042997990c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 18 Feb 2010 00:30:51 +0100 Subject: dd support for the LANGUAGE environment variable --- apt-pkg/aptconfiguration.cc | 92 +++++++++++++++++++++++++++++---------------- apt-pkg/aptconfiguration.h | 2 +- apt-pkg/contrib/strutl.cc | 18 +++++++++ apt-pkg/contrib/strutl.h | 1 + 4 files changed, 80 insertions(+), 33 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 899004d9f..9fd51ad5a 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -8,9 +8,11 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#include #include #include +#include +#include +#include #include #include @@ -96,7 +98,7 @@ const Configuration::getCompressionTypes(bool const &Cached) { will result in "de_DE, de, en". The special word "none" is the stopcode for the not-All code vector */ std::vector const Configuration::getLanguages(bool const &All, - bool const &Cached, char const * const Locale) { + bool const &Cached, char const ** const Locale) { using std::string; // The detection is boring and has a lot of cornercases, @@ -117,27 +119,29 @@ std::vector const Configuration::getLanguages(bool const &All, } } - // get the environment language code + // 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); + 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('.') != string::npos) ? envMsg.find('.') : (lenShort + 3); + 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, envShortIncluded = false; + bool envLongIncluded = true; // first cornercase: LANG=C, so we use only "en" Translation if (envLong == "C") { codes.push_back("en"); + allCodes = codes; 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) { - // 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... - char const *needLong[] = { "cs", "en", "pt", "sv", "zh", NULL }; for (char const **l = needLong; *l != NULL; l++) if (envShort.compare(*l) == 0) { envLongIncluded = false; @@ -155,33 +159,64 @@ std::vector const Configuration::getLanguages(bool const &All, if (oldAcquire.empty() == false && oldAcquire != "environment") { if (oldAcquire != "none") codes.push_back(oldAcquire); + allCodes = codes; 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 environment; + // take care of LC_MESSAGES + if (envLongIncluded == false) + environment.push_back(envLong); + environment.push_back(envShort); + // take care of LANGUAGE + string envLang = Locale == 0 ? getenv("LANGUAGE") : *(Locale+1); + if (envLang.empty() == false) { + std::vector env = ExplodeString(envLang,':'); + short addedLangs = 0; // add a maximum of 3 fallbacks from the environment + for (std::vector::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") { - if (envLongIncluded == false) - codes.push_back(envLong); - if (envShortIncluded == false) - codes.push_back(envShort); - return codes; + codes = environment; } else if (forceLang != "none") codes.push_back(forceLang); + allCodes = codes; return codes; } std::vector const lang = _config->FindVector("Acquire::Languages"); // the default setting -> "environment, en" if (lang.empty() == true) { - if (envLongIncluded == false) - codes.push_back(envLong); - if (envShortIncluded == false) - codes.push_back(envShort); + codes = environment; if (envShort != "en") codes.push_back("en"); + allCodes = codes; return codes; } @@ -191,26 +226,19 @@ std::vector const Configuration::getLanguages(bool const &All, for (std::vector::const_iterator l = lang.begin(); l != lang.end(); l++) { if (*l == "environment") { - if (envLongIncluded == true && envShortIncluded == true) - continue; - if (envLongIncluded == false) { - envLongIncluded = true; - if (noneSeen == false) - codes.push_back(envLong); - allCodes.push_back(envLong); - } - if (envShortIncluded == false) { - envShortIncluded = true; + for (std::vector::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(envShort); - allCodes.push_back(envShort); + codes.push_back(*e); + allCodes.push_back(*e); } continue; } else if (*l == "none") { noneSeen = true; continue; - } else if ((envLongIncluded == true && *l == envLong) || - (envShortIncluded == true && *l == envShort)) + } else if (std::find(allCodes.begin(), allCodes.end(), *l) != allCodes.end()) continue; if (noneSeen == false) diff --git a/apt-pkg/aptconfiguration.h b/apt-pkg/aptconfiguration.h index f2f04a39b..2ba1b3825 100644 --- a/apt-pkg/aptconfiguration.h +++ b/apt-pkg/aptconfiguration.h @@ -64,7 +64,7 @@ public: /*{{{*/ * \return a vector of (all) Language Codes in the prefered usage order */ std::vector static const getLanguages(bool const &All = false, - bool const &Cached = true, char const * const Locale = 0); + bool const &Cached = true, char const ** const Locale = 0); /*}}}*/ }; diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 2913fbf44..3bbaf5f30 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 ExplodeString(string const &haystack, char const &split) +{ + string::const_iterator start = haystack.begin(); + string::const_iterator end = start; + vector 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 2b2e147fb..d65f975d2 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 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; -- cgit v1.2.3 From 3f2d77b5e02c5749a78ad9852c01cfad4ce0fda1 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 18 Feb 2010 00:35:25 +0100 Subject: * aptconfiguration.cc: - include all existing Translation files in the Cache (Closes: 564137) Previously if APT was executed with a different LC_* all these invocations needed to rebuild the Cache as too many files were included or missing: Now the lists-directory is checked for Translation-files and all these will be included in getLanguages() regardless of the environment setting (after a "none" so APT will not use them for displaying information). --- apt-pkg/aptconfiguration.cc | 78 +++++++++++++++++++++++++++++++++++++++++---- apt-pkg/deb/debmetaindex.cc | 5 ++- 2 files changed, 76 insertions(+), 7 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 9fd51ad5a..b5f29472d 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -14,9 +14,12 @@ #include #include -#include -#include +#include +#include + #include +#include +#include /*}}}*/ namespace APT { // getCompressionTypes - Return Vector of usbale compressiontypes /*{{{*/ @@ -119,6 +122,37 @@ std::vector const Configuration::getLanguages(bool const &All, } } + // 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 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 @@ -134,7 +168,11 @@ std::vector const Configuration::getLanguages(bool const &All, if (envLong == "C") { codes.push_back("en"); allCodes = codes; - return 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 @@ -159,8 +197,16 @@ std::vector const Configuration::getLanguages(bool const &All, if (oldAcquire.empty() == false && oldAcquire != "environment") { if (oldAcquire != "none") codes.push_back(oldAcquire); + codes.push_back("en"); allCodes = codes; - return codes; + for (std::vector::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, @@ -207,7 +253,14 @@ std::vector const Configuration::getLanguages(bool const &All, } else if (forceLang != "none") codes.push_back(forceLang); allCodes = codes; - return codes; + for (std::vector::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 const lang = _config->FindVector("Acquire::Languages"); @@ -217,7 +270,14 @@ std::vector const Configuration::getLanguages(bool const &All, if (envShort != "en") codes.push_back("en"); allCodes = codes; - return codes; + for (std::vector::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 @@ -245,6 +305,12 @@ std::vector const Configuration::getLanguages(bool const &All, codes.push_back(*l); allCodes.push_back(*l); } + + for (std::vector::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 diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 8f28f053b..520e94a80 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -181,6 +181,7 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const for (vector::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); } @@ -219,8 +220,10 @@ vector *debReleaseIndex::GetIndexFiles() Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted())); for (vector::const_iterator l = lang.begin(); - l != lang.end(); l++) + l != lang.end(); l++) { + if (*l == "none") continue; Indexes->push_back(new debTranslationsIndex(URI,Dist,(*I)->Section,(*l).c_str())); + } } } -- cgit v1.2.3 From b7044b4b7483259f6dbca4fce56320dbde6da02a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 18 Feb 2010 00:55:35 +0100 Subject: doesn't use a default separator in ExplodeString (halfway losted in merge) --- apt-pkg/deb/debmetaindex.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 0e4e6df9e..947a7f04b 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -313,7 +313,7 @@ class debSLTypeDebian : public pkgSourceList::Type { map::const_iterator const arch = Options.find("arch"); vector const Archs = - (arch != Options.end()) ? ExplodeString(arch->second) : + (arch != Options.end()) ? ExplodeString(arch->second, ',') : APT::Configuration::getArchitectures(); for (vector::const_iterator I = List.begin(); -- cgit v1.2.3 From 44c8b5dff8871485d071f92cd154dc1c14c3c015 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 18 Feb 2010 01:37:59 +0100 Subject: we break the ABI, so let use increase the ABI number :) (This is the revert of the glibc-abi-compatibility-hack) --- apt-pkg/init.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') 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; -- cgit v1.2.3 From a100bb98eac562817ebb3139b82259cf0222cc2b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 18 Feb 2010 22:08:25 +0100 Subject: fix crash when LANGUAGE is not set --- apt-pkg/aptconfiguration.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index b5f29472d..10613f11d 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -217,7 +217,8 @@ std::vector const Configuration::getLanguages(bool const &All, environment.push_back(envLong); environment.push_back(envShort); // take care of LANGUAGE - string envLang = Locale == 0 ? getenv("LANGUAGE") : *(Locale+1); + const char *language_env = getenv("LANGUAGE") == 0 ? "" : getenv("LANGUAGE"); + string envLang = Locale == 0 ? language_env : *(Locale+1); if (envLang.empty() == false) { std::vector env = ExplodeString(envLang,':'); short addedLangs = 0; // add a maximum of 3 fallbacks from the environment -- cgit v1.2.3 From 75ce206243e409b170d06723430eb85a4a747882 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 26 Feb 2010 20:47:19 +0100 Subject: move ShowPkg() from apt-get to the PkgIterator and rename it to FullName() responseable for displaying a package name and the architecture in a uniform way. Pretty option can be used to not append the architecture if it is the native architecture or all - and use it all over the place in the commandline tools. --- apt-pkg/cacheiterators.h | 1 + apt-pkg/pkgcache.cc | 12 ++++++++++++ 2 files changed, 13 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 43cbe1377..a64326a44 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -151,6 +151,7 @@ class pkgCache::PkgIterator: public Iterator { //Nice printable representation friend std::ostream& operator <<(std::ostream& out, PkgIterator i); + std::string FullName(bool const &Pretty = false) const; // Constructors inline PkgIterator(pkgCache &Owner,Package *Trg) : Iterator(Owner, Trg), HashIndex(0) { diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 29c27b58e..24d9e0329 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -445,6 +445,18 @@ operator<<(ostream& out, pkgCache::PkgIterator Pkg) return out; } /*}}}*/ +// PkgIterator::FullName - Returns Name and (maybe) Architecture /*{{{*/ +// --------------------------------------------------------------------- +/* Returns a name:arch string */ +std::string pkgCache::PkgIterator::FullName(bool const &Pretty) const +{ + string fullname = Name(); + if (Pretty == false || + (strcmp(Arch(), "all") != 0 && _config->Find("APT::Architecture") != Arch())) + return fullname.append(":").append(Arch()); + return fullname; +} + /*}}}*/ // DepIterator::IsCritical - Returns true if the dep is important /*{{{*/ // --------------------------------------------------------------------- /* Currently critical deps are defined as depends, predepends and -- cgit v1.2.3 From 06afffcc24f339e8735acd4698af6e5995ad24aa Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 27 Feb 2010 02:02:25 +0100 Subject: =?UTF-8?q?*=20apt-pkg/contrib/mmap.{h,cc}:=20=20=20-=20add=20char?= =?UTF-8?q?[]=20fallback=20for=20filesystems=20without=20shared=20writable?= =?UTF-8?q?=20=20=20=20=20mmap()=20like=20JFFS2.=20Thanks=20to=20Marius=20?= =?UTF-8?q?Vollmer=20for=20writing=20=20=20=20=20and=20to=20Lo=C3=AFc=20Mi?= =?UTF-8?q?nier=20for=20pointing=20to=20the=20patch!=20(Closes:=20#314334)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apt-pkg/contrib/mmap.cc | 70 +++++++++++++++++++++++++++++++++++++++++-------- apt-pkg/contrib/mmap.h | 5 ++++ 2 files changed, 64 insertions(+), 11 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc index f440f9489..b3f29032c 100644 --- a/apt-pkg/contrib/mmap.cc +++ b/apt-pkg/contrib/mmap.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include /*}}}*/ @@ -35,7 +36,7 @@ // --------------------------------------------------------------------- /* */ MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0), - Base(0) + Base(0), SyncToFd(NULL) { if ((Flags & NoImmMap) != NoImmMap) Map(F); @@ -45,7 +46,7 @@ MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0), // --------------------------------------------------------------------- /* */ MMap::MMap(unsigned long Flags) : Flags(Flags), iSize(0), - Base(0) + Base(0), SyncToFd(NULL) { } /*}}}*/ @@ -78,7 +79,24 @@ bool MMap::Map(FileFd &Fd) // Map it. Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0); if (Base == (void *)-1) - return _error->Errno("mmap",_("Couldn't make mmap of %lu bytes"),iSize); + { + if (errno == ENODEV || errno == EINVAL) + { + // The filesystem doesn't support this particular kind of mmap. + // So we allocate a buffer and read the whole file into it. + int const dupped_fd = dup(Fd.Fd()); + if (dupped_fd == -1) + return _error->Errno("mmap", _("Couldn't duplicate file descriptor %i"), Fd.Fd()); + + Base = new unsigned char[iSize]; + SyncToFd = new FileFd (dupped_fd); + if (!SyncToFd->Seek(0L) || !SyncToFd->Read(Base, iSize)) + return false; + } + else + return _error->Errno("mmap",_("Couldn't make mmap of %lu bytes"), + iSize); + } return true; } @@ -93,10 +111,19 @@ bool MMap::Close(bool DoSync) if (DoSync == true) Sync(); - - if (munmap((char *)Base,iSize) != 0) - _error->Warning("Unable to munmap"); - + + if (SyncToFd != NULL) + { + delete[] (char *)Base; + delete SyncToFd; + SyncToFd = NULL; + } + else + { + if (munmap((char *)Base, iSize) != 0) + _error->WarningE("mmap", _("Unable to close mmap")); + } + iSize = 0; Base = 0; return true; @@ -113,8 +140,18 @@ bool MMap::Sync() #ifdef _POSIX_SYNCHRONIZED_IO if ((Flags & ReadOnly) != ReadOnly) - if (msync((char *)Base,iSize,MS_SYNC) < 0) - return _error->Errno("msync","Unable to write mmap"); + { + if (SyncToFd != NULL) + { + if (!SyncToFd->Seek(0) || !SyncToFd->Write(Base, iSize)) + return false; + } + else + { + if (msync((char *)Base, iSize, MS_SYNC) < 0) + return _error->Errno("msync", _("Unable to synchronize mmap")); + } + } #endif return true; } @@ -130,8 +167,19 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop) #ifdef _POSIX_SYNCHRONIZED_IO unsigned long PSize = sysconf(_SC_PAGESIZE); if ((Flags & ReadOnly) != ReadOnly) - if (msync((char *)Base+(int)(Start/PSize)*PSize,Stop - Start,MS_SYNC) < 0) - return _error->Errno("msync","Unable to write mmap"); + { + if (SyncToFd != 0) + { + if (!SyncToFd->Seek(0) || + !SyncToFd->Write (((char *)Base)+Start, Stop-Start)) + return false; + } + else + { + if (msync((char *)Base+(int)(Start/PSize)*PSize,Stop - Start,MS_SYNC) < 0) + return _error->Errno("msync", _("Unable to synchronize mmap")); + } + } #endif return true; } diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h index cd2b15ba2..5ca951204 100644 --- a/apt-pkg/contrib/mmap.h +++ b/apt-pkg/contrib/mmap.h @@ -44,6 +44,11 @@ class MMap unsigned long iSize; void *Base; + // In case mmap can not be used, we keep a dup of the file + // descriptor that should have been mmaped so that we can write to + // the file in Sync(). + FileFd *SyncToFd; + bool Map(FileFd &Fd); bool Close(bool DoSync = true); -- cgit v1.2.3 From e0b94b97b179812e5a0b3b72ea9fcae106d545c5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 27 Feb 2010 17:01:12 +0100 Subject: Enable the AutoRemover to talk "Multi-Arch" by marking all pseudo packages in a group if one is marked. The auto-installed flag is from now on Architecture bound: A section without an architecture tag will be treated as applying to all architectures - the next write operation will take care of this by creating separate sections for the architectures. --- apt-pkg/depcache.cc | 170 +++++++++++++++++++++++++++++++++------------------- apt-pkg/depcache.h | 4 +- 2 files changed, 109 insertions(+), 65 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index eeb74a434..45c614c6f 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -165,34 +165,46 @@ bool pkgDepCache::Init(OpProgress *Prog) bool pkgDepCache::readStateFile(OpProgress *Prog) /*{{{*/ { FileFd state_file; - string state = _config->FindDir("Dir::State") + "extended_states"; + string const state = _config->FindDir("Dir::State") + "extended_states"; if(FileExists(state)) { state_file.Open(state, FileFd::ReadOnly); - int file_size = state_file.Size(); + int const file_size = state_file.Size(); if(Prog != NULL) Prog->OverallProgress(0, file_size, 1, _("Reading state information")); pkgTagFile tagfile(&state_file); pkgTagSection section; - int amt=0; - bool debug_autoremove=_config->FindB("Debug::pkgAutoRemove",false); + int amt = 0; + bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false); while(tagfile.Step(section)) { - string pkgname = section.FindS("Package"); - pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname); - // Silently ignore unknown packages and packages with no actual - // version. - if(!pkg.end() && !pkg.VersionList().end()) { - short reason = section.FindI("Auto-Installed", 0); - if(reason > 0) - PkgState[pkg->ID].Flags |= Flag::Auto; - if(debug_autoremove) - std::cout << "Auto-Installed : " << pkgname << std::endl; - amt+=section.size(); - if(Prog != NULL) - Prog->OverallProgress(amt, file_size, 1, - _("Reading state information")); + string const pkgname = section.FindS("Package"); + string pkgarch = section.FindS("Architecture"); + if (pkgarch.empty() == true) + pkgarch = "any"; + pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch); + // Silently ignore unknown packages and packages with no actual version. + if(pkg.end() == true || pkg->VersionList == 0) + continue; + + short const reason = section.FindI("Auto-Installed", 0); + if(reason > 0) + { + PkgState[pkg->ID].Flags |= Flag::Auto; + if (unlikely(debug_autoremove)) + std::cout << "Auto-Installed : " << pkg.FullName() << std::endl; + if (pkgarch == "any") + { + pkgCache::GrpIterator G = pkg.Group(); + for (pkg = G.NextPkg(pkg); pkg.end() != true; pkg = G.NextPkg(pkg)) + if (pkg->VersionList != 0) + PkgState[pkg->ID].Flags |= Flag::Auto; + } } + amt += section.size(); + if(Prog != NULL) + Prog->OverallProgress(amt, file_size, 1, + _("Reading state information")); } if(Prog != NULL) Prog->OverallProgress(file_size, file_size, 1, @@ -204,13 +216,13 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) /*{{{*/ /*}}}*/ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/ { - bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false); + bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false); if(debug_autoremove) std::clog << "pkgDepCache::writeStateFile()" << std::endl; FileFd StateFile; - string state = _config->FindDir("Dir::State") + "extended_states"; + string const state = _config->FindDir("Dir::State") + "extended_states"; // if it does not exist, create a empty one if(!FileExists(state)) @@ -225,7 +237,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/ state.c_str()); FILE *OutFile; - string outfile = state + ".tmp"; + string const outfile = state + ".tmp"; if((OutFile = fopen(outfile.c_str(),"w")) == NULL) return _error->Error(_("Failed to write temporary StateFile %s"), outfile.c_str()); @@ -236,46 +248,54 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/ std::set pkgs_seen; const char *nullreorderlist[] = {0}; while(tagfile.Step(section)) { - string pkgname = section.FindS("Package"); + string const pkgname = section.FindS("Package"); + string pkgarch = section.FindS("Architecture"); + if (pkgarch.empty() == true) + pkgarch = "native"; // Silently ignore unknown packages and packages with no actual // version. - pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname); + pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch); if(pkg.end() || pkg.VersionList().end()) continue; - bool newAuto = (PkgState[pkg->ID].Flags & Flag::Auto); + bool const newAuto = (PkgState[pkg->ID].Flags & Flag::Auto); if(_config->FindB("Debug::pkgAutoRemove",false)) std::clog << "Update existing AutoInstall info: " - << pkg.Name() << std::endl; - TFRewriteData rewrite[2]; - rewrite[0].Tag = "Auto-Installed"; - rewrite[0].Rewrite = newAuto ? "1" : "0"; + << pkg.FullName() << std::endl; + TFRewriteData rewrite[3]; + rewrite[0].Tag = "Architecture"; + rewrite[0].Rewrite = pkg.Arch(); rewrite[0].NewTag = 0; - rewrite[1].Tag = 0; + rewrite[1].Tag = "Auto-Installed"; + rewrite[1].Rewrite = newAuto ? "1" : "0"; + rewrite[1].NewTag = 0; + rewrite[2].Tag = 0; TFRewrite(OutFile, section, nullreorderlist, rewrite); fprintf(OutFile,"\n"); - pkgs_seen.insert(pkgname); + pkgs_seen.insert(pkg.FullName()); } // then write the ones we have not seen yet std::ostringstream ostr; for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); pkg++) { if(PkgState[pkg->ID].Flags & Flag::Auto) { - if (pkgs_seen.find(pkg.Name()) != pkgs_seen.end()) { + if (pkgs_seen.find(pkg.FullName()) != pkgs_seen.end()) { if(debug_autoremove) - std::clog << "Skipping already written " << pkg.Name() << std::endl; + std::clog << "Skipping already written " << pkg.FullName() << std::endl; continue; } - // skip not installed ones if requested - if(InstalledOnly && pkg->CurrentVer == 0) - continue; + // skip not installed ones if requested + if(InstalledOnly && pkg->CurrentVer == 0) + continue; + const char* const pkgarch = pkg.Arch(); + if (strcmp(pkgarch, "all") == 0) + continue; if(debug_autoremove) - std::clog << "Writing new AutoInstall: " - << pkg.Name() << std::endl; + std::clog << "Writing new AutoInstall: " << pkg.FullName() << std::endl; ostr.str(string("")); - ostr << "Package: " << pkg.Name() + ostr << "Package: " << pkg.Name() + << "\nArchitecture: " << pkgarch << "\nAuto-Installed: 1\n\n"; fprintf(OutFile,"%s",ostr.str().c_str()); - fprintf(OutFile,"\n"); } } fclose(OutFile); @@ -1426,7 +1446,7 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) // debug output if(debug_autoremove && PkgState[p->ID].Flags & Flag::Auto) - std::clog << "AutoDep: " << p.Name() << std::endl; + std::clog << "AutoDep: " << p.FullName() << std::endl; } // init vars @@ -1460,13 +1480,18 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) // MarkPackage - mark a single package in Mark-and-Sweep /*{{{*/ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg, const pkgCache::VerIterator &ver, - bool follow_recommends, - bool follow_suggests) + bool const &follow_recommends, + bool const &follow_suggests) { pkgDepCache::StateCache &state = PkgState[pkg->ID]; - VerIterator currver = pkg.CurrentVer(); - VerIterator candver = state.CandidateVerIter(*this); - VerIterator instver = state.InstVerIter(*this); + + // if we are marked already we are done + if(state.Marked) + return; + + VerIterator const currver = pkg.CurrentVer(); + VerIterator const candver = state.CandidateVerIter(*this); + VerIterator const instver = state.InstVerIter(*this); #if 0 // If a package was garbage-collected but is now being marked, we @@ -1492,15 +1517,11 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg, !(ver == currver && instver.end() && !ver.end())) return; - // if we are marked already we are done - if(state.Marked) - return; + bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove", false); - bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove", false); - if(debug_autoremove) { - std::clog << "Marking: " << pkg.Name(); + std::clog << "Marking: " << pkg.FullName(); if(!ver.end()) std::clog << " " << ver.VerStr(); if(!currver.end()) @@ -1512,8 +1533,34 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg, state.Marked=true; - if(!ver.end()) + if(ver.end() == true) + return; + + // If the version belongs to a Multi-Arch all package + // we will mark all others in this Group with this version also + // Beware: We compare versions here the lazy way: string comparision + // this is bad if multiple repositories provide different versions + // of the package with an identical version number - but even in this + // case the dependencies are likely the same. + if (ver->MultiArch == pkgCache::Version::All && + strcmp(ver.Arch(true), "all") == 0) { + GrpIterator G = pkg.Group(); + const char* const VerStr = ver.VerStr(); + for (PkgIterator P = G.FindPkg("any"); + P.end() != true; P = G.NextPkg(P)) + { + for (VerIterator V = P.VersionList(); + V.end() != true; ++V) + { + if (strcmp(VerStr, V.VerStr()) != 0) + continue; + MarkPackage(P, V, follow_recommends, follow_suggests); + break; + } + } + } + for(DepIterator d = ver.DependsList(); !d.end(); ++d) { if(d->Type == Dep::Depends || @@ -1531,10 +1578,9 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg, { if(debug_autoremove) { - std::clog << "Following dep: " << d.ParentPkg().Name() + std::clog << "Following dep: " << d.ParentPkg().FullName() << " " << d.ParentVer().VerStr() << " " - << d.DepType() << " " - << d.TargetPkg().Name(); + << d.DepType() << " " << d.TargetPkg().FullName(); if((d->CompareOp & ~pkgCache::Dep::Or) != pkgCache::Dep::NoOp) { std::clog << " (" << d.CompType() << " " @@ -1542,7 +1588,7 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg, } std::clog << std::endl; } - MarkPackage(V.ParentPkg(), V, + MarkPackage(V.ParentPkg(), V, follow_recommends, follow_suggests); } } @@ -1555,17 +1601,16 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg, { if(debug_autoremove) { - std::clog << "Following dep: " << d.ParentPkg().Name() - << " " << d.ParentVer().VerStr() << " " - << d.DepType() << " " - << d.TargetPkg().Name(); + std::clog << "Following dep: " << d.ParentPkg().FullName() << " " + << d.ParentVer().VerStr() << " " + << d.DepType() << " " << d.TargetPkg().FullName() << " "; if((d->CompareOp & ~pkgCache::Dep::Or) != pkgCache::Dep::NoOp) { std::clog << " (" << d.CompType() << " " << d.TargetVer() << ")"; } std::clog << ", provided by " - << prv.OwnerPkg().Name() << " " + << prv.OwnerPkg().FullName() << " " << prv.OwnerVer().VerStr() << std::endl; } @@ -1576,7 +1621,6 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg, } } } - } } /*}}}*/ bool pkgDepCache::Sweep() /*{{{*/ @@ -1598,7 +1642,7 @@ bool pkgDepCache::Sweep() /*{{{*/ { state.Garbage=true; if(debug_autoremove) - std::cout << "Garbage: " << p.Name() << std::endl; + std::cout << "Garbage: " << p.FullName() << std::endl; } } diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index ab1021a44..23b29cc13 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -79,8 +79,8 @@ class pkgDepCache : protected pkgCache::Namespace */ void MarkPackage(const pkgCache::PkgIterator &pkg, const pkgCache::VerIterator &ver, - bool follow_recommends, - bool follow_suggests); + bool const &follow_recommends, + bool const &follow_suggests); /** \brief Update the Marked field of all packages. * -- cgit v1.2.3 From a04cd1f9a580867d65be8f1ecb3eac25a86eb953 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 28 Feb 2010 19:45:05 +0100 Subject: Fix the PkgFileIterator Constructor which defaults to the wrong value. (0 instead of the HeaderP) This breaks the Cache Validation functionality as the end() doesn't test for NULL. (The fault was introduced with the rewriting of the CacheIterators) --- apt-pkg/cacheiterators.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index a64326a44..28e062f3c 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -345,7 +345,8 @@ class pkgCache::PkgFileIterator : public Iterator // Constructors inline PkgFileIterator() : Iterator() {}; - inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg = 0) : Iterator(Owner, Trg) {}; + inline PkgFileIterator(pkgCache &Owner) : Iterator(Owner, Owner.PkgFileP) {}; + inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Iterator(Owner, Trg) {}; }; /*}}}*/ // Version File /*{{{*/ -- cgit v1.2.3 From 4a6d21639f807ae82d5a51a92c4bbbd0ca2a4494 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 28 Feb 2010 22:45:34 +0100 Subject: Create Pins for all group members instead of only for native architecture --- apt-pkg/policy.cc | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index f9901bc9a..0b8c1a81b 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -187,35 +187,38 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator Pkg) void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name, string Data,signed short Priority) { - Pin *P = 0; - if (Name.empty() == true) - P = &*Defaults.insert(Defaults.end(),PkgPin()); - else { - // Get a spot to put the pin - pkgCache::PkgIterator Pkg = Cache->FindPkg(Name); - if (Pkg.end() == true) + Pin *P = &*Defaults.insert(Defaults.end(),PkgPin()); + P->Type = Type; + P->Priority = Priority; + P->Data = Data; + return; + } + + // Get a spot to put the pin + pkgCache::GrpIterator Grp = Cache->FindGrp(Name); + for (pkgCache::PkgIterator Pkg = Grp.FindPkg("any"); + Pkg.end() != true; Pkg = Grp.NextPkg(Pkg)) + { + Pin *P = 0; + if (Pkg.end() == false) + P = Pins + Pkg->ID; + else { // Check the unmatched table - for (vector::iterator I = Unmatched.begin(); + for (vector::iterator I = Unmatched.begin(); I != Unmatched.end() && P == 0; I++) if (I->Pkg == Name) P = &*I; - + if (P == 0) - P = &*Unmatched.insert(Unmatched.end(),PkgPin()); + P = &*Unmatched.insert(Unmatched.end(),PkgPin()); } - else - { - P = Pins + Pkg->ID; - } + P->Type = Type; + P->Priority = Priority; + P->Data = Data; } - - // Set.. - P->Type = Type; - P->Priority = Priority; - P->Data = Data; } /*}}}*/ // Policy::GetMatch - Get the matching version for a package pin /*{{{*/ -- cgit v1.2.3 From 70ae240915df3ef89715d71d5fe7a6910cbf057e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 1 Mar 2010 15:27:55 +0100 Subject: Remove and Unpack operations should not be ignored for pseudo packages - they should trigger the remove/unpack of the "all" package. Otherwise - as this package has no dependencies - it will be triggered to late. The Configuration step doesn't need it as the "all" package is a dependency of the pseudo-package, so it will be configured before the pseudo packages are tried: So at this step the ignorance is okay. Also IsMissing() should report the status of the all package if an pseudo package is checked instead of always reporting no-miss. --- apt-pkg/orderlist.cc | 11 ++++++----- apt-pkg/packagemanager.cc | 13 +++++++++---- 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc index 2e7618b55..7c950292a 100644 --- a/apt-pkg/orderlist.cc +++ b/apt-pkg/orderlist.cc @@ -127,8 +127,9 @@ bool pkgOrderList::IsMissing(PkgIterator Pkg) if (FileList[Pkg->ID].empty() == false) return false; + // Missing Pseudo packages are missing if the real package is missing if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == true) - return false; + return IsMissing(Pkg.Group().FindPkg("all")); return true; } @@ -203,7 +204,7 @@ bool pkgOrderList::OrderCritical() { PkgIterator P(Cache,*I); if (IsNow(P) == true) - clog << " " << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl; + clog << " " << P.FullName() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl; } } @@ -276,7 +277,7 @@ bool pkgOrderList::OrderUnpack(string *FileList) { PkgIterator P(Cache,*I); if (IsNow(P) == true) - clog << " " << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl; + clog << " " << P.FullName() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl; } } @@ -547,7 +548,7 @@ bool pkgOrderList::VisitNode(PkgIterator Pkg) if (Debug == true) { for (int j = 0; j != Depth; j++) clog << ' '; - clog << "Visit " << Pkg.Name() << endl; + clog << "Visit " << Pkg.FullName() << endl; } Depth++; @@ -606,7 +607,7 @@ bool pkgOrderList::VisitNode(PkgIterator Pkg) if (Debug == true) { for (int j = 0; j != Depth; j++) clog << ' '; - clog << "Leave " << Pkg.Name() << ' ' << IsFlag(Pkg,Added) << ',' << IsFlag(Pkg,AddPending) << endl; + clog << "Leave " << Pkg.FullName() << ' ' << IsFlag(Pkg,Added) << ',' << IsFlag(Pkg,AddPending) << endl; } return true; diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index db882721e..35cc24550 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -470,6 +470,8 @@ bool pkgPackageManager::SmartRemove(PkgIterator Pkg) if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false) return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge); + else + return SmartRemove(Pkg.Group().FindPkg("all")); return true; } /*}}}*/ @@ -584,11 +586,14 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) for (PrvIterator P = Cache[Pkg].InstVerIter(Cache).ProvidesList(); P.end() == false; P++) CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion()); - - if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false && - Install(Pkg,FileNames[Pkg->ID]) == false) + + if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false) + { + if(Install(Pkg,FileNames[Pkg->ID]) == false) + return false; + } else if (SmartUnPack(Pkg.Group().FindPkg("all")) == false) return false; - + List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); // Perform immedate configuration of the package. -- cgit v1.2.3 From 1ec1653cd4849423e0d5f769ecbfab2d6f16c4ad Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 1 Mar 2010 21:59:03 +0100 Subject: We need to kill also pseudo packages which have no dependency, no installed reverse dependency and which also doesn't provide something. They cause problems if this pseudo packages get new dependencies. As a consequence we also need to recheck the dependencies of a killed pseudo package (and especially the providers of these dependencies) to really kill all non required packages. --- apt-pkg/depcache.cc | 77 ++++++++++++++++++++++++++++++++++++++++++++--------- apt-pkg/depcache.h | 1 + 2 files changed, 66 insertions(+), 12 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 45c614c6f..893164ea1 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -630,11 +630,46 @@ bool pkgDepCache::RemovePseudoInstalledPkg(PkgIterator &Pkg, std::setMultiArch != Version::All) return false; - unsigned char const DepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy); - if ((DepState & DepInstMin) == DepInstMin) + // Never ever kill an "all" package - they have no dependency so they can't be broken + if (strcmp(Pkg.Arch(),"all") == 0) return false; - // Dependencies for this arch all are not statisfied +// std::cout << "CHECK " << Pkg << std::endl; + + unsigned char const DepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy); + if ((DepState & DepInstMin) == DepInstMin) { + // okay, the package isn't broken, but is the package also required? + // If it has no real dependencies, no installed rdepends and doesn't + // provide something of value, we will kill it as not required. + // These pseudopackages have otherwise interesting effects if they get + // a new dependency in a newer version… + for (pkgCache::DepIterator D = V.DependsList(); + D.end() != true; ++D) + if ((D->Type == pkgCache::Dep::Depends || + D->Type == pkgCache::Dep::PreDepends) && + D.ParentPkg()->Group != Pkg->Group) + return false; + for (DepIterator D = Pkg.RevDependsList(); D.end() != true; ++D) + { + if (D->Type != pkgCache::Dep::Depends && + D->Type != pkgCache::Dep::PreDepends) + continue; + PkgIterator const P = D.ParentPkg(); + if (P->CurrentVer != 0) + return false; + } + for (PrvIterator Prv = V.ProvidesList(); Prv.end() != true; Prv++) + for (DepIterator d = Prv.ParentPkg().RevDependsList(); + d.end() != true; ++d) + { + PkgIterator const P = d.ParentPkg(); + if (P->CurrentVer != 0 && + P->Group != Pkg->Group) + return false; + } + } + + // Dependencies for this arch all package are not statisfied // so we installed it only for our convenience: get right of it now. RemoveSizes(Pkg); RemoveStates(Pkg); @@ -655,15 +690,33 @@ bool pkgDepCache::RemovePseudoInstalledPkg(PkgIterator &Pkg, std::setCurrentVer != 0) - recheck.insert(P.Index()); - } + for (DepIterator d = V.DependsList(); d.end() != true; ++d) + { + PkgIterator const P = d.TargetPkg(); + for (PrvIterator Prv = P.ProvidesList(); Prv.end() != true; ++Prv) + { + PkgIterator const O = Prv.OwnerPkg(); + if (O->CurrentVer != 0) + recheck.insert(O.Index()); + } + + if (P->CurrentVer != 0) + recheck.insert(P.Index()); + } + + for (PrvIterator Prv = V.ProvidesList(); Prv.end() != true; Prv++) + { + for (DepIterator d = Prv.ParentPkg().RevDependsList(); + d.end() != true; ++d) + { + PkgIterator const P = d.ParentPkg(); + if (P->CurrentVer == 0) + continue; + + recheck.insert(P.Index()); + } + } + return true; } diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 23b29cc13..ea605f199 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -332,6 +332,7 @@ class pkgDepCache : protected pkgCache::Namespace inline operator pkgCache &() {return *Cache;}; inline Header &Head() {return *Cache->HeaderP;}; inline PkgIterator PkgBegin() {return Cache->PkgBegin();}; + inline GrpIterator FindGrp(string const &Name) {return Cache->FindGrp(Name);}; inline PkgIterator FindPkg(string const &Name) {return Cache->FindPkg(Name);}; inline PkgIterator FindPkg(string const &Name, string const &Arch) {return Cache->FindPkg(Name, Arch);}; -- cgit v1.2.3 From 5e5d20643487fd1693af418bd1201be5802c232d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 1 Mar 2010 22:47:17 +0100 Subject: fix compiler error if compiled with -std=c++0x --- apt-pkg/algorithms.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index c905cffa9..f8a9e210c 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -535,11 +535,11 @@ void pkgProblemResolver::MakeScores() // Important Required Standard Optional Extra signed short PrioMap[] = { 0, - _config->FindI("pkgProblemResolver::Scores::Important",3), - _config->FindI("pkgProblemResolver::Scores::Required",2), - _config->FindI("pkgProblemResolver::Scores::Standard",1), - _config->FindI("pkgProblemResolver::Scores::Optional",-1), - _config->FindI("pkgProblemResolver::Scores::Extra",-2) + (signed short) _config->FindI("pkgProblemResolver::Scores::Important",3), + (signed short) _config->FindI("pkgProblemResolver::Scores::Required",2), + (signed short) _config->FindI("pkgProblemResolver::Scores::Standard",1), + (signed short) _config->FindI("pkgProblemResolver::Scores::Optional",-1), + (signed short) _config->FindI("pkgProblemResolver::Scores::Extra",-2) }; signed short PrioEssentials = _config->FindI("pkgProblemResolver::Scores::Essentials",100); signed short PrioInstalledAndNotObsolete = _config->FindI("pkgProblemResolver::Scores::NotObsolete",1); -- cgit v1.2.3 From cf0e078c440226e0009bb861486b974a03842f7b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 3 Mar 2010 21:29:01 +0100 Subject: fix memory leak in getLanguages() by closing the directory after checking --- apt-pkg/aptconfiguration.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 10613f11d..f3f94dce3 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -152,6 +152,7 @@ std::vector const Configuration::getLanguages(bool const &All, builtin.push_back(c); } } + closedir(D); // get the environment language codes: LC_MESSAGES (and later LANGUAGE) // we extract both, a long and a short code and then we will -- cgit v1.2.3 From 569cc9349d26cc6a886111023df21ba569b1ffbe Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 12 Mar 2010 10:56:25 +0100 Subject: * apt-pkg/deb/dpkgpm.cc: - fix error message construction in OpenLog() --- apt-pkg/deb/dpkgpm.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index fb6054f79..ad1ea77fd 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -564,35 +564,37 @@ void pkgDPkgPM::WriteHistoryTag(string tag, string value) // DPkgPM::OpenLog /*{{{*/ bool pkgDPkgPM::OpenLog() { - string logdir = _config->FindDir("Dir::Log"); + string const logdir = _config->FindDir("Dir::Log"); if(not FileExists(logdir)) return _error->Error(_("Directory '%s' missing"), logdir.c_str()); // get current time char timestr[200]; - time_t t = time(NULL); - struct tm *tmp = localtime(&t); + time_t const t = time(NULL); + struct tm const * const tmp = localtime(&t); strftime(timestr, sizeof(timestr), "%F %T", tmp); // open terminal log - string logfile_name = flCombine(logdir, + string const logfile_name = flCombine(logdir, _config->Find("Dir::Log::Terminal")); if (!logfile_name.empty()) { term_out = fopen(logfile_name.c_str(),"a"); if (term_out == NULL) - return _error->WarningE(_("Could not open file '%s'"), logfile_name.c_str()); + return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str()); chmod(logfile_name.c_str(), 0600); fprintf(term_out, "\nLog started: %s\n", timestr); } - // write - string history_name = flCombine(logdir, + // write your history + string const history_name = flCombine(logdir, _config->Find("Dir::Log::History")); if (!history_name.empty()) { history_out = fopen(history_name.c_str(),"a"); + if (history_out == NULL) + return _error->WarningE("OpenLog", _("Could not open file '%s'"), history_name.c_str()); chmod(history_name.c_str(), 0644); fprintf(history_out, "\nStart-Date: %s\n", timestr); string remove, purge, install, upgrade, downgrade; -- cgit v1.2.3 From 3a4477a4241bcfbc9db541cf34cc75c1f1111b78 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 12 Mar 2010 11:08:13 +0100 Subject: * cmdline/apt-get.cc - fix memory leaks in error conditions in DoSource() --- apt-pkg/cdrom.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc index 96d4e9c91..783ffc430 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -289,7 +289,8 @@ bool pkgCdrom::DropRepeats(vector &List,const char *Name) List[J] = string(); } } - + delete[] Inodes; + // Wipe erased entries for (unsigned int I = 0; I < List.size();) { -- cgit v1.2.3 From 2bb255740bf18b5e0524fe833523303abb5c9051 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 12 Mar 2010 19:41:30 +0100 Subject: * apt-pkg/deb/dpkgpm.cc: - if available store the Commandline in the history * apt-pkg/contrib/cmndline.cc: - save Commandline in Commandline::AsString for logging --- apt-pkg/contrib/cmndline.cc | 42 +++++++++++++++++++++++++++++++++++++++++- apt-pkg/contrib/cmndline.h | 1 + apt-pkg/deb/dpkgpm.cc | 2 ++ 3 files changed, 44 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/cmndline.cc b/apt-pkg/contrib/cmndline.cc index bfd53695e..0b16bf51a 100644 --- a/apt-pkg/contrib/cmndline.cc +++ b/apt-pkg/contrib/cmndline.cc @@ -135,7 +135,9 @@ bool CommandLine::Parse(int argc,const char **argv) for (; I != argc; I++) *Files++ = argv[I]; *Files = 0; - + + SaveInConfig(argc, argv); + return true; } /*}}}*/ @@ -351,3 +353,41 @@ bool CommandLine::DispatchArg(Dispatch *Map,bool NoMatch) return false; } /*}}}*/ +// CommandLine::SaveInConfig - for output later in a logfile or so /*{{{*/ +// --------------------------------------------------------------------- +/* We save the commandline here to have it around later for e.g. logging. + It feels a bit like a hack here and isn't bulletproof, but it is better + than nothing after all. */ +void CommandLine::SaveInConfig(unsigned int const &argc, char const * const * const argv) +{ + char cmdline[300]; + unsigned int length = 0; + bool lastWasOption = false; + bool closeQuote = false; + for (unsigned int i = 0; i < argc; ++i, ++length) + { + for (unsigned int j = 0; argv[i][j] != '\0' && length < sizeof(cmdline)-1; ++j, ++length) + { + cmdline[length] = argv[i][j]; + if (lastWasOption == true && argv[i][j] == '=') + { + // That is possibly an option: Quote it if it includes spaces, + // the benefit is that this will eliminate also most false positives + const char* c = &argv[i][j+1]; + for (; *c != '\0' && *c != ' '; ++c); + if (*c == '\0') continue; + cmdline[++length] = '"'; + closeQuote = true; + } + } + if (closeQuote == true) + cmdline[length++] = '"'; + // Problem: detects also --hello + if (cmdline[length-1] == 'o') + lastWasOption = true; + cmdline[length] = ' '; + } + cmdline[--length] = '\0'; + _config->Set("CommandLine::AsString", cmdline); +} + /*}}}*/ diff --git a/apt-pkg/contrib/cmndline.h b/apt-pkg/contrib/cmndline.h index e28071e81..7c0c71aa7 100644 --- a/apt-pkg/contrib/cmndline.h +++ b/apt-pkg/contrib/cmndline.h @@ -60,6 +60,7 @@ class CommandLine Configuration *Conf; bool HandleOpt(int &I,int argc,const char *argv[], const char *&Opt,Args *A,bool PreceedeMatch = false); + void static SaveInConfig(unsigned int const &argc, char const * const * const argv); public: diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index ad1ea77fd..9ba60060c 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -614,6 +614,8 @@ bool pkgDPkgPM::OpenLog() remove += I.Name() + string(" (") + Cache[I].CurVersion + string("), "); } } + if (_config->Exists("Commandline::AsString") == true) + WriteHistoryTag("Commandline", _config->Find("Commandline::AsString")); WriteHistoryTag("Install", install); WriteHistoryTag("Upgrade", upgrade); WriteHistoryTag("Downgrade",downgrade); -- cgit v1.2.3 From ea5624c3d04c35f5a269b6f7431c135330c9b9b5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 13 Mar 2010 14:11:22 +0100 Subject: * apt-pkg/deb/debversion.cc: - consider absent of debian revision equivalent to 0 (Closes: #573592) This moves the existing testcase for version comparison to "my" directory, adds a few more tests (e.g. the tests used in cupt) and rewrites the testcases runner: The runner does now call dpkg --compare-versions to check what dpkg thinks about the comparison - all done in less code ;) --- apt-pkg/deb/debversion.cc | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debversion.cc b/apt-pkg/deb/debversion.cc index ad45e9a44..755ffbe96 100644 --- a/apt-pkg/deb/debversion.cc +++ b/apt-pkg/deb/debversion.cc @@ -190,8 +190,22 @@ int debVersioningSystem::DoCmpVersion(const char *A,const char *AEnd, dlhs++; if (drhs != rhs) drhs++; - - return CmpFragment(dlhs,AEnd,drhs,BEnd); + + // no debian revision need to be treated like -0 + if (*(dlhs-1) == '-' && *(drhs-1) == '-') + return CmpFragment(dlhs,AEnd,drhs,BEnd); + else if (*(dlhs-1) == '-') + { + const char* null = "0"; + return CmpFragment(dlhs,AEnd,null, null+1); + } + else if (*(drhs-1) == '-') + { + const char* null = "0"; + return CmpFragment(null, null+1, drhs, BEnd); + } + else + return 0; } /*}}}*/ // debVS::CheckDep - Check a single dependency /*{{{*/ -- cgit v1.2.3 From 1f530ccb32c17b70b05dd5feee706dc1098a7251 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 14 Mar 2010 14:45:00 +0100 Subject: Ensure that for each all package at least one pseudopackage is installed Removing pseudo packages is cool so far, the problem is that we will remove with the not required removing so many pseudo packages that we will have after the remove a few packages with NO installed pseudo package (e.g. metapackages are good candidates) - so we will walk over all these packages and try to find a pseudopackage for this package we can install without breaking something. --- apt-pkg/depcache.cc | 77 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 9 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 893164ea1..ffa4fe71c 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -634,10 +634,8 @@ bool pkgDepCache::RemovePseudoInstalledPkg(PkgIterator &Pkg, std::setType == pkgCache::Dep::Depends || - D->Type == pkgCache::Dep::PreDepends) && - D.ParentPkg()->Group != Pkg->Group) + if (D.IsCritical() == true && D.ParentPkg()->Group != Pkg->Group) return false; for (DepIterator D = Pkg.RevDependsList(); D.end() != true; ++D) { - if (D->Type != pkgCache::Dep::Depends && - D->Type != pkgCache::Dep::PreDepends) + if (D.IsCritical() == false) continue; PkgIterator const P = D.ParentPkg(); + if (P->Group == Pkg->Group) + continue; if (P->CurrentVer != 0) return false; } @@ -800,6 +797,68 @@ void pkgDepCache::Update(OpProgress *Prog) } recheck.erase(p); } + + /* Okay, we have killed a great amount of pseudopackages - + we have killed so many that we have now arch "all" packages + without an installed pseudo package, but we NEED an installed + pseudo package, so we will search now for a pseudo package + we can install without breaking everything. */ + for (GrpIterator G = Cache->GrpBegin(); G.end() != true; ++G) + { + PkgIterator P = G.FindPkg("all"); + if (P.end() == true) + continue; + if (P->CurrentVer == 0) + continue; + bool installed = false; + for (P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P)) + { + if (strcmp(P.Arch(), "all") == 0) + continue; + if (P->CurrentVer == 0) + continue; + installed = true; + break; + } + if (installed == false) + recheck.insert(G.Index()); + } + std::vector Archs = APT::Configuration::getArchitectures(); + bool checkChanged = false; + do { + for(std::set::const_iterator g = recheck.begin(); + g != recheck.end(); ++g) { + GrpIterator G = GrpIterator(*Cache, Cache->GrpP + *g); + VerIterator allV = G.FindPkg("all").CurrentVer(); + for (std::vector::const_iterator a = Archs.begin(); + a != Archs.end(); ++a) + { + PkgIterator P = G.FindPkg(*a); + if (P.end() == true) continue; + for (VerIterator V = P.VersionList(); V.end() != true; ++V) + { + // FIXME: String comparison isn't a save indicator! + if (strcmp(allV.VerStr(),V.VerStr()) != 0) + continue; + unsigned char const CurDepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy); + if ((CurDepState & DepInstMin) != DepInstMin) + break; // we found the correct version, but it is broken. Better try another arch or later again + P->CurrentVer = V.Index(); + AddStates(P); + Update(P); + AddSizes(P); + checkChanged = true; + break; + } + } + recheck.erase(g); + } + } while (checkChanged == true && recheck.empty() == false); + + if (_config->FindB("Debug::MultiArchKiller", false) == true) + for(std::set::const_iterator g = recheck.begin(); + g != recheck.end(); ++g) + std::cout << "No pseudo package for »" << GrpIterator(*Cache, Cache->GrpP + *g).Name() << "« installed" << std::endl; } if (Prog != 0) -- cgit v1.2.3 From c176c4d0adad246ac0768f9e2b60aa8e4c56fffb Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 14 Mar 2010 21:48:14 +0100 Subject: * apt-pkg/depcache.cc: - remove Auto-Installed information from extended_states together with the package itself (Closes: #572364) --- apt-pkg/depcache.cc | 31 ++++++++++++++++++++++++------- apt-pkg/depcache.h | 2 +- apt-pkg/tagfile.cc | 13 ++----------- apt-pkg/tagfile.h | 15 ++++++++++++++- 4 files changed, 41 insertions(+), 20 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 5943d858a..e9fb5f76a 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -235,16 +235,30 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/ std::set pkgs_seen; const char *nullreorderlist[] = {0}; while(tagfile.Step(section)) { - string pkgname = section.FindS("Package"); + string const pkgname = section.FindS("Package"); // Silently ignore unknown packages and packages with no actual // version. pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname); if(pkg.end() || pkg.VersionList().end()) continue; - bool newAuto = (PkgState[pkg->ID].Flags & Flag::Auto); + StateCache const &P = PkgState[pkg->ID]; + bool newAuto = (P.Flags & Flag::Auto); + // skip not installed or now-removed ones if requested + if (InstalledOnly && ( + (pkg->CurrentVer == 0 && P.Mode != ModeInstall) || + (pkg->CurrentVer != 0 && P.Mode == ModeDelete))) + { + // The section is obsolete if it contains no other tag + unsigned int const count = section.Count(); + if (count < 2 || + (count == 2 && section.Exists("Auto-Installed"))) + continue; + else + newAuto = false; + } if(_config->FindB("Debug::pkgAutoRemove",false)) std::clog << "Update existing AutoInstall info: " - << pkg.Name() << std::endl; + << pkgname << std::endl; TFRewriteData rewrite[2]; rewrite[0].Tag = "Auto-Installed"; rewrite[0].Rewrite = newAuto ? "1" : "0"; @@ -258,15 +272,18 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/ // then write the ones we have not seen yet std::ostringstream ostr; for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); pkg++) { - if(PkgState[pkg->ID].Flags & Flag::Auto) { + StateCache const &P = PkgState[pkg->ID]; + if(P.Flags & Flag::Auto) { if (pkgs_seen.find(pkg.Name()) != pkgs_seen.end()) { if(debug_autoremove) std::clog << "Skipping already written " << pkg.Name() << std::endl; continue; } - // skip not installed ones if requested - if(InstalledOnly && pkg->CurrentVer == 0) - continue; + // skip not installed ones if requested + if (InstalledOnly && ( + (pkg->CurrentVer == 0 && P.Mode != ModeInstall) || + (pkg->CurrentVer != 0 && P.Mode == ModeDelete))) + continue; if(debug_autoremove) std::clog << "Writing new AutoInstall: " << pkg.Name() << std::endl; diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 0306861a1..fd1f202be 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -447,7 +447,7 @@ class pkgDepCache : protected pkgCache::Namespace // read persistent states bool readStateFile(OpProgress *prog); - bool writeStateFile(OpProgress *prog, bool InstalledOnly=false); + bool writeStateFile(OpProgress *prog, bool InstalledOnly=true); // Size queries inline double UsrSize() {return iUsrSize;}; diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 7c5d15a58..0d4999ee7 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -193,17 +193,8 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long Offset) /*}}}*/ // TagSection::Scan - Scan for the end of the header information /*{{{*/ // --------------------------------------------------------------------- -/* This looks for the first double new line in the data stream. It also - indexes the tags in the section. This very simple hash function for the - last 8 letters gives very good performance on the debian package files */ -inline static unsigned long AlphaHash(const char *Text, const char *End = 0) -{ - unsigned long Res = 0; - for (; Text != End && *Text != ':' && *Text != 0; Text++) - Res = ((unsigned long)(*Text) & 0xDF) ^ (Res << 1); - return Res & 0xFF; -} - +/* This looks for the first double new line in the data stream. + It also indexes the tags in the section. */ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength) { const char *End = Start + MaxLength; diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h index 321329a23..f63a51d07 100644 --- a/apt-pkg/tagfile.h +++ b/apt-pkg/tagfile.h @@ -33,7 +33,18 @@ class pkgTagSection unsigned int AlphaIndexes[0x100]; unsigned int TagCount; - + + /* This very simple hash function for the last 8 letters gives + very good performance on the debian package files */ + inline static unsigned long AlphaHash(const char *Text, const char *End = 0) + { + unsigned long Res = 0; + for (; Text != End && *Text != ':' && *Text != 0; Text++) + Res = ((unsigned long)(*Text) & 0xDF) ^ (Res << 1); + return Res & 0xFF; + } + + protected: const char *Stop; @@ -54,6 +65,8 @@ class pkgTagSection virtual void TrimRecord(bool BeforeRecord, const char* &End); inline unsigned int Count() const {return TagCount;}; + inline bool Exists(const char* const Tag) {return AlphaIndexes[AlphaHash(Tag)] != 0;} + inline void Get(const char *&Start,const char *&Stop,unsigned int I) const {Start = Section + Indexes[I]; Stop = Section + Indexes[I+1];} -- cgit v1.2.3 From 7e2b56a39618589e77ea8c73611ab0aae39aae7f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 17 Mar 2010 14:47:05 +0100 Subject: * apt-pkg/pkgcachegen.cc: - merge versions correctly even if multiple different versions with the same version number are available. Thanks to Magnus Holmgren for the patch! (Closes: #351056) --- apt-pkg/pkgcachegen.cc | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 3eeb18cae..75a0e34f0 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -175,17 +175,22 @@ bool pkgCacheGenerator::MergeList(ListParser &List, pkgCache::VerIterator Ver = Pkg.VersionList(); map_ptrloc *LastVer = &Pkg->VersionList; int Res = 1; + unsigned long const Hash = List.VersionHash(); for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++) { Res = Cache.VS->CmpVersion(Version,Ver.VerStr()); - if (Res >= 0) + // Version is higher as current version - insert here + if (Res > 0) break; + // Versionstrings are equal - is hash also equal? + if (Res == 0 && Ver->Hash == Hash) + break; + // proceed with the next till we have either the right + // or we found another version (which will be lower) } - - /* We already have a version for this item, record that we - saw it */ - unsigned long Hash = List.VersionHash(); - if (Res == 0 && Ver->Hash == Hash) + + /* We already have a version for this item, record that we saw it */ + if (Res == 0) { if (List.UsePackage(Pkg,Ver) == false) return _error->Error(_("Error occurred while processing %s (UsePackage2)"), @@ -204,17 +209,6 @@ bool pkgCacheGenerator::MergeList(ListParser &List, } continue; - } - - // Skip to the end of the same version set. - if (Res == 0) - { - for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++) - { - Res = Cache.VS->CmpVersion(Version,Ver.VerStr()); - if (Res != 0) - break; - } } // Add a new version -- cgit v1.2.3 From e426a5ff1cd02797b29f5781be4d6fc8bdf44610 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 18 Mar 2010 13:27:55 +0100 Subject: Fix a segfault in the version merger introduced in the previous patch: As we skip now versions with a different hash we will have situations in which the version is equal but the hash different causing to check the next version, but as this version was the last one the version iterator is invalid then the merger wants to add further information. --- apt-pkg/pkgcachegen.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 75a0e34f0..47ead2df9 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -190,7 +190,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List, } /* We already have a version for this item, record that we saw it */ - if (Res == 0) + if (Res == 0 && Ver.end() == false && Ver->Hash == Hash) { if (List.UsePackage(Pkg,Ver) == false) return _error->Error(_("Error occurred while processing %s (UsePackage2)"), -- cgit v1.2.3 From 306eacf617b8ea8c87b31258c55a5373be4ad946 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 18 Mar 2010 18:07:51 +0100 Subject: generate "negative" dependencies against all architectures of a package Negative means here Conflicts, Replaces and Breaks - this adds again a whole lot of dependencies. --- apt-pkg/deb/deblistparser.cc | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 84eab44a7..5c9cf6d4b 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -609,7 +609,10 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver, const char *Stop; if (Section.Find(Tag,Start,Stop) == false) return true; - + + static std::vector const archs = APT::Configuration::getArchitectures(); + static bool const multiArch = archs.size() <= 1; + string Package; string const pkgArch = Ver.Arch(true); string Version; @@ -620,8 +623,18 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver, Start = ParseDepends(Start,Stop,Package,Version,Op); if (Start == 0) return _error->Error("Problem parsing dependency %s",Tag); - - if (NewDepends(Ver,Package,pkgArch,Version,Op,Type) == false) + + if (multiArch == true && + (Type == pkgCache::Dep::Conflicts || + Type == pkgCache::Dep::DpkgBreaks || + Type == pkgCache::Dep::Replaces)) + { + for (std::vector::const_iterator a = archs.begin(); + a != archs.end(); ++a) + if (NewDepends(Ver,Package,*a,Version,Op,Type) == false) + return false; + } + else if (NewDepends(Ver,Package,pkgArch,Version,Op,Type) == false) return false; if (Start == Stop) break; -- cgit v1.2.3 From 8d4c859d0d20687a8ffcf9e1d60466d061c2e24d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 18 Mar 2010 18:51:14 +0100 Subject: Readd the FindPkg() method implementation used in the singleArch days to use it as a fallback if multiarch is not enabled. The effect is barly noticeable but SingleArch is the realworld scenario. --- apt-pkg/pkgcache.cc | 30 +++++++++++++++++++++++++++++- apt-pkg/pkgcache.h | 8 +++++++- 2 files changed, 36 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 24d9e0329..fe8757ded 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -108,6 +108,7 @@ bool pkgCache::Header::CheckSizes(Header &Against) const /* */ pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map) { + MultiArchEnabled = APT::Configuration::getArchitectures().size() > 1; if (DoMap == true) ReMap(); } @@ -178,11 +179,31 @@ unsigned long pkgCache::sHash(const char *Str) const return Hash % _count(HeaderP->PkgHashTable); } + /*}}}*/ +// Cache::SingleArchFindPkg - Locate a package by name /*{{{*/ +// --------------------------------------------------------------------- +/* Returns 0 on error, pointer to the package otherwise + The multiArch enabled methods will fallback to this one as it is (a bit) + faster for single arch environments and realworld is mostly singlearch… */ +pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name) +{ + // Look at the hash bucket + Package *Pkg = PkgP + HeaderP->PkgHashTable[Hash(Name)]; + for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage) + { + if (Pkg->Name != 0 && StrP[Pkg->Name] == Name[0] && + stringcasecmp(Name,StrP + Pkg->Name) == 0) + return PkgIterator(*this,Pkg); + } + return PkgIterator(*this,0); +} /*}}}*/ // Cache::FindPkg - Locate a package by name /*{{{*/ // --------------------------------------------------------------------- /* Returns 0 on error, pointer to the package otherwise */ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) { + if (MultiArchCache() == false) + return SingleArchFindPkg(Name); size_t const found = Name.find(':'); if (found == string::npos) return FindPkg(Name, "native"); @@ -195,7 +216,14 @@ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) { // Cache::FindPkg - Locate a package by name /*{{{*/ // --------------------------------------------------------------------- /* Returns 0 on error, pointer to the package otherwise */ -pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string Arch) { +pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string const &Arch) { + if (MultiArchCache() == false) { + if (Arch == "native" || Arch == "all" || + Arch == _config->Find("APT::Architecture")) + return SingleArchFindPkg(Name); + else + return PkgIterator(*this,0); + } /* We make a detour via the GrpIterator here as on a multi-arch environment a group is easier to find than a package (less entries in the buckets) */ diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 012caac76..577eebad9 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -126,7 +126,7 @@ class pkgCache /*{{{*/ // Accessors GrpIterator FindGrp(const string &Name); PkgIterator FindPkg(const string &Name); - PkgIterator FindPkg(const string &Name, string Arch); + PkgIterator FindPkg(const string &Name, const string &Arch); Header &Head() {return *HeaderP;}; inline GrpIterator GrpBegin(); @@ -136,6 +136,8 @@ class pkgCache /*{{{*/ inline PkgFileIterator FileBegin(); inline PkgFileIterator FileEnd(); + inline bool MultiArchCache() const { return MultiArchEnabled; }; + // Make me a function pkgVersioningSystem *VS; @@ -146,6 +148,10 @@ class pkgCache /*{{{*/ pkgCache(MMap *Map,bool DoMap = true); virtual ~pkgCache() {}; + +private: + bool MultiArchEnabled; + PkgIterator SingleArchFindPkg(const string &Name); }; /*}}}*/ // Header structure /*{{{*/ -- cgit v1.2.3 From 9552aeeb1524d5b659ae209becb322b3d6763183 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 19 Mar 2010 13:06:48 +0100 Subject: add a missing non-const & Accessors to the Iterator class --- apt-pkg/cacheiterators.h | 1 + 1 file changed, 1 insertion(+) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 28e062f3c..e2ca74683 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -62,6 +62,7 @@ template class pkgCache::Iterator { inline Str const *operator ->() const {return S;}; inline operator Str *() {return S == OwnerPointer() ? 0 : S;}; inline operator Str const *() const {return S == OwnerPointer() ? 0 : S;}; + inline Str &operator *() {return *S;}; inline Str const &operator *() const {return *S;}; inline pkgCache *Cache() {return Owner;}; -- cgit v1.2.3 From 8f5525e96777133e18772e398a2bb22ffc497d44 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 21 Mar 2010 17:38:43 +0100 Subject: * apt-pkg/policy.cc: - Always return a candidate if there is at least one version pinned > 0 (Closes: #512318) --- apt-pkg/policy.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index f9901bc9a..b12a50d0a 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; } /*}}}*/ -- cgit v1.2.3 From 6bc703c22970055d9e1a1b4e3e0efe74f4cefda5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 21 Mar 2010 21:48:09 +0100 Subject: =?UTF-8?q?Add=20with=20pkgCacheGen::Essential=20a=20way=20to=20co?= =?UTF-8?q?ntrol=20which=20packages=20get=20the=20essential=20flag:=20*=20?= =?UTF-8?q?native=20is=20the=20default=20and=20will=20only=20mark=20packag?= =?UTF-8?q?es=20of=20the=20main=20arch=20*=20all=20will=20mark=20all=20pac?= =?UTF-8?q?kages=20which=20have=20these=20flag=20in=20Packages=20*=20none?= =?UTF-8?q?=20will=20obviously=20do=20the=20opposite=20*=20installed=20wil?= =?UTF-8?q?l=20only=20mark=20packages=20which=20are=20installed=20as=20ess?= =?UTF-8?q?ential,=20=20=20so=20it=20will=20behave=20in=20the=20same=20way?= =?UTF-8?q?=20as=20dpkg=20does=20it.=20It=20is=20mostly=20needed=20sometim?= =?UTF-8?q?es=20for=20debugging=20but=20some=20users=20with=20special=20ne?= =?UTF-8?q?eds=20might=20like=20to=20switch=20the=20mode=20as=20well=20und?= =?UTF-8?q?er=20the=20expense=20to=20be=20on=20their=20own=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apt-pkg/deb/deblistparser.cc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 5c9cf6d4b..947e060e3 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -255,9 +255,13 @@ bool debListParser::UsePackage(pkgCache::PkgIterator Pkg, if (Pkg->Section == 0) Pkg->Section = UniqFindTagWrite("Section"); - // Packages which are not from "our" arch doesn't get the essential flag + // Packages which are not from the "native" arch doesn't get the essential flag + // in the default "native" mode - it is also possible to mark "all" or "none". + // The "installed" mode is handled by ParseStatus(), See #544481 and friends. string const static myArch = _config->Find("APT::Architecture"); - if (Pkg->Arch != 0 && myArch == Pkg.Arch()) + string const static essential = _config->Find("pkgCacheGen::Essential", "native"); + if ((essential == "native" && Pkg->Arch != 0 && myArch == Pkg.Arch()) || + essential == "all") if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false) return false; if (Section.FindFlag("Important",Pkg->Flags,pkgCache::Flag::Important) == false) @@ -333,7 +337,13 @@ bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg, const char *Stop; if (Section.Find("Status",Start,Stop) == false) return true; - + + // UsePackage() is responsible for setting the flag in the default case + bool const static essential = _config->Find("pkgCacheGen::Essential", "") == "installed"; + if (essential == true && + Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false) + return false; + // Isolate the first word const char *I = Start; for(; I < Stop && *I != ' '; I++); -- cgit v1.2.3 From 6dc60370a750334cb701386cfa4ef9719db9078a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 30 Mar 2010 12:38:38 +0200 Subject: replace every call to toupper with one to our own tolower_ascii This sounds like a premature optimization and since Mr. Knuth we all know that they are the root of all evil - but, and here it starts to be interesting: As the tolower_ascii method is by far the most called method we have (~60 Mio. times) and as we compare only strings containing ascii characters (package names, configuration options) using our own method reduces execution time of APT by 4% plus it avoids that the locale settings can influence us. --- apt-pkg/contrib/error.h | 8 ++++---- apt-pkg/contrib/macros.h | 10 ++++++---- apt-pkg/contrib/strutl.cc | 49 +++++++++++++++++++++++++---------------------- apt-pkg/contrib/strutl.h | 21 ++++++-------------- 4 files changed, 42 insertions(+), 46 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h index 90747ff7e..8d5ec05ea 100644 --- a/apt-pkg/contrib/error.h +++ b/apt-pkg/contrib/error.h @@ -60,13 +60,13 @@ class GlobalError public: // Call to generate an error from a library call. - bool Errno(const char *Function,const char *Description,...) __like_printf_2 __cold; - bool WarningE(const char *Function,const char *Description,...) __like_printf_2 __cold; + bool Errno(const char *Function,const char *Description,...) __like_printf(3) __cold; + bool WarningE(const char *Function,const char *Description,...) __like_printf(3) __cold; /* A warning should be considered less severe than an error, and may be ignored by the client. */ - bool Error(const char *Description,...) __like_printf_1 __cold; - bool Warning(const char *Description,...) __like_printf_1 __cold; + bool Error(const char *Description,...) __like_printf(2) __cold; + bool Warning(const char *Description,...) __like_printf(2) __cold; // Simple accessors inline bool PendingError() {return PendingFlag;}; diff --git a/apt-pkg/contrib/macros.h b/apt-pkg/contrib/macros.h index c39caf198..62e7b65db 100644 --- a/apt-pkg/contrib/macros.h +++ b/apt-pkg/contrib/macros.h @@ -58,6 +58,7 @@ #if __GNUC__ >= 3 #define __must_check __attribute__ ((warn_unused_result)) #define __deprecated __attribute__ ((deprecated)) + #define __attrib_const __attribute__ ((__const__)) /* likely() and unlikely() can be used to mark boolean expressions as (not) likely true which will help the compiler to optimise */ #define likely(x) __builtin_expect (!!(x), 1) @@ -65,6 +66,7 @@ #else #define __must_check /* no warn_unused_result */ #define __deprecated /* no deprecated */ + #define __attrib_const /* no const attribute */ #define likely(x) (x) #define unlikely(x) (x) #endif @@ -72,17 +74,17 @@ // cold functions are unlikely() to be called #if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 #define __cold __attribute__ ((__cold__)) + #define __hot __attribute__ ((__hot__)) #else #define __cold /* no cold marker */ + #define __hot /* no hot marker */ #endif #ifdef __GNUG__ // Methods have a hidden this parameter that is visible to this attribute - #define __like_printf_1 __attribute__ ((format (printf, 2, 3))) - #define __like_printf_2 __attribute__ ((format (printf, 3, 4))) + #define __like_printf(n) __attribute__((format(printf, n, n + 1))) #else - #define __like_printf_1 /* no like-printf */ - #define __like_printf_2 /* no like-printf */ + #define __like_printf(n) /* no like-printf */ #endif #endif diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 1b9922a31..ab47cdede 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -566,7 +566,7 @@ int stringcmp(string::const_iterator A,string::const_iterator AEnd, int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd) { for (; A != AEnd && B != BEnd; A++, B++) - if (toupper(*A) != toupper(*B)) + if (tolower_ascii(*A) != tolower_ascii(*B)) break; if (A == AEnd && B == BEnd) @@ -575,7 +575,7 @@ int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd) return 1; if (B == BEnd) return -1; - if (toupper(*A) < toupper(*B)) + if (tolower_ascii(*A) < tolower_ascii(*B)) return -1; return 1; } @@ -584,7 +584,7 @@ int stringcasecmp(string::const_iterator A,string::const_iterator AEnd, const char *B,const char *BEnd) { for (; A != AEnd && B != BEnd; A++, B++) - if (toupper(*A) != toupper(*B)) + if (tolower_ascii(*A) != tolower_ascii(*B)) break; if (A == AEnd && B == BEnd) @@ -593,7 +593,7 @@ int stringcasecmp(string::const_iterator A,string::const_iterator AEnd, return 1; if (B == BEnd) return -1; - if (toupper(*A) < toupper(*B)) + if (tolower_ascii(*A) < tolower_ascii(*B)) return -1; return 1; } @@ -601,7 +601,7 @@ int stringcasecmp(string::const_iterator A,string::const_iterator AEnd, string::const_iterator B,string::const_iterator BEnd) { for (; A != AEnd && B != BEnd; A++, B++) - if (toupper(*A) != toupper(*B)) + if (tolower_ascii(*A) != tolower_ascii(*B)) break; if (A == AEnd && B == BEnd) @@ -610,7 +610,7 @@ int stringcasecmp(string::const_iterator A,string::const_iterator AEnd, return 1; if (B == BEnd) return -1; - if (toupper(*A) < toupper(*B)) + if (tolower_ascii(*A) < tolower_ascii(*B)) return -1; return 1; } @@ -789,28 +789,28 @@ bool ReadMessages(int Fd, vector &List) // MonthConv - Converts a month string into a number /*{{{*/ // --------------------------------------------------------------------- /* This was lifted from the boa webserver which lifted it from 'wn-v1.07' - Made it a bit more robust with a few touppers though. */ + Made it a bit more robust with a few tolower_ascii though. */ static int MonthConv(char *Month) { - switch (toupper(*Month)) + switch (tolower_ascii(*Month)) { - case 'A': - return toupper(Month[1]) == 'P'?3:7; - case 'D': + case 'a': + return tolower_ascii(Month[1]) == 'p'?3:7; + case 'd': return 11; - case 'F': + case 'f': return 1; - case 'J': - if (toupper(Month[1]) == 'A') + case 'j': + if (tolower_ascii(Month[1]) == 'a') return 0; - return toupper(Month[2]) == 'N'?5:6; - case 'M': - return toupper(Month[2]) == 'R'?2:4; - case 'N': + return tolower_ascii(Month[2]) == 'n'?5:6; + case 'm': + return tolower_ascii(Month[2]) == 'r'?2:4; + case 'n': return 10; - case 'O': + case 'o': return 9; - case 'S': + case 's': return 8; // Pretend it is January.. @@ -1133,10 +1133,13 @@ char *safe_snprintf(char *Buffer,char *End,const char *Format,...) // tolower_ascii - tolower() function that ignores the locale /*{{{*/ // --------------------------------------------------------------------- -/* */ -int tolower_ascii(int c) +/* This little function is the most called method we have and tries + therefore to do the absolut minimum - and is noteable faster than + standard tolower/toupper and as a bonus avoids problems with different + locales - we only operate on ascii chars anyway. */ +int tolower_ascii(int const c) { - if (c >= 'A' and c <= 'Z') + if (c >= 'A' && c <= 'Z') return c + 32; return c; } diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index e72288f4c..cdf78f317 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -25,19 +25,12 @@ #include #include +#include "macros.h" + using std::string; using std::vector; using std::ostream; -#ifdef __GNUG__ -// Methods have a hidden this parameter that is visible to this attribute -#define APT_FORMAT2 __attribute__ ((format (printf, 2, 3))) -#define APT_FORMAT3 __attribute__ ((format (printf, 3, 4))) -#else -#define APT_FORMAT2 -#define APT_FORMAT3 -#endif - bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest); char *_strstrip(char *String); char *_strtabexpand(char *String,size_t Len); @@ -60,11 +53,11 @@ bool Hex2Num(const string &Str,unsigned char *Num,unsigned int Length); bool TokSplitString(char Tok,char *Input,char **List, unsigned long ListMax); vector 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; +void ioprintf(ostream &out,const char *format,...) __like_printf(2); +void strprintf(string &out,const char *format,...) __like_printf(2); +char *safe_snprintf(char *Buffer,char *End,const char *Format,...) __like_printf(3); bool CheckDomainList(const string &Host, const string &List); -int tolower_ascii(int c); +int tolower_ascii(int const c) __attrib_const __hot; #define APT_MKSTRCMP(name,func) \ inline int name(const char *A,const char *B) {return func(A,A+strlen(A),B,B+strlen(B));}; \ @@ -144,6 +137,4 @@ struct RxChoiceList unsigned long RegexChoice(RxChoiceList *Rxs,const char **ListBegin, const char **ListEnd); -#undef APT_FORMAT2 - #endif -- cgit v1.2.3 From c408e01e546e641a0906f188ca6bb924a2f17b40 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 30 Mar 2010 12:39:33 +0200 Subject: Group packages in the same group together in the package list so it is easier to find them later on as we have no "noice" anymore between them. --- apt-pkg/pkgcache.cc | 17 +++++------------ apt-pkg/pkgcachegen.cc | 26 +++++++++++++++++--------- 2 files changed, 22 insertions(+), 21 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index fe8757ded..1bbd74bd9 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -343,24 +343,17 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) { // GrpIterator::NextPkg - Locate the next package in the group /*{{{*/ // --------------------------------------------------------------------- /* Returns an End-Pointer on error, pointer to the package otherwise. - We can't simply ++ to the next as the list of packages includes - "package noise" (= packages with the same hash value but different name) */ + We can't simply ++ to the next as the next package of the last will + be from a different group (with the same hash value) */ pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const &LastPkg) { if (unlikely(IsGood() == false || S->FirstPackage == 0 || LastPkg.end() == true)) return PkgIterator(*Owner, 0); - // Iterate over the list to find the next package - pkgCache::Package *Pkg = Owner->PkgP + LastPkg.Index(); - Pkg = Owner->PkgP + Pkg->NextPackage; - for (; Pkg != Owner->PkgP; Pkg = Owner->PkgP + Pkg->NextPackage) { - if (S->Name == Pkg->Name) - return PkgIterator(*Owner, Pkg); - if ((Owner->PkgP + S->LastPackage) == Pkg) - break; - } + if (S->LastPackage == LastPkg.Index()) + return PkgIterator(*Owner, 0); - return PkgIterator(*Owner, 0); + return PkgIterator(*Owner, Owner->PkgP + LastPkg->NextPackage); } /*}}}*/ // GrpIterator::operator ++ - Postfix incr /*{{{*/ diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 8187b3950..577e2f1d4 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -379,15 +379,23 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name return false; Pkg = pkgCache::PkgIterator(Cache,Cache.PkgP + Package); - // Insert it into the hash table - unsigned long const Hash = Cache.Hash(Name); - Pkg->NextPackage = Cache.HeaderP->PkgHashTable[Hash]; - Cache.HeaderP->PkgHashTable[Hash] = Package; - - // remember the packages in the group - Grp->FirstPackage = Package; - if (Grp->LastPackage == 0) - Grp->LastPackage = Package; + // Insert the package into our package list + if (Grp->FirstPackage == 0) // the group is new + { + // Insert it into the hash table + unsigned long const Hash = Cache.Hash(Name); + Pkg->NextPackage = Cache.HeaderP->PkgHashTable[Hash]; + Cache.HeaderP->PkgHashTable[Hash] = Package; + Grp->FirstPackage = Package; + } + else // Group the Packages together + { + // this package is the new last package + pkgCache::PkgIterator LastPkg(Cache, Cache.PkgP + Grp->LastPackage); + Pkg->NextPackage = LastPkg->NextPackage; + LastPkg->NextPackage = Package; + } + Grp->LastPackage = Package; // Set the name, arch and the ID Pkg->Name = Grp->Name; -- cgit v1.2.3 From 3f42500d6b9eb318c46cacafdcfd6beb707ef9e9 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 30 Mar 2010 14:25:57 +0200 Subject: rename ExplodeString to VectorizeString --- apt-pkg/aptconfiguration.cc | 2 +- apt-pkg/contrib/strutl.cc | 6 +++--- apt-pkg/contrib/strutl.h | 2 +- apt-pkg/deb/debmetaindex.cc | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index a1379ce7d..2acf8dd9f 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -221,7 +221,7 @@ std::vector const Configuration::getLanguages(bool const &All, const char *language_env = getenv("LANGUAGE") == 0 ? "" : getenv("LANGUAGE"); string envLang = Locale == 0 ? language_env : *(Locale+1); if (envLang.empty() == false) { - std::vector env = ExplodeString(envLang,':'); + std::vector env = VectorizeString(envLang,':'); short addedLangs = 0; // add a maximum of 3 fallbacks from the environment for (std::vector::const_iterator e = env.begin(); e != env.end() && addedLangs < 3; ++e) { diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index ab47cdede..7eb986ac0 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -1000,12 +1000,12 @@ bool TokSplitString(char Tok,char *Input,char **List, return true; } /*}}}*/ -// ExplodeString - Split a string up into a vector /*{{{*/ +// VectorizeString - Split a string up into a vector of strings /*{{{*/ // --------------------------------------------------------------------- /* 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 ExplodeString(string const &haystack, char const &split) + also, but the advantage is that we have an iteratable vector */ +vector VectorizeString(string const &haystack, char const &split) { string::const_iterator start = haystack.begin(); string::const_iterator end = start; diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index cdf78f317..d8070d3f5 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -52,7 +52,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 ExplodeString(string const &haystack, char const &split); +vector VectorizeString(string const &haystack, char const &split) __attrib_const; void ioprintf(ostream &out,const char *format,...) __like_printf(2); void strprintf(string &out,const char *format,...) __like_printf(2); char *safe_snprintf(char *Buffer,char *End,const char *Format,...) __like_printf(3); diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 947a7f04b..8df3ed18d 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -313,7 +313,7 @@ class debSLTypeDebian : public pkgSourceList::Type { map::const_iterator const arch = Options.find("arch"); vector const Archs = - (arch != Options.end()) ? ExplodeString(arch->second, ',') : + (arch != Options.end()) ? VectorizeString(arch->second, ',') : APT::Configuration::getArchitectures(); for (vector::const_iterator I = List.begin(); -- cgit v1.2.3 From 33dd02e3a95141d4e16677048614c3171c4c4ffc Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 30 Mar 2010 14:45:38 +0200 Subject: convert some tabs to spaces to respect the style guide --- apt-pkg/deb/deblistparser.cc | 39 +++++----- apt-pkg/pkgcachegen.cc | 169 +++++++++++++++++++++++-------------------- 2 files changed, 109 insertions(+), 99 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 947e060e3..0551a5f7c 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -36,8 +36,8 @@ static debListParser::WordList PrioList[] = {{"important",pkgCache::State::Impor 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"); + if (Arch == "native") + this->Arch = _config->Find("APT::Architecture"); } /*}}}*/ // ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/ @@ -56,10 +56,10 @@ unsigned long debListParser::UniqFindTagWrite(const char *Tag) // --------------------------------------------------------------------- /* This is to return the name of the package this section describes */ string debListParser::Package() { - string const Result = Section.FindS("Package"); - if(unlikely(Result.empty() == true)) - _error->Error("Encountered a section with no Package: header"); - return Result; + string const Result = Section.FindS("Package"); + if(unlikely(Result.empty() == true)) + _error->Error("Encountered a section with no Package: header"); + return Result; } /*}}}*/ // ListParser::Architecture - Return the package arch /*{{{*/ @@ -68,25 +68,26 @@ string debListParser::Package() { Note that architecture "all" packages will get the architecture of the Packages file parsed here. */ string debListParser::Architecture() { - string const Result = Section.FindS("Architecture"); - 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; + string const Result = Section.FindS("Architecture"); + 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; } /*}}}*/ // ListParser::ArchitectureAll /*{{{*/ // --------------------------------------------------------------------- /* */ bool debListParser::ArchitectureAll() { - return Section.FindS("Architecture") == "all"; + return Section.FindS("Architecture") == "all"; } /*}}}*/ // ListParser::Version - Return the version string /*{{{*/ diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 577e2f1d4..21240b951 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -335,29 +335,30 @@ bool pkgCacheGenerator::MergeFileProvides(ListParser &List) // CacheGenerator::NewGroup - Add a new group /*{{{*/ // --------------------------------------------------------------------- /* This creates a new group structure and adds it to the hash table */ -bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name) { - Grp = Cache.FindGrp(Name); - if (Grp.end() == false) - return true; +bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name) +{ + Grp = Cache.FindGrp(Name); + if (Grp.end() == false) + return true; - // Get a structure - unsigned long const Group = Map.Allocate(sizeof(pkgCache::Group)); - if (unlikely(Group == 0)) - return false; + // Get a structure + unsigned long const Group = Map.Allocate(sizeof(pkgCache::Group)); + if (unlikely(Group == 0)) + return false; - Grp = pkgCache::GrpIterator(Cache, Cache.GrpP + Group); - Grp->Name = Map.WriteString(Name); - if (unlikely(Grp->Name == 0)) - return false; + Grp = pkgCache::GrpIterator(Cache, Cache.GrpP + Group); + Grp->Name = Map.WriteString(Name); + if (unlikely(Grp->Name == 0)) + return false; - // Insert it into the hash table - unsigned long const Hash = Cache.Hash(Name); - Grp->Next = Cache.HeaderP->GrpHashTable[Hash]; - Cache.HeaderP->GrpHashTable[Hash] = Group; + // Insert it into the hash table + unsigned long const Hash = Cache.Hash(Name); + Grp->Next = Cache.HeaderP->GrpHashTable[Hash]; + Cache.HeaderP->GrpHashTable[Hash] = Group; - Cache.HeaderP->GroupCount++; + Cache.HeaderP->GroupCount++; - return true; + return true; } /*}}}*/ // CacheGenerator::NewPackage - Add a new package /*{{{*/ @@ -526,68 +527,76 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, // CacheGenerator::FinishCache - do various finish operations /*{{{*/ // --------------------------------------------------------------------- /* This prepares the Cache for delivery */ -bool pkgCacheGenerator::FinishCache(OpProgress &Progress) { - // FIXME: add progress reporting for this operation - // Do we have different architectures in your groups ? - vector archs = APT::Configuration::getArchitectures(); - if (archs.size() > 1) { - // Create Conflicts in between the group - for (pkgCache::GrpIterator G = GetCache().GrpBegin(); G.end() != true; G++) { - string const PkgName = G.Name(); - for (pkgCache::PkgIterator P = G.PackageList(); P.end() != true; P = G.NextPkg(P)) { - if (strcmp(P.Arch(),"all") == 0) - continue; - pkgCache::PkgIterator allPkg; - for (pkgCache::VerIterator V = P.VersionList(); V.end() != true; V++) { - string const Arch = V.Arch(true); - map_ptrloc *OldDepLast = NULL; - /* MultiArch handling introduces a lot of implicit Dependencies: - - MultiArch: same → Co-Installable if they have the same version - - Architecture: all → Need to be Co-Installable for internal reasons - - All others conflict with all other group members */ - bool const coInstall = (V->MultiArch == pkgCache::Version::All || - V->MultiArch == pkgCache::Version::Same); - if (V->MultiArch == pkgCache::Version::All && allPkg.end() == true) - allPkg = G.FindPkg("all"); - for (vector::const_iterator A = archs.begin(); A != archs.end(); ++A) { - if (*A == Arch) - continue; - /* We allow only one installed arch at the time - per group, therefore each group member conflicts - with all other group members */ - pkgCache::PkgIterator D = G.FindPkg(*A); - if (D.end() == true) - continue; - if (coInstall == true) { - // Replaces: ${self}:other ( << ${binary:Version}) - NewDepends(D, V, V.VerStr(), - pkgCache::Dep::Less, pkgCache::Dep::Replaces, - OldDepLast); - // Breaks: ${self}:other (!= ${binary:Version}) - NewDepends(D, V, V.VerStr(), - pkgCache::Dep::Less, pkgCache::Dep::DpkgBreaks, - OldDepLast); - NewDepends(D, V, V.VerStr(), - pkgCache::Dep::Greater, pkgCache::Dep::DpkgBreaks, - OldDepLast); - if (V->MultiArch == pkgCache::Version::All) { - // Depend on ${self}:all which does depend on nothing - NewDepends(allPkg, V, V.VerStr(), - pkgCache::Dep::Equals, pkgCache::Dep::Depends, - OldDepLast); - } - } else { - // Conflicts: ${self}:other - NewDepends(D, V, "", - pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts, - OldDepLast); - } - } - } - } - } - } - return true; +bool pkgCacheGenerator::FinishCache(OpProgress &Progress) +{ + // FIXME: add progress reporting for this operation + // Do we have different architectures in your groups ? + vector archs = APT::Configuration::getArchitectures(); + if (archs.size() > 1) + { + // Create Conflicts in between the group + for (pkgCache::GrpIterator G = GetCache().GrpBegin(); G.end() != true; G++) + { + string const PkgName = G.Name(); + for (pkgCache::PkgIterator P = G.PackageList(); P.end() != true; P = G.NextPkg(P)) + { + if (strcmp(P.Arch(),"all") == 0) + continue; + pkgCache::PkgIterator allPkg; + for (pkgCache::VerIterator V = P.VersionList(); V.end() != true; V++) + { + string const Arch = V.Arch(true); + map_ptrloc *OldDepLast = NULL; + /* MultiArch handling introduces a lot of implicit Dependencies: + - MultiArch: same → Co-Installable if they have the same version + - Architecture: all → Need to be Co-Installable for internal reasons + - All others conflict with all other group members */ + bool const coInstall = (V->MultiArch == pkgCache::Version::All || + V->MultiArch == pkgCache::Version::Same); + if (V->MultiArch == pkgCache::Version::All && allPkg.end() == true) + allPkg = G.FindPkg("all"); + for (vector::const_iterator A = archs.begin(); A != archs.end(); ++A) + { + if (*A == Arch) + continue; + /* We allow only one installed arch at the time + per group, therefore each group member conflicts + with all other group members */ + pkgCache::PkgIterator D = G.FindPkg(*A); + if (D.end() == true) + continue; + if (coInstall == true) + { + // Replaces: ${self}:other ( << ${binary:Version}) + NewDepends(D, V, V.VerStr(), + pkgCache::Dep::Less, pkgCache::Dep::Replaces, + OldDepLast); + // Breaks: ${self}:other (!= ${binary:Version}) + NewDepends(D, V, V.VerStr(), + pkgCache::Dep::Less, pkgCache::Dep::DpkgBreaks, + OldDepLast); + NewDepends(D, V, V.VerStr(), + pkgCache::Dep::Greater, pkgCache::Dep::DpkgBreaks, + OldDepLast); + if (V->MultiArch == pkgCache::Version::All) + { + // Depend on ${self}:all which does depend on nothing + NewDepends(allPkg, V, V.VerStr(), + pkgCache::Dep::Equals, pkgCache::Dep::Depends, + OldDepLast); + } + } else { + // Conflicts: ${self}:other + NewDepends(D, V, "", + pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts, + OldDepLast); + } + } + } + } + } + } + return true; } /*}}}*/ // CacheGenerator::NewDepends - Create a dependency element /*{{{*/ -- cgit v1.2.3 From 436d7eab92bb8f9cc6498acfbf2055e717be6fd0 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 31 Mar 2010 17:19:10 +0200 Subject: Userinfo is urlencoded in URIs (RFC 3986) Thanks to Jean-Baptiste Lallement for spotting and fixing it! * apt-pkg/contrib/strutl.cc: - always escape '%' (LP: #130289) (Closes: #500560) - unescape '%' sequence only if followed by 2 hex digit - username/password are urlencoded in proxy string (RFC 3986) --- apt-pkg/contrib/strutl.cc | 21 +++++++++++++++------ apt-pkg/contrib/strutl.h | 1 + 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 7eb986ac0..c7d63ce8a 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -198,7 +198,8 @@ bool ParseQuoteWord(const char *&String,string &Res) char *I; for (I = Buffer; I < Buffer + sizeof(Buffer) && Start != C; I++) { - if (*Start == '%' && Start + 2 < C) + if (*Start == '%' && Start + 2 < C && + isxdigit(Start[1]) && isxdigit(Start[2])) { Tmp[0] = Start[1]; Tmp[1] = Start[2]; @@ -273,7 +274,8 @@ string QuoteString(const string &Str, const char *Bad) for (string::const_iterator I = Str.begin(); I != Str.end(); I++) { if (strchr(Bad,*I) != 0 || isprint(*I) == 0 || - *I <= 0x20 || *I >= 0x7F) + *I == 0x25 || // percent '%' char + *I <= 0x20 || *I >= 0x7F) // control chars { char Buf[10]; sprintf(Buf,"%%%02x",(int)*I); @@ -289,11 +291,17 @@ string QuoteString(const string &Str, const char *Bad) // --------------------------------------------------------------------- /* This undoes QuoteString */ string DeQuoteString(const string &Str) +{ + return DeQuoteString(Str.begin(),Str.end()); +} +string DeQuoteString(string::const_iterator const &begin, + string::const_iterator const &end) { string Res; - for (string::const_iterator I = Str.begin(); I != Str.end(); I++) + for (string::const_iterator I = begin; I != end; I++) { - if (*I == '%' && I + 2 < Str.end()) + if (*I == '%' && I + 2 < end && + isxdigit(I[1]) && isxdigit(I[2])) { char Tmp[3]; Tmp[0] = I[1]; @@ -1238,9 +1246,10 @@ void URI::CopyFrom(const string &U) else { Host.assign(At+1,SingleSlash); - User.assign(FirstColon,SecondColon); + // username and password must be encoded (RFC 3986) + User.assign(DeQuoteString(FirstColon,SecondColon)); if (SecondColon < At) - Password.assign(SecondColon+1,At); + Password.assign(DeQuoteString(SecondColon+1,At)); } // Now we parse the RFC 2732 [] hostnames. diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index d8070d3f5..e509145f9 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -38,6 +38,7 @@ bool ParseQuoteWord(const char *&String,string &Res); bool ParseCWord(const char *&String,string &Res); string QuoteString(const string &Str,const char *Bad); string DeQuoteString(const string &Str); +string DeQuoteString(string::const_iterator const &begin, string::const_iterator const &end); string SizeToStr(double Bytes); string TimeToStr(unsigned long Sec); string Base64Encode(const string &Str); -- cgit v1.2.3 From c753eec1d192a56e7f4ba1b07ae766b740185a3f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 3 Apr 2010 17:07:30 +0200 Subject: * apt-pkg/depcache.cc: - "reinstall" the correct version for a killed pseudo package --- apt-pkg/depcache.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 75f69ee11..0f07de2fe 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -855,13 +855,16 @@ void pkgDepCache::Update(OpProgress *Prog) if (P.end() == true) continue; for (VerIterator V = P.VersionList(); V.end() != true; ++V) { - // FIXME: String comparison isn't a save indicator! - if (strcmp(allV.VerStr(),V.VerStr()) != 0) + if (allV->Hash != V->Hash || + strcmp(allV.VerStr(),V.VerStr()) != 0) continue; unsigned char const CurDepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy); if ((CurDepState & DepInstMin) != DepInstMin) break; // we found the correct version, but it is broken. Better try another arch or later again + RemoveSizes(P); + RemoveStates(P); P->CurrentVer = V.Index(); + PkgState[P->ID].InstallVer = V; AddStates(P); Update(P); AddSizes(P); -- cgit v1.2.3 From 5e8b2b74ab565ffb72e035ce89a7a991d4de3dcf Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 3 Apr 2010 17:57:41 +0200 Subject: Initialize history_out always with NULL so apt will not segfault later in the event of a failure in OpenLog() (which will happen if called with Debug::NoLocking as user) --- apt-pkg/deb/dpkgpm.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index c0efa7b59..14a4968f7 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -105,7 +105,7 @@ ionice(int PID) /* */ pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) : pkgPackageManager(Cache), dpkgbuf_pos(0), - term_out(NULL), PackagesDone(0), PackagesTotal(0) + term_out(NULL), history_out(NULL), PackagesDone(0), PackagesTotal(0) { } /*}}}*/ @@ -651,6 +651,7 @@ bool pkgDPkgPM::CloseLog() fprintf(history_out, "End-Date: %s\n", timestr); fclose(history_out); } + history_out = NULL; return true; } -- cgit v1.2.3 From 87af68aa09fd1b0ab4f87fd064654a032c4daf30 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 3 Apr 2010 18:50:07 +0200 Subject: * apt-pkg/packagemanager.cc: - don't try to "unpack" pseudo packages twice --- apt-pkg/packagemanager.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 034cc8339..eef79cccd 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -596,9 +596,17 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) { if(Install(Pkg,FileNames[Pkg->ID]) == false) return false; - } else if (SmartUnPack(Pkg.Group().FindPkg("all")) == false) - return false; - + } else { + // Pseudo packages will not be unpacked - instead we will do this + // for the "real" package, but only once and if it is already + // configured we don't need to unpack it again… + PkgIterator const P = Pkg.Group().FindPkg("all"); + if (List->IsFlag(P,pkgOrderList::UnPacked) != true && + List->IsFlag(P,pkgOrderList::Configured) != true) { + if (SmartUnPack(P) == false) + return false; + } + } List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); // Perform immedate configuration of the package. -- cgit v1.2.3 From b3793d41d420a895ef5be4521a56535cc79f0d4a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 4 Apr 2010 10:34:45 +0200 Subject: remove the ABI compatible stub for GetListOfFilesInDir --- apt-pkg/contrib/fileutl.cc | 5 ----- apt-pkg/contrib/fileutl.h | 5 +---- 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index da32983f1..75adce305 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -201,11 +201,6 @@ bool FileExists(string File) // --------------------------------------------------------------------- /* If an extension is given only files with this extension are included in the returned vector, otherwise every "normal" file is included. */ -std::vector GetListOfFilesInDir(string const &Dir, string const &Ext, - bool const &SortList) -{ - return GetListOfFilesInDir(Dir, Ext, SortList, false); -} std::vector GetListOfFilesInDir(string const &Dir, string const &Ext, bool const &SortList, bool const &AllowNoExt) { diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 85a94898c..351d53c5e 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -82,11 +82,8 @@ bool RunScripts(const char *Cnf); bool CopyFile(FileFd &From,FileFd &To); int GetLock(string File,bool Errors = true); bool FileExists(string File); -// FIXME: next ABI-Break: merge the two method-headers std::vector GetListOfFilesInDir(string const &Dir, string const &Ext, - bool const &SortList); -std::vector GetListOfFilesInDir(string const &Dir, string const &Ext, - bool const &SortList, bool const &AllowNoExt); + bool const &SortList, bool const &AllowNoExt=false); std::vector GetListOfFilesInDir(string const &Dir, std::vector const &Ext, bool const &SortList); string SafeGetCWD(); -- cgit v1.2.3 From 1cd1c398d18b78f4aa9d882a5de5385f4538e0be Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 7 Apr 2010 16:38:18 +0200 Subject: * apt-pkg/contrib/fileutl.cc: - add a parent-guarded "mkdir -p" as CreateDirectory() * apt-pkg/acquire.{cc,h}: - add a delayed constructor with Setup() for success reporting - check for and create directories in Setup if needed instead of error out unfriendly in the Constructor (Closes: #523920, #525783) - optional handle a lock file in Setup() * cmdline/apt-get.cc: - remove the lock file handling and let Acquire take care of it instead --- apt-pkg/acquire.cc | 89 ++++++++++++++++++++++++++++++++++------------ apt-pkg/acquire.h | 31 +++++++++++++--- apt-pkg/algorithms.cc | 4 ++- apt-pkg/contrib/fileutl.cc | 52 +++++++++++++++++++++++++++ apt-pkg/contrib/fileutl.h | 3 ++ apt-pkg/pkgcachegen.cc | 15 +++++++- 6 files changed, 164 insertions(+), 30 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index 74510ae21..d83d80fac 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -29,7 +30,6 @@ #include #include #include -#include /*}}}*/ using namespace std; @@ -37,32 +37,72 @@ using namespace std; // Acquire::pkgAcquire - Constructor /*{{{*/ // --------------------------------------------------------------------- /* We grab some runtime state from the configuration space */ -pkgAcquire::pkgAcquire(pkgAcquireStatus *Log) : Log(Log) +pkgAcquire::pkgAcquire() : Queues(0), Workers(0), Configs(0), Log(NULL), ToFetch(0), + Debug(_config->FindB("Debug::pkgAcquire",false)), + Running(false), LockFD(-1) { - Queues = 0; - Configs = 0; - Workers = 0; - ToFetch = 0; - Running = false; - - string Mode = _config->Find("Acquire::Queue-Mode","host"); + string const Mode = _config->Find("Acquire::Queue-Mode","host"); + if (strcasecmp(Mode.c_str(),"host") == 0) + QueueMode = QueueHost; + if (strcasecmp(Mode.c_str(),"access") == 0) + QueueMode = QueueAccess; +} +pkgAcquire::pkgAcquire(pkgAcquireStatus *Progress) : Queues(0), Workers(0), + Configs(0), Log(Progress), ToFetch(0), + Debug(_config->FindB("Debug::pkgAcquire",false)), + Running(false), LockFD(-1) +{ + string const Mode = _config->Find("Acquire::Queue-Mode","host"); if (strcasecmp(Mode.c_str(),"host") == 0) QueueMode = QueueHost; if (strcasecmp(Mode.c_str(),"access") == 0) - QueueMode = QueueAccess; + QueueMode = QueueAccess; + Setup(Progress, ""); +} + /*}}}*/ +// Acquire::Setup - Delayed Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* Do everything needed to be a complete Acquire object and report the + success (or failure) back so the user knows that something is wrong… */ +bool pkgAcquire::Setup(pkgAcquireStatus *Progress, string const &Lock) +{ + Log = Progress; - Debug = _config->FindB("Debug::pkgAcquire",false); - - // This is really a stupid place for this - struct stat St; - if (stat((_config->FindDir("Dir::State::lists") + "partial/").c_str(),&St) != 0 || - S_ISDIR(St.st_mode) == 0) - _error->Error(_("Lists directory %spartial is missing."), - _config->FindDir("Dir::State::lists").c_str()); - if (stat((_config->FindDir("Dir::Cache::Archives") + "partial/").c_str(),&St) != 0 || - S_ISDIR(St.st_mode) == 0) - _error->Error(_("Archive directory %spartial is missing."), - _config->FindDir("Dir::Cache::Archives").c_str()); + // check for existence and possibly create auxiliary directories + if (CheckDirectory(_config->FindDir("Dir::State"), _config->FindDir("Dir::State::lists") + "partial/") == false || + CheckDirectory(_config->FindDir("Dir::Cache"), _config->FindDir("Dir::Cache::Archives") + "partial/") == false) + return false; + + if (Lock.empty() == true || _config->FindB("Debug::NoLocking", false) == true) + return true; + + // Lock the directory this acquire object will work in + LockFD = GetLock(flCombine(Lock, "lock")); + if (LockFD == -1) + return _error->Error(_("Unable to lock directory %s"), Lock.c_str()); + + return true; +} + /*}}}*/ +// Acquire::CheckDirectory - ensure that the given directory exists /*{{{*/ +// --------------------------------------------------------------------- +/* a small wrapper around CreateDirectory to check if it exists and to + remove the trailing "/apt/" from the parent directory if needed */ +bool pkgAcquire::CheckDirectory(string const &Parent, string const &Path) const +{ + if (DirectoryExists(Path) == true) + return true; + + size_t const len = Parent.size(); + if (len > 5 && Parent.find("/apt/", len - 6, 5) != len - 5) + { + if (CreateDirectory(Parent.substr(0,len-5), Path) == true) + return true; + } + else if (CreateDirectory(Parent, Path) == true) + return true; + + return _error->Errno("Acquire", _("Directory %s can't be created."), Path.c_str()); } /*}}}*/ // Acquire::~pkgAcquire - Destructor /*{{{*/ @@ -71,7 +111,10 @@ pkgAcquire::pkgAcquire(pkgAcquireStatus *Log) : Log(Log) pkgAcquire::~pkgAcquire() { Shutdown(); - + + if (LockFD != -1) + close(LockFD); + while (Configs != 0) { MethodConfig *Jnk = Configs; diff --git a/apt-pkg/acquire.h b/apt-pkg/acquire.h index 6c130c1b3..9e91a9f67 100644 --- a/apt-pkg/acquire.h +++ b/apt-pkg/acquire.h @@ -66,6 +66,8 @@ #ifndef PKGLIB_ACQUIRE_H #define PKGLIB_ACQUIRE_H +#include + #include #include @@ -161,7 +163,7 @@ class pkgAcquire QueueAccess} QueueMode; /** \brief If \b true, debugging information will be dumped to std::clog. */ - bool Debug; + bool const Debug; /** \brief If \b true, a download is currently in progress. */ bool Running; @@ -332,15 +334,22 @@ class pkgAcquire */ double PartialPresent(); - /** \brief Construct a new pkgAcquire. + /** \brief Delayed constructor * - * \param Log The progress indicator associated with this - * download, or \b NULL for none. This object is not owned by the + * \param Progress indicator associated with this download or + * \b NULL for none. This object is not owned by the * download process and will not be deleted when the pkgAcquire * object is destroyed. Naturally, it should live for at least as * long as the pkgAcquire object does. + * \param Lock defines a lock file that should be acquired to ensure + * only one Acquire class is in action at the time or an empty string + * if no lock file should be used. */ - pkgAcquire(pkgAcquireStatus *Log = 0); + bool Setup(pkgAcquireStatus *Progress = NULL, string const &Lock = ""); + + /** \brief Construct a new pkgAcquire. */ + pkgAcquire(pkgAcquireStatus *Log) __deprecated; + pkgAcquire(); /** \brief Destroy this pkgAcquire object. * @@ -348,6 +357,18 @@ class pkgAcquire * this download. */ virtual ~pkgAcquire(); + + private: + /** \brief FD of the Lock file we acquire in Setup (if any) */ + int LockFD; + + /** \brief Ensure the existence of the given Path + * + * \param Parent directory of the Path directory - a trailing + * /apt/ will be removed before CreateDirectory call. + * \param Path which should exist after (successful) call + */ + bool CheckDirectory(string const &Parent, string const &Path) const; }; /** \brief Represents a single download source from which an item diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index f8a9e210c..f1e51131a 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -1398,7 +1398,9 @@ bool ListUpdate(pkgAcquireStatus &Stat, int PulseInterval) { pkgAcquire::RunResult res; - pkgAcquire Fetcher(&Stat); + pkgAcquire Fetcher; + if (Fetcher.Setup(&Stat, _config->FindDir("Dir::State::Lists")) == false) + return false; // Populate it with the source selection if (List.GetIndexes(&Fetcher) == false) diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 75adce305..16f7ce929 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -18,6 +18,7 @@ /*}}}*/ // Include Files /*{{{*/ #include +#include #include #include #include @@ -197,6 +198,57 @@ bool FileExists(string File) return true; } /*}}}*/ +// DirectoryExists - Check if a directory exists and is really one /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool DirectoryExists(string const &Path) +{ + struct stat Buf; + if (stat(Path.c_str(),&Buf) != 0) + return false; + return ((Buf.st_mode & S_IFDIR) != 0); +} + /*}}}*/ +// CreateDirectory - poor man's mkdir -p guarded by a parent directory /*{{{*/ +// --------------------------------------------------------------------- +/* This method will create all directories needed for path in good old + mkdir -p style but refuses to do this if Parent is not a prefix of + this Path. Example: /var/cache/ and /var/cache/apt/archives are given, + so it will create apt/archives if /var/cache exists - on the other + hand if the parent is /var/lib the creation will fail as this path + is not a parent of the path to be generated. */ +bool CreateDirectory(string const &Parent, string const &Path) +{ + if (Parent.empty() == true || Path.empty() == true) + return false; + + if (DirectoryExists(Path) == true) + return true; + + if (DirectoryExists(Parent) == false) + return false; + + // we are not going to create directories "into the blue" + if (Path.find(Parent, 0) != 0) + return false; + + vector const dirs = VectorizeString(Path.substr(Parent.size()), '/'); + string progress = Parent; + for (vector::const_iterator d = dirs.begin(); d != dirs.end(); ++d) + { + if (d->empty() == true) + continue; + + progress.append("/").append(*d); + if (DirectoryExists(progress) == true) + continue; + + if (mkdir(progress.c_str(), 0755) != 0) + return false; + } + return true; +} + /*}}}*/ // GetListOfFilesInDir - returns a vector of files in the given dir /*{{{*/ // --------------------------------------------------------------------- /* If an extension is given only files with this extension are included diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 351d53c5e..003bd9b83 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -21,6 +21,7 @@ #ifndef PKGLIB_FILEUTL_H #define PKGLIB_FILEUTL_H +#include #include #include @@ -82,6 +83,8 @@ bool RunScripts(const char *Cnf); bool CopyFile(FileFd &From,FileFd &To); int GetLock(string File,bool Errors = true); bool FileExists(string File); +bool DirectoryExists(string const &Path) __attrib_const; +bool CreateDirectory(string const &Parent, string const &Path); std::vector GetListOfFilesInDir(string const &Dir, string const &Ext, bool const &SortList, bool const &AllowNoExt=false); std::vector GetListOfFilesInDir(string const &Dir, std::vector const &Ext, diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 21240b951..114c9d5ed 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -1003,7 +1003,20 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, // Decide if we can write to the files.. string const CacheFile = _config->FindFile("Dir::Cache::pkgcache"); string const SrcCacheFile = _config->FindFile("Dir::Cache::srcpkgcache"); - + + // ensure the cache directory exists + if (CacheFile.empty() == false || SrcCacheFile.empty() == false) + { + string dir = _config->FindDir("Dir::Cache"); + size_t const len = dir.size(); + if (len > 5 && dir.find("/apt/", len - 6, 5) == len - 5) + dir = dir.substr(0, len - 5); + if (CacheFile.empty() == false) + CreateDirectory(dir, flNotFile(CacheFile)); + if (SrcCacheFile.empty() == false) + CreateDirectory(dir, flNotFile(SrcCacheFile)); + } + // Decide if we can write to the cache bool Writeable = false; if (CacheFile.empty() == false) -- cgit v1.2.3 From a722b2c5c935768efbdd5b23eed7ce32ccd60908 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 9 Apr 2010 15:38:48 +0200 Subject: * apt-pkg/acquire-item.cc: - Acquire::ForceHash to force method for expected hash - display MD5Sum in --print-uris if not forced to use another method instead of displaying the strongest available (Closes: #576420) --- apt-pkg/acquire-item.cc | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 4f0abbb91..916fca71e 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -1327,7 +1327,8 @@ pkgAcqArchive::pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources, the archive is already available in the cache and stashs the MD5 for checking later. */ bool pkgAcqArchive::QueueNext() -{ +{ + string const ForceHash = _config->Find("Acquire::ForceHash"); for (; Vf.end() == false; Vf++) { // Ignore not source sources @@ -1350,12 +1351,25 @@ bool pkgAcqArchive::QueueNext() return false; string PkgFile = Parse.FileName(); - if(Parse.SHA256Hash() != "") - ExpectedHash = HashString("SHA256", Parse.SHA256Hash()); - else if (Parse.SHA1Hash() != "") - ExpectedHash = HashString("SHA1", Parse.SHA1Hash()); - else - ExpectedHash = HashString("MD5Sum", Parse.MD5Hash()); + if (ForceHash.empty() == false) + { + if(stringcasecmp(ForceHash, "sha256") == 0) + ExpectedHash = HashString("SHA256", Parse.SHA256Hash()); + else if (stringcasecmp(ForceHash, "sha1") == 0) + ExpectedHash = HashString("SHA1", Parse.SHA1Hash()); + else + ExpectedHash = HashString("MD5Sum", Parse.MD5Hash()); + } + else + { + string Hash; + if ((Hash = Parse.SHA256Hash()).empty() == false) + ExpectedHash = HashString("SHA256", Hash); + else if ((Hash = Parse.SHA1Hash()).empty() == false) + ExpectedHash = HashString("SHA1", Hash); + else + ExpectedHash = HashString("MD5Sum", Parse.MD5Hash()); + } if (PkgFile.empty() == true) return _error->Error(_("The package index files are corrupted. No Filename: " "field for package %s."), -- cgit v1.2.3 From 3d5a34b22a83eb4bf9b1407e13240b8e2a333d5f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 13 Apr 2010 09:28:57 +0200 Subject: regex for package names executed on Grp- not PkgIterator --- apt-pkg/depcache.h | 1 + 1 file changed, 1 insertion(+) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 6765d3e7c..72b9b5d4d 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -331,6 +331,7 @@ class pkgDepCache : protected pkgCache::Namespace // Legacy.. We look like a pkgCache inline operator pkgCache &() {return *Cache;}; inline Header &Head() {return *Cache->HeaderP;}; + inline GrpIterator GrpBegin() {return Cache->GrpBegin();}; inline PkgIterator PkgBegin() {return Cache->PkgBegin();}; inline GrpIterator FindGrp(string const &Name) {return Cache->FindGrp(Name);}; inline PkgIterator FindPkg(string const &Name) {return Cache->FindPkg(Name);}; -- cgit v1.2.3 From 9c2c9c24f7027a0299e545e55c38ac4c557359a5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 13 Apr 2010 10:18:19 +0200 Subject: create the partial dirs also automatic if only Dir::Cache::archives or Dir::Cache::lists was set --- apt-pkg/acquire.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index d83d80fac..832eaa02c 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -69,9 +69,18 @@ bool pkgAcquire::Setup(pkgAcquireStatus *Progress, string const &Lock) Log = Progress; // check for existence and possibly create auxiliary directories - if (CheckDirectory(_config->FindDir("Dir::State"), _config->FindDir("Dir::State::lists") + "partial/") == false || - CheckDirectory(_config->FindDir("Dir::Cache"), _config->FindDir("Dir::Cache::Archives") + "partial/") == false) - return false; + string const listDir = _config->FindDir("Dir::State::lists"); + string const partialListDir = listDir + "partial/"; + string const archivesDir = _config->FindDir("Dir::Cache::Archives"); + string const partialArchivesDir = archivesDir + "partial/"; + + if (CheckDirectory(_config->FindDir("Dir::State"), partialListDir) == false && + CheckDirectory(listDir, partialListDir) == false) + return _error->Errno("Acquire", _("List directory %spartial is missing."), listDir.c_str()); + + if (CheckDirectory(_config->FindDir("Dir::Cache"), partialArchivesDir) == false && + CheckDirectory(archivesDir, partialArchivesDir) == false) + return _error->Errno("Acquire", _("Archives directory %spartial is missing."), archivesDir.c_str()); if (Lock.empty() == true || _config->FindB("Debug::NoLocking", false) == true) return true; @@ -94,7 +103,7 @@ bool pkgAcquire::CheckDirectory(string const &Parent, string const &Path) const return true; size_t const len = Parent.size(); - if (len > 5 && Parent.find("/apt/", len - 6, 5) != len - 5) + if (len > 5 && Parent.find("/apt/", len - 6, 5) == len - 5) { if (CreateDirectory(Parent.substr(0,len-5), Path) == true) return true; @@ -102,7 +111,7 @@ bool pkgAcquire::CheckDirectory(string const &Parent, string const &Path) const else if (CreateDirectory(Parent, Path) == true) return true; - return _error->Errno("Acquire", _("Directory %s can't be created."), Path.c_str()); + return false; } /*}}}*/ // Acquire::~pkgAcquire - Destructor /*{{{*/ -- cgit v1.2.3 From 05bae55fb7fe23b2061182a60db2f2f914a2d3ec Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 14 Apr 2010 18:01:11 +0200 Subject: * apt-pkg/deb/dpkgpm.cc: - remove Chroot-Directory from files passed to install commands. Thanks to Kel Modderman for report & patch! (Closes: #577226) --- apt-pkg/deb/dpkgpm.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 14a4968f7..ca8faa8a5 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -124,7 +124,19 @@ bool pkgDPkgPM::Install(PkgIterator Pkg,string File) if (File.empty() == true || Pkg.end() == true) return _error->Error("Internal Error, No file name for %s",Pkg.Name()); - List.push_back(Item(Item::Install,Pkg,File)); + // If the filename string begins with DPkg::Chroot-Directory, return the + // substr that is within the chroot so dpkg can access it. + string const chrootdir = _config->FindDir("DPkg::Chroot-Directory","/"); + if (chrootdir != "/" && File.find(chrootdir) == 0) + { + size_t len = chrootdir.length(); + if (chrootdir.at(len - 1) == '/') + len--; + List.push_back(Item(Item::Install,Pkg,File.substr(len))); + } + else + List.push_back(Item(Item::Install,Pkg,File)); + return true; } /*}}}*/ -- cgit v1.2.3 From 6838dd8781d2986e51b7c65b7b404a70cfcd2321 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 24 Apr 2010 12:15:59 +0200 Subject: * apt-pkg/sourcelist.cc: - be less strict and accept [option=value] as well --- apt-pkg/sourcelist.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index a860c7eac..e13472fa6 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -94,6 +94,13 @@ bool pkgSourceList::Type::ParseLine(vector &List, if (option.length() < 3) return _error->Error(_("Malformed line %lu in source list %s ([option] too short)"),CurLine,File.c_str()); + // accept options even if the last has no space before the ]-end marker + if (option.at(option.length()-1) == ']') + { + for (; *Buffer != ']'; --Buffer); + option.resize(option.length()-1); + } + 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()); -- cgit v1.2.3 From c3a3a1b1b68706df40dc022bdcdf8ede684f5956 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 24 Apr 2010 12:44:11 +0200 Subject: * apt-pkg/contrib/configuration.cc: - error out if #clear directive has no argument --- apt-pkg/contrib/configuration.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc index 7588b041c..9129d92f0 100644 --- a/apt-pkg/contrib/configuration.cc +++ b/apt-pkg/contrib/configuration.cc @@ -773,6 +773,8 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio else return _error->Error(_("Syntax error %s:%u: Unsupported directive '%s'"),FName.c_str(),CurLine,Tag.c_str()); } + else if (Tag.empty() == true && NoWord == false && Word == "#clear") + return _error->Error(_("Syntax error %s:%u: clear directive requires an option tree as argument"),FName.c_str(),CurLine); else { // Set the item in the configuration class -- cgit v1.2.3 From 77278c2b5249162036121c20d537ca53e5914f0d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 28 Apr 2010 09:41:44 +0200 Subject: * [ Abi break ] apt-pkg/acquire-item.{cc,h}: - add "IsIndexFile" to constructor of pkgAcqFile so that it sends the right cache control headers --- apt-pkg/acquire-item.cc | 14 ++++++++++++-- apt-pkg/acquire-item.h | 9 ++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index d2aca597e..270838f0e 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -1539,8 +1539,9 @@ void pkgAcqArchive::Finished() /* The file is added to the queue */ pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string Hash, unsigned long Size,string Dsc,string ShortDesc, - const string &DestDir, const string &DestFilename) : - Item(Owner), ExpectedHash(Hash) + const string &DestDir, const string &DestFilename, + bool IsIndexFile) : + Item(Owner), ExpectedHash(Hash), IsIndexFile(IsIndexFile) { Retries = _config->FindI("Acquire::Retries",0); @@ -1655,3 +1656,12 @@ void pkgAcqFile::Failed(string Message,pkgAcquire::MethodConfig *Cnf) Item::Failed(Message,Cnf); } /*}}}*/ +// AcqIndex::Custom600Headers - Insert custom request headers /*{{{*/ +// --------------------------------------------------------------------- +/* The only header we use is the last-modified header. */ +string pkgAcqFile::Custom600Headers() +{ + if (IsIndexFile) + return "\nIndex-File: true"; +} + /*}}}*/ diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index 3f073de5b..592924f3b 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -856,6 +856,9 @@ class pkgAcqFile : public pkgAcquire::Item */ unsigned int Retries; + /** \brief Should this file be considered a index file */ + bool IsIndexFile; + public: // Specialized action members @@ -864,6 +867,7 @@ class pkgAcqFile : public pkgAcquire::Item pkgAcquire::MethodConfig *Cnf); virtual string DescURI() {return Desc.URI;}; virtual string HashSum() {return ExpectedHash.toStr(); }; + virtual string Custom600Headers(); /** \brief Create a new pkgAcqFile object. * @@ -887,6 +891,8 @@ class pkgAcqFile : public pkgAcquire::Item * * \param DestFilename The filename+path the file is downloaded to. * + * \param IsIndexFile The file is considered a IndexFile and cache-control + * headers like "cache-control: max-age=0" are send * * If DestFilename is empty, download to DestDir/ if * DestDir is non-empty, $CWD/ otherwise. If @@ -896,7 +902,8 @@ class pkgAcqFile : public pkgAcquire::Item pkgAcqFile(pkgAcquire *Owner, string URI, string Hash, unsigned long Size, string Desc, string ShortDesc, - const string &DestDir="", const string &DestFilename=""); + const string &DestDir="", const string &DestFilename="", + bool IsIndexFile=false); }; /*}}}*/ /** @} */ -- cgit v1.2.3 From 0c01e682d29051d4e26ea60e378796d30569ba5f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 28 Apr 2010 15:45:06 +0200 Subject: * apt-pkg/depcache.cc: - fix incorrect std::cout usage for debug output --- apt-pkg/depcache.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index ec7a5de64..37b1c889d 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -186,7 +186,7 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) /*{{{*/ if(reason > 0) PkgState[pkg->ID].Flags |= Flag::Auto; if(debug_autoremove) - std::cout << "Auto-Installed : " << pkgname << std::endl; + std::clog << "Auto-Installed : " << pkgname << std::endl; amt+=section.size(); if(Prog != NULL) Prog->OverallProgress(amt, file_size, 1, @@ -1511,7 +1511,7 @@ bool pkgDepCache::Sweep() /*{{{*/ { state.Garbage=true; if(debug_autoremove) - std::cout << "Garbage: " << p.Name() << std::endl; + std::clog << "Garbage: " << p.Name() << std::endl; } } -- cgit v1.2.3 From 4dec007b1d8af31824903ffa3099ff4839ab528e Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 28 Apr 2010 15:49:55 +0200 Subject: apt-pkg/policy.cc: yet another cout -> clog fix --- apt-pkg/policy.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index f9901bc9a..a24ab7452 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -106,7 +106,7 @@ bool pkgPolicy::InitDefaults() if (_config->FindB("Debug::pkgPolicy",false) == true) for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); F++) - cout << "Prio of " << F.FileName() << ' ' << PFPriority[F->ID] << endl; + std::clog << "Prio of " << F.FileName() << ' ' << PFPriority[F->ID] << std::endl; return true; } -- cgit v1.2.3 From edde664d0cc5fe46f572696c605832700c553b9e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 28 Apr 2010 16:25:05 +0200 Subject: rewrite the pseudo package reinstaller to be more intelligent in his package choices The previous implementation tried to install the package for arch A and if this fails B, C and so on. This results in wrong architecture choices for packages which depend on other pseudo packages, so he will now try to install the dependencies first before trying the package itself and only if this fails he tries the next architecture. --- apt-pkg/depcache.cc | 120 +++++++++++++++++++++++++++++++++++----------------- apt-pkg/depcache.h | 2 + 2 files changed, 84 insertions(+), 38 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 0f07de2fe..a63deee3a 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -841,45 +841,15 @@ void pkgDepCache::Update(OpProgress *Prog) if (installed == false) recheck.insert(G.Index()); } - std::vector Archs = APT::Configuration::getArchitectures(); - bool checkChanged = false; - do { - for(std::set::const_iterator g = recheck.begin(); - g != recheck.end(); ++g) { - GrpIterator G = GrpIterator(*Cache, Cache->GrpP + *g); - VerIterator allV = G.FindPkg("all").CurrentVer(); - for (std::vector::const_iterator a = Archs.begin(); - a != Archs.end(); ++a) - { - PkgIterator P = G.FindPkg(*a); - if (P.end() == true) continue; - for (VerIterator V = P.VersionList(); V.end() != true; ++V) - { - if (allV->Hash != V->Hash || - strcmp(allV.VerStr(),V.VerStr()) != 0) - continue; - unsigned char const CurDepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy); - if ((CurDepState & DepInstMin) != DepInstMin) - break; // we found the correct version, but it is broken. Better try another arch or later again - RemoveSizes(P); - RemoveStates(P); - P->CurrentVer = V.Index(); - PkgState[P->ID].InstallVer = V; - AddStates(P); - Update(P); - AddSizes(P); - checkChanged = true; - break; - } - } - recheck.erase(g); - } - } while (checkChanged == true && recheck.empty() == false); - if (_config->FindB("Debug::MultiArchKiller", false) == true) - for(std::set::const_iterator g = recheck.begin(); - g != recheck.end(); ++g) - std::cout << "No pseudo package for »" << GrpIterator(*Cache, Cache->GrpP + *g).Name() << "« installed" << std::endl; + while (recheck.empty() != true) + { + std::set::const_iterator g = recheck.begin(); + unsigned long const G = *g; + recheck.erase(g); + if (unlikely(ReInstallPseudoForGroup(G, recheck) == false)) + _error->Warning(_("Internal error, group »%s« has no installable pseudo package"), GrpIterator(*Cache, Cache->GrpP + *g).Name()); + } } if (Prog != 0) @@ -888,6 +858,80 @@ void pkgDepCache::Update(OpProgress *Prog) readStateFile(Prog); } /*}}}*/ +// DepCache::ReInstallPseudoForGroup - MultiArch helper for Update() /*{{{*/ +// --------------------------------------------------------------------- +/* RemovePseudoInstalledPkg() is very successful. It even kills packages + to an amount that no pseudo package is left, but we need a pseudo package + for upgrading senarios so we need to reinstall one pseudopackage which + doesn't break everything. Thankfully we can't have architecture depending + negative dependencies so this problem is already eliminated */ +bool pkgDepCache::ReInstallPseudoForGroup(pkgCache::PkgIterator const &P, std::set &recheck) +{ + if (P->CurrentVer != 0) + return true; + // recursive call for packages which provide this package + for (pkgCache::PrvIterator Prv = P.ProvidesList(); Prv.end() != true; ++Prv) + ReInstallPseudoForGroup(Prv.OwnerPkg(), recheck); + // check if we actually need to look at this group + unsigned long const G = P->Group; + std::set::const_iterator Pi = recheck.find(G); + if (Pi == recheck.end()) + return true; + recheck.erase(Pi); // remove here, so we can't fall into an endless loop + if (unlikely(ReInstallPseudoForGroup(G, recheck) == false)) + { + recheck.insert(G); + return false; + } + return true; +} +bool pkgDepCache::ReInstallPseudoForGroup(unsigned long const &G, std::set &recheck) +{ + std::vector static const Archs = APT::Configuration::getArchitectures(); + pkgCache::GrpIterator Grp(*Cache, Cache->GrpP + G); + if (unlikely(Grp.end() == true)) + return false; + for (std::vector::const_iterator a = Archs.begin(); + a != Archs.end(); ++a) + { + pkgCache::PkgIterator P = Grp.FindPkg(*a); + if (P.end() == true) + continue; + pkgCache::VerIterator allV = Grp.FindPkg("all").CurrentVer(); + for (VerIterator V = P.VersionList(); V.end() != true; ++V) + { + // search for the same version as the all package + if (allV->Hash != V->Hash || strcmp(allV.VerStr(),V.VerStr()) != 0) + continue; + unsigned char const CurDepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy); + // If it is broken, try to install dependencies first before retry + if ((CurDepState & DepInstMin) != DepInstMin) + { + for (pkgCache::DepIterator D = V.DependsList(); D.end() != true; ++D) + { + if (D->Type != pkgCache::Dep::PreDepends && D->Type != pkgCache::Dep::Depends) + continue; + ReInstallPseudoForGroup(D.TargetPkg(), recheck); + } + unsigned char const CurDepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy); + // if package ist still broken… try another arch + if ((CurDepState & DepInstMin) != DepInstMin) + break; + } + // dependencies satisfied: reinstall the package + RemoveSizes(P); + RemoveStates(P); + P->CurrentVer = V.Index(); + PkgState[P->ID].InstallVer = V; + AddStates(P); + Update(P); + AddSizes(P); + return true; + } + } + return false; +} + /*}}}*/ // DepCache::Update - Update the deps list of a package /*{{{*/ // --------------------------------------------------------------------- /* This is a helper for update that only does the dep portion of the scan. diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 72b9b5d4d..3decc7a5f 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -470,6 +470,8 @@ class pkgDepCache : protected pkgCache::Namespace private: // Helper for Update(OpProgress) to remove pseudoinstalled arch all packages bool RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set &recheck); + bool ReInstallPseudoForGroup(unsigned long const &Grp, std::set &recheck); + bool ReInstallPseudoForGroup(pkgCache::PkgIterator const &P, std::set &recheck); }; #endif -- cgit v1.2.3 From 8f40076991ecc89ab1e3c486da2696a44c285f18 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 3 May 2010 10:07:13 +0200 Subject: * apt-pkg/indexfile.cc: - If no "_" is found in the language code, try to find a "." This is required for languages like Esperanto that have no county associated with them (LP: #560956) Thanks to "Aisano" for the fix --- apt-pkg/indexfile.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/indexfile.cc b/apt-pkg/indexfile.cc index 34fd71b20..5a82b7b2e 100644 --- a/apt-pkg/indexfile.cc +++ b/apt-pkg/indexfile.cc @@ -127,6 +127,8 @@ string pkgIndexFile::LanguageCode() 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; } -- cgit v1.2.3 From 583f7c147dc479bbdb431aa94c4d589d785207c3 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 3 May 2010 16:55:11 +0200 Subject: =?UTF-8?q?replace=20=C2=BB=C2=AB=20with=20''=20in=20the=20interna?= =?UTF-8?q?l=20error=20msg=20to=20have=20ascii=20chars=20for=20gettext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apt-pkg/depcache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index a63deee3a..659c4227e 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -848,7 +848,7 @@ void pkgDepCache::Update(OpProgress *Prog) unsigned long const G = *g; recheck.erase(g); if (unlikely(ReInstallPseudoForGroup(G, recheck) == false)) - _error->Warning(_("Internal error, group »%s« has no installable pseudo package"), GrpIterator(*Cache, Cache->GrpP + *g).Name()); + _error->Warning(_("Internal error, group '%s' has no installable pseudo package"), GrpIterator(*Cache, Cache->GrpP + *g).Name()); } } -- cgit v1.2.3 From 94449d7cd3eed7637c1ed78863c01ff207faa31e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 4 May 2010 12:30:13 +0200 Subject: * doc/cache.sgml: - drop the file in favor of inplace documentation with doxygen --- apt-pkg/pkgcache.h | 469 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 385 insertions(+), 84 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 577eebad9..a2e63ff03 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -1,20 +1,75 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: pkgcache.h,v 1.25 2001/07/01 22:28:24 jgg Exp $ -/* ###################################################################### - - Cache - Structure definitions for the cache file - - Please see doc/apt-pkg/cache.sgml for a more detailed description of - this format. Also be sure to keep that file up-to-date!! - +/**\file pkgcache.h + \brief pkgCache - Structure definitions for the cache file + + The goal of the cache file is two fold: + Firstly to speed loading and processing of the package file array and + secondly to reduce memory consumption of the package file array. + + The implementation is aimed at an environment with many primary package + files, for instance someone that has a Package file for their CD-ROM, a + Package file for the latest version of the distribution on the CD-ROM and a + package file for the development version. Always present is the information + contained in the status file which might be considered a separate package + file. + + Please understand, this is designed as a Cache file it is not meant to be + used on any system other than the one it was created for. It is not meant to + be authoritative either, i.e. if a system crash or software failure occurs it + must be perfectly acceptable for the cache file to be in an inconsistent + state. Furthermore at any time the cache file may be erased without losing + any information. + + Also the structures and storage layout is optimized for use by the APT + and may not be suitable for all purposes. However it should be possible + to extend it with associate cache files that contain other information. + + To keep memory use down the cache file only contains often used fields and + fields that are inexpensive to store, the Package file has a full list of + fields. Also the client may assume that all items are perfectly valid and + need not perform checks against their correctness. Removal of information + from the cache is possible, but blanks will be left in the file, and + unused strings will also be present. The recommended implementation is to + simply rebuild the cache each time any of the data files change. It is + possible to add a new package file to the cache without any negative side + effects. + + Note on Pointer access Clients should always use the CacheIterators classes for access to the - cache. They provide a simple STL-like method for traversing the links - of the datastructure. - - See pkgcachegen.h for information about generating cache structures. - - ##################################################################### */ + cache and the data in it. They also provide a simple STL-like method for + traversing the links of the datastructure. + + Every item in every structure is stored as the index to that structure. + What this means is that once the files is mmaped every data access has to + go through a fix up stage to get a real memory pointer. This is done + by taking the index, multiplying it by the type size and then adding + it to the start address of the memory block. This sounds complex, but + in C it is a single array dereference. Because all items are aligned to + their size and indexes are stored as multiples of the size of the structure + the format is immediately portable to all possible architectures - BUT the + generated files are -NOT-. + + This scheme allows code like this to be written: + + void *Map = mmap(...); + Package *PkgList = (Package *)Map; + Header *Head = (Header *)Map; + char *Strings = (char *)Map; + cout << (Strings + PkgList[Head->HashTable[0]]->Name) << endl; + + Notice the lack of casting or multiplication. The net result is to return + the name of the first package in the first hash bucket, without error + checks. + + The generator uses allocation pools to group similarly sized structures in + large blocks to eliminate any alignment overhead. The generator also + assures that no structures overlap and all indexes are unique. Although + at first glance it may seem like there is the potential for two structures + to exist at the same point the generator never allows this to happen. + (See the discussion of free space pools) + + See \ref pkgcachegen.h for more information about generating cache structures. */ /*}}}*/ #ifndef PKGLIB_PKGCACHE_H #define PKGLIB_PKGCACHE_H @@ -66,12 +121,20 @@ class pkgCache /*{{{*/ { enum DepType {Depends=1,PreDepends=2,Suggests=3,Recommends=4, Conflicts=5,Replaces=6,Obsoletes=7,DpkgBreaks=8,Enhances=9}; + /** \brief available compare operators + + The lower 4 bits are used to indicate what operator is being specified and + the upper 4 bits are flags. OR indicates that the next package is + or'd with the current package. */ enum DepCompareOp {Or=0x10,NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3, Greater=0x4,Equals=0x5,NotEquals=0x6}; }; struct State { + /** \brief priority of a package version + + Zero is used for unparsable or absent Priority fields. */ enum VerPriority {Important=1,Required=2,Standard=3,Optional=4,Extra=5}; enum PkgSelectedState {Unknown=0,Install=1,Hold=2,DeInstall=3,Purge=4}; enum PkgInstState {Ok=0,ReInstReq=1,HoldInst=2,HoldReInstReq=3}; @@ -120,7 +183,7 @@ class pkgCache /*{{{*/ inline unsigned long Hash(const string &S) const {return sHash(S);}; inline unsigned long Hash(const char *S) const {return sHash(S);}; - // Usefull transformation things + // Useful transformation things const char *Priority(unsigned char Priority); // Accessors @@ -157,13 +220,29 @@ private: // Header structure /*{{{*/ struct pkgCache::Header { - // Signature information + /** \brief Signature information + + This must contain the hex value 0x98FE76DC which is designed to + verify that the system loading the image has the same byte order + and byte size as the system saving the image */ unsigned long Signature; + /** These contain the version of the cache file */ short MajorVersion; short MinorVersion; + /** \brief indicates if the cache should be erased + + Dirty is true if the cache file was opened for reading, the client + expects to have written things to it and have not fully synced it. + The file should be erased and rebuilt if it is true. */ bool Dirty; - - // Size of structure values + + /** \brief Size of structure values + + All *Sz variables contains the sizeof() that particular structure. + It is used as an extra consistency check on the structure of the file. + + If any of the size values do not exactly match what the client expects + then the client should refuse the load the file. */ unsigned short HeaderSz; unsigned short PackageSz; unsigned short PackageFileSz; @@ -173,8 +252,12 @@ struct pkgCache::Header unsigned short ProvidesSz; unsigned short VerFileSz; unsigned short DescFileSz; - - // Structure counts + + /** \brief Structure counts + + These indicate the number of each structure contained in the cache. + PackageCount is especially useful for generating user state structures. + See Package::Id for more info. */ unsigned long GroupCount; unsigned long PackageCount; unsigned long VersionCount; @@ -184,22 +267,48 @@ struct pkgCache::Header unsigned long VerFileCount; unsigned long DescFileCount; unsigned long ProvidesCount; - - // Offsets - map_ptrloc FileList; // struct PackageFile - map_ptrloc StringList; // struct StringItem - map_ptrloc VerSysName; // StringTable - map_ptrloc Architecture; // StringTable + + /** \brief index of the first PackageFile structure + + The PackageFile structures are singly linked lists that represent + all package files that have been merged into the cache. */ + map_ptrloc FileList; + /** \brief index of the first StringItem structure + + The cache contains a list of all the unique strings (StringItems). + The parser reads this list into memory so it can match strings + against it.*/ + map_ptrloc StringList; + /** \brief String representing the version system used */ + map_ptrloc VerSysName; + /** \brief Architecture(s) the cache was built against */ + map_ptrloc Architecture; + /** \brief The maximum size of a raw entry from the original Package file */ unsigned long MaxVerFileSize; + /** \brief The maximum size of a raw entry from the original Translation file */ unsigned long MaxDescFileSize; - /* Allocation pools, there should be one of these for each structure - excluding the header */ + /** \brief The Pool structures manage the allocation pools that the generator uses + + Start indicates the first byte of the pool, Count is the number of objects + remaining in the pool and ItemSize is the structure size (alignment factor) + of the pool. An ItemSize of 0 indicates the pool is empty. There should be + the same number of pools as there are structure types. The generator + stores this information so future additions can make use of any unused pool + blocks. */ DynamicMMap::Pool Pools[9]; - // Rapid package and group name lookup - // Notice: Increase only both table sizes as the - // hashmethod assume the size of the Pkg one + /** \brief hash tables providing rapid group/package name lookup + + Each group/package name is inserted into the hash table using pkgCache::Hash(const &string) + By iterating over each entry in the hash table it is possible to iterate over + the entire list of packages. Hash Collisions are handled with a singly linked + list of packages based at the hash item. The linked list contains only + packages that match the hashing function. + In the PkgHashTable is it possible that multiple packages have the same name - + these packages are stored as a sequence in the list. + + Beware: The Hashmethod assumes that the hash table sizes are equal */ map_ptrloc PkgHashTable[2*1048]; map_ptrloc GrpHashTable[2*1048]; @@ -207,140 +316,332 @@ struct pkgCache::Header Header(); }; /*}}}*/ -struct pkgCache::Group { /*{{{*/ - map_ptrloc Name; // Stringtable +// Group structure /*{{{*/ +/** \brief groups architecture depending packages together - // Linked List - map_ptrloc FirstPackage;// Package - map_ptrloc LastPackage; // Package - map_ptrloc Next; // Group + On or more packages with the same name form a group, so we have + a simple way to access a package built for different architectures + Group exists in a singly linked list of group records starting at + the hash index of the name in the pkgCache::Header::GrpHashTable */ +struct pkgCache::Group +{ + /** \brief Name of the group */ + map_ptrloc Name; // StringItem + + // Linked List + /** Link to the first package which belongs to the group */ + map_ptrloc FirstPackage; // Package + /** Link to the last package which belongs to the group */ + map_ptrloc LastPackage; // Package + /** Link to the next Group */ + map_ptrloc Next; // Group }; /*}}}*/ -struct pkgCache::Package /*{{{*/ +// Package structure /*{{{*/ +/** \brief contains information for a single unique package + + There can be any number of versions of a given package. + Package exists in a singly linked list of package records starting at + the hash index of the name in the pkgCache::Header::PkgHashTable + + A package can be created for every architecture so package names are + not unique, but it is garanteed that packages with the same name + are sequencel ordered in the list. Packages with the same name can be + accessed with the Group. +*/ +struct pkgCache::Package { - // Pointers - map_ptrloc Name; // Stringtable - map_ptrloc Arch; // StringTable (StringItem) + /** \brief Name of the package */ + map_ptrloc Name; // StringItem + /** \brief Architecture of the package */ + map_ptrloc Arch; // StringItem + /** \brief Base of a singly linked list of versions + + Each structure represents a unique version of the package. + The version structures contain links into PackageFile and the + original text file as well as detailed information about the size + and dependencies of the specific package. In this way multiple + versions of a package can be cleanly handled by the system. + Furthermore, this linked list is guaranteed to be sorted + from Highest version to lowest version with no duplicate entries. */ map_ptrloc VersionList; // Version + /** \brief index to the installed version */ map_ptrloc CurrentVer; // Version - map_ptrloc Section; // StringTable (StringItem) + /** \brief indicates the deduced section + + Should be the index to the string "Unknown" or to the section + of the last parsed item. */ + map_ptrloc Section; // StringItem + /** \brief index of the group this package belongs to */ map_ptrloc Group; // Group the Package belongs to - - // Linked list + + // Linked list + /** \brief Link to the next package in the same bucket */ map_ptrloc NextPackage; // Package + /** \brief List of all dependencies on this package */ map_ptrloc RevDepends; // Dependency + /** \brief List of all "packages" this package provide */ map_ptrloc ProvidesList; // Provides // Install/Remove/Purge etc + /** \brief state that the user wishes the package to be in */ unsigned char SelectedState; // What + /** \brief installation state of the package + + This should be "ok" but in case the installation failed + it will be different. + */ unsigned char InstState; // Flags + /** \brief indicates if the package is installed */ unsigned char CurrentState; // State - + + /** \brief unique sequel ID + + ID is a unique value from 0 to Header->PackageCount assigned by the generator. + This allows clients to create an array of size PackageCount and use it to store + state information for the package map. For instance the status file emitter uses + this to track which packages have been emitted already. */ unsigned int ID; + /** \brief some useful indicators of the package's state */ unsigned long Flags; }; /*}}}*/ -struct pkgCache::PackageFile /*{{{*/ +// Package File structure /*{{{*/ +/** \brief stores information about the files used to generate the cache + + Package files are referenced by Version structures to be able to know + after the generation still from which Packages file includes this Version + as we need this information later on e.g. for pinning. */ +struct pkgCache::PackageFile { - // Names - map_ptrloc FileName; // Stringtable - map_ptrloc Archive; // Stringtable - map_ptrloc Codename; // Stringtable - map_ptrloc Component; // Stringtable - map_ptrloc Version; // Stringtable - map_ptrloc Origin; // Stringtable - map_ptrloc Label; // Stringtable - map_ptrloc Architecture; // Stringtable - map_ptrloc Site; // Stringtable - map_ptrloc IndexType; // Stringtable - unsigned long Size; + /** \brief physical disk file that this PackageFile represents */ + map_ptrloc FileName; // StringItem + /** \brief the release information + + Please see the files document for a description of what the + release information means. */ + map_ptrloc Archive; // StringItem + map_ptrloc Codename; // StringItem + map_ptrloc Component; // StringItem + map_ptrloc Version; // StringItem + map_ptrloc Origin; // StringItem + map_ptrloc Label; // StringItem + map_ptrloc Architecture; // StringItem + /** \brief The site the index file was fetched from */ + map_ptrloc Site; // StringItem + /** \brief indicates what sort of index file this is + + @TODO enumerate at least the possible indexes */ + map_ptrloc IndexType; // StringItem + /** \brief Size of the file + + Used together with the modification time as a + simple check to ensure that the Packages + file has not been altered since Cache generation. */ + unsigned long Size; + /** \brief Modification time for the file */ + time_t mtime; + + /* @TODO document PackageFile::Flags */ unsigned long Flags; - + // Linked list + /** \brief Link to the next PackageFile in the Cache */ map_ptrloc NextFile; // PackageFile + /** \brief unique sequel ID */ unsigned int ID; - time_t mtime; // Modification time for the file }; /*}}}*/ -struct pkgCache::VerFile /*{{{*/ +// VerFile structure /*{{{*/ +/** \brief associates a version with a PackageFile + + This allows a full description of all Versions in all files + (and hence all sources) under consideration. */ +struct pkgCache::VerFile { + /** \brief index of the package file that this version was found in */ map_ptrloc File; // PackageFile + /** \brief next step in the linked list */ map_ptrloc NextFile; // PkgVerFile + /** \brief position in the package file */ map_ptrloc Offset; // File offset + /* @TODO document pkgCache::VerFile::Size */ unsigned long Size; }; /*}}}*/ -struct pkgCache::DescFile /*{{{*/ +// DescFile structure /*{{{*/ +/** \brief associates a description with a Translation file */ +struct pkgCache::DescFile { + /** \brief index of the file that this description was found in */ map_ptrloc File; // PackageFile + /** \brief next step in the linked list */ map_ptrloc NextFile; // PkgVerFile + /** \brief position in the file */ map_ptrloc Offset; // File offset + /* @TODO document pkgCache::DescFile::Size */ unsigned long Size; }; /*}}}*/ -struct pkgCache::Version /*{{{*/ +// Version structure /*{{{*/ +/** \brief information for a single version of a package + + The version list is always sorted from highest version to lowest + version by the generator. Equal version numbers are either merged + or handled as separate versions based on the Hash value. */ +struct pkgCache::Version { - map_ptrloc VerStr; // Stringtable - map_ptrloc Section; // StringTable (StringItem) + /** \brief complete version string */ + map_ptrloc VerStr; // StringItem + /** \brief section this version is filled in */ + map_ptrloc Section; // StringItem + /** \brief stores the MultiArch capabilities of this version + + None is the default and doesn't trigger special behaviour, + Foreign means that this version can fulfill dependencies even + if it is built for another architecture as the requester. + Same indicates that builds for different architectures can + be co-installed on the system and All is the marker for a + version with the Architecture: all. */ enum {None, All, Foreign, Same, Allowed} MultiArch; - // Lists + /** \brief references all the PackageFile's that this version came from + + FileList can be used to determine what distribution(s) the Version + applies to. If FileList is 0 then this is a blank version. + The structure should also have a 0 in all other fields excluding + pkgCache::Version::VerStr and Possibly pkgCache::Version::NextVer. */ map_ptrloc FileList; // VerFile + /** \brief next (lower or equal) version in the linked list */ map_ptrloc NextVer; // Version + /** \brief next description in the linked list */ map_ptrloc DescriptionList; // Description + /** \brief base of the dependency list */ map_ptrloc DependsList; // Dependency + /** \brief links to the owning package + + This allows reverse dependencies to determine the package */ map_ptrloc ParentPkg; // Package + /** \brief list of pkgCache::Provides */ map_ptrloc ProvidesList; // Provides - + + /** \brief archive size for this version + + For Debian this is the size of the .deb file. */ map_ptrloc Size; // These are the .deb size + /** \brief uncompressed size for this version */ map_ptrloc InstalledSize; + /** \brief characteristic value representing this version + + No two packages in existence should have the same VerStr + and Hash with different contents. */ unsigned short Hash; + /** \brief unique sequel ID */ unsigned int ID; + /** \brief parsed priority value */ unsigned char Priority; }; /*}}}*/ -struct pkgCache::Description /*{{{*/ +// Description structure /*{{{*/ +/** \brief datamember of a linked list of available description for a version */ +struct pkgCache::Description { - // Language Code store the description translation language code. If - // the value has a 0 lenght then this is readed using the Package - // file else the Translation-CODE are used. - map_ptrloc language_code; // StringTable - map_ptrloc md5sum; // StringTable + /** \brief Language code of this description (translation) + + If the value has a 0 length then this is read using the Package + file else the Translation-CODE file is used. */ + map_ptrloc language_code; // StringItem + /** \brief MD5sum of the original description + + Used to map Translations of a description to a version + and to check that the Translation is up-to-date. */ + map_ptrloc md5sum; // StringItem - // Linked list + /* @TODO document pkgCache::Description::FileList */ map_ptrloc FileList; // DescFile + /** \brief next translation for this description */ map_ptrloc NextDesc; // Description + /** \brief the text is a description of this package */ map_ptrloc ParentPkg; // Package + /** \brief unique sequel ID */ unsigned int ID; }; /*}}}*/ -struct pkgCache::Dependency /*{{{*/ +// Dependency structure /*{{{*/ +/** \brief information for a single dependency record + + The records are split up like this to ease processing by the client. + The base of the linked list is pkgCache::Version::DependsList. + All forms of dependencies are recorded here including Depends, + Recommends, Suggests, Enhances, Conflicts, Replaces and Breaks. */ +struct pkgCache::Dependency { - map_ptrloc Version; // Stringtable + /** \brief string of the version the dependency is applied against */ + map_ptrloc Version; // StringItem + /** \brief index of the package this depends applies to + + The generator will - if the package does not already exist - + create a blank (no version records) package. */ map_ptrloc Package; // Package + /** \brief next dependency of this version */ map_ptrloc NextDepends; // Dependency + /** \brief next reverse dependency of this package */ map_ptrloc NextRevDepends; // Dependency + /** \brief version of the package which has the reverse depends */ map_ptrloc ParentVer; // Version - - // Specific types of depends - map_ptrloc ID; + + /** \brief unique sequel ID */ + map_ptrloc ID; + /** \brief Dependency type - Depends, Recommends, Conflicts, etc */ unsigned char Type; + /** \brief comparison operator specified on the depends line + + If the high bit is set then it is a logical OR with the previous record. */ unsigned char CompareOp; }; /*}}}*/ -struct pkgCache::Provides /*{{{*/ +// Provides structure /*{{{*/ +/** \brief handles virtual packages + + When a Provides: line is encountered a new provides record is added + associating the package with a virtual package name. + The provides structures are linked off the package structures. + This simplifies the analysis of dependencies and other aspects A provides + refers to a specific version of a specific package, not all versions need to + provide that provides.*/ +struct pkgCache::Provides { - map_ptrloc ParentPkg; // Pacakge + /** \brief index of the package providing this */ + map_ptrloc ParentPkg; // Package + /** \brief index of the version this provide line applies to */ map_ptrloc Version; // Version - map_ptrloc ProvideVersion; // Stringtable + /** \brief version in the provides line (if any) + + This version allows dependencies to depend on specific versions of a + Provides, as well as allowing Provides to override existing packages. + This is experimental. Note that Debian doesn't allow versioned provides */ + map_ptrloc ProvideVersion; // StringItem + /** \brief next provides (based of package) */ map_ptrloc NextProvides; // Provides + /** \brief next provides (based of version) */ map_ptrloc NextPkgProv; // Provides }; /*}}}*/ -struct pkgCache::StringItem /*{{{*/ +// StringItem structure /*{{{*/ +/** \brief used for generating single instances of strings + + Some things like Section Name are are useful to have as unique tags. + It is part of a linked list based at pkgCache::Header::StringList + + All strings are simply inlined any place in the file that is natural + for the writer. The client should make no assumptions about the positioning + of strings. All StringItems should be null-terminated. */ +struct pkgCache::StringItem { - map_ptrloc String; // Stringtable + /** \brief string this refers to */ + map_ptrloc String; // StringItem + /** \brief Next link in the chain */ map_ptrloc NextItem; // StringItem }; /*}}}*/ -- cgit v1.2.3 From 52c41485092d6da77d2848a955609f22da50372c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 4 May 2010 12:43:08 +0200 Subject: * apt-pkg/pkgcache.h: - enhance the Groups ABI by providing a ID as the other structs does - check also the size of the Group struct then checking for the others --- apt-pkg/pkgcache.cc | 3 +++ apt-pkg/pkgcache.h | 10 +++++++--- apt-pkg/pkgcachegen.cc | 3 +-- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 1bbd74bd9..ba3c5cbf8 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -55,6 +55,7 @@ pkgCache::Header::Header() Dirty = false; HeaderSz = sizeof(pkgCache::Header); + GroupSz = sizeof(pkgCache::Group); PackageSz = sizeof(pkgCache::Package); PackageFileSz = sizeof(pkgCache::PackageFile); VersionSz = sizeof(pkgCache::Version); @@ -64,6 +65,7 @@ pkgCache::Header::Header() VerFileSz = sizeof(pkgCache::VerFile); DescFileSz = sizeof(pkgCache::DescFile); + GroupCount = 0; PackageCount = 0; VersionCount = 0; DescriptionCount = 0; @@ -90,6 +92,7 @@ pkgCache::Header::Header() bool pkgCache::Header::CheckSizes(Header &Against) const { if (HeaderSz == Against.HeaderSz && + GroupSz == Against.GroupSz && PackageSz == Against.PackageSz && PackageFileSz == Against.PackageFileSz && VersionSz == Against.VersionSz && diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index a2e63ff03..643f240b0 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -244,6 +244,7 @@ struct pkgCache::Header If any of the size values do not exactly match what the client expects then the client should refuse the load the file. */ unsigned short HeaderSz; + unsigned short GroupSz; unsigned short PackageSz; unsigned short PackageFileSz; unsigned short VersionSz; @@ -329,12 +330,15 @@ struct pkgCache::Group map_ptrloc Name; // StringItem // Linked List - /** Link to the first package which belongs to the group */ + /** \brief Link to the first package which belongs to the group */ map_ptrloc FirstPackage; // Package - /** Link to the last package which belongs to the group */ + /** \brief Link to the last package which belongs to the group */ map_ptrloc LastPackage; // Package - /** Link to the next Group */ + /** \brief Link to the next Group */ map_ptrloc Next; // Group + /** \brief unique sequel ID */ + unsigned int ID; + }; /*}}}*/ // Package structure /*{{{*/ diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 114c9d5ed..d96d3370f 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -356,8 +356,7 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name) Grp->Next = Cache.HeaderP->GrpHashTable[Hash]; Cache.HeaderP->GrpHashTable[Hash] = Group; - Cache.HeaderP->GroupCount++; - + Grp->ID = Cache.HeaderP->GroupCount++; return true; } /*}}}*/ -- cgit v1.2.3 From 61a07c57a8898f3888245493032784cd1c82e956 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 4 May 2010 13:34:34 +0200 Subject: fix compiler warning: reaching end of non-void method --- apt-pkg/acquire-item.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 1f253bb81..c035b9163 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -1685,5 +1685,6 @@ string pkgAcqFile::Custom600Headers() { if (IsIndexFile) return "\nIndex-File: true"; + return ""; } /*}}}*/ -- cgit v1.2.3 From 229fb1a3a35bade26cfff373087461d7a98aade3 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 4 May 2010 17:05:23 +0200 Subject: * apt-pkg/contrib/weakptr.h: - add a class WeakPointable which allows one to register weak pointers to an object which will be set to NULL when the object is deallocated. * [ABI break] apt-pkg/acquire{-worker,-item,}.h: - subclass pkgAcquire::{Worker,Item,ItemDesc} from WeakPointable. --- apt-pkg/acquire-item.h | 3 ++- apt-pkg/acquire-worker.h | 3 ++- apt-pkg/acquire.h | 3 ++- apt-pkg/contrib/weakptr.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++ apt-pkg/makefile | 2 +- 5 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 apt-pkg/contrib/weakptr.h (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index bafa8263a..b338b2a41 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -27,6 +27,7 @@ #include #include #include +#include /** \addtogroup acquire * @{ @@ -46,7 +47,7 @@ * * \see pkgAcquire */ -class pkgAcquire::Item +class pkgAcquire::Item : public WeakPointable { protected: diff --git a/apt-pkg/acquire-worker.h b/apt-pkg/acquire-worker.h index 2942df69f..06283922e 100644 --- a/apt-pkg/acquire-worker.h +++ b/apt-pkg/acquire-worker.h @@ -20,6 +20,7 @@ #define PKGLIB_ACQUIRE_WORKER_H #include +#include /** \brief A fetch subprocess. @@ -41,7 +42,7 @@ * * \sa pkgAcqMethod, pkgAcquire::Item, pkgAcquire */ -class pkgAcquire::Worker +class pkgAcquire::Worker : public WeakPointable { friend class pkgAcquire; diff --git a/apt-pkg/acquire.h b/apt-pkg/acquire.h index 9e91a9f67..8e2c21151 100644 --- a/apt-pkg/acquire.h +++ b/apt-pkg/acquire.h @@ -67,6 +67,7 @@ #define PKGLIB_ACQUIRE_H #include +#include #include #include @@ -376,7 +377,7 @@ class pkgAcquire * * An item may have several assocated ItemDescs over its lifetime. */ -struct pkgAcquire::ItemDesc +struct pkgAcquire::ItemDesc : public WeakPointable { /** \brief The URI from which to download this item. */ string URI; diff --git a/apt-pkg/contrib/weakptr.h b/apt-pkg/contrib/weakptr.h new file mode 100644 index 000000000..5158e393c --- /dev/null +++ b/apt-pkg/contrib/weakptr.h @@ -0,0 +1,62 @@ +/* weakptr.h - An object which supports weak pointers. + * + * Copyright (C) 2010 Julian Andres Klode + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef WEAK_POINTER_H +#define WEAK_POINTER_H + +#include +/** + * Class for objects providing support for weak pointers. + * + * This class allows for the registration of certain pointers as weak, + * which will cause them to be set to NULL when the destructor of the + * object is called. + */ +class WeakPointable { +private: + std::set pointers; + +public: + + /** + * Add a new weak pointer. + */ + inline void AddWeakPointer(WeakPointable** weakptr) { + pointers.insert(weakptr); + } + + /** + * Remove the weak pointer from the list of weak pointers. + */ + inline void RemoveWeakPointer(WeakPointable **weakptr) { + pointers.erase(weakptr); + } + + /** + * Deconstruct the object, set all weak pointers to NULL. + */ + ~WeakPointable() { + std::set::iterator iter = pointers.begin(); + while (iter != pointers.end()) + **(iter++) = NULL; + } +}; + +#endif // WEAK_POINTER_H diff --git a/apt-pkg/makefile b/apt-pkg/makefile index bdd49c089..148ad581b 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -25,7 +25,7 @@ SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \ contrib/fileutl.cc HEADERS = mmap.h error.h configuration.h fileutl.h cmndline.h netrc.h\ md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha256.h hashes.h \ - macros.h + macros.h weakptr.h # Source code for the core main library SOURCE+= pkgcache.cc version.cc depcache.cc \ -- cgit v1.2.3 From 61d15f9104e1f574b0786700207675b892a0e241 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 4 May 2010 18:01:51 +0200 Subject: * apt-pkg/pkgcache.cc: - Merge fix from David to correct handling in single-arch environments. This makes apt-get showauto working. --- apt-pkg/pkgcache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 1bbd74bd9..351702240 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -218,7 +218,7 @@ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) { /* Returns 0 on error, pointer to the package otherwise */ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string const &Arch) { if (MultiArchCache() == false) { - if (Arch == "native" || Arch == "all" || + if (Arch == "native" || Arch == "all" || Arch == "any" || Arch == _config->Find("APT::Architecture")) return SingleArchFindPkg(Name); else -- cgit v1.2.3 From a101a93299d4a2795edb8495c117eb5095a26e2b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 4 May 2010 19:44:11 +0200 Subject: return in SingleArch a package also for "any" --- apt-pkg/pkgcache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index ba3c5cbf8..a59a06d65 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -221,7 +221,7 @@ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) { /* Returns 0 on error, pointer to the package otherwise */ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string const &Arch) { if (MultiArchCache() == false) { - if (Arch == "native" || Arch == "all" || + if (Arch == "native" || Arch == "all" || Arch == "any" || Arch == _config->Find("APT::Architecture")) return SingleArchFindPkg(Name); else -- cgit v1.2.3 From 63b528a4585d10926a9972663435bc0abc815345 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 5 May 2010 09:54:49 +0200 Subject: * apt-pkg/deb/debrecords.cc: - fix max tag buffer size (LP: #545336, closes: #578959) --- apt-pkg/deb/debrecords.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc index 8ed0bb7eb..57d30dc62 100644 --- a/apt-pkg/deb/debrecords.cc +++ b/apt-pkg/deb/debrecords.cc @@ -19,7 +19,8 @@ /* */ debRecordParser::debRecordParser(string FileName,pkgCache &Cache) : File(FileName,FileFd::ReadOnly), - Tags(&File,Cache.Head().MaxVerFileSize + 200) + Tags(&File, std::max(Cache.Head().MaxVerFileSize, + Cache.Head().MaxDescFileSize) + 200) { } /*}}}*/ -- cgit v1.2.3 From 448eaf8b5999b6866237a069d678337b647968c4 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 6 May 2010 11:55:54 +0200 Subject: convert FileExists to DirectoryExists to check if the path is really a directory (and to have a better method name in the error message if not) --- apt-pkg/init.cc | 4 ++-- apt-pkg/policy.cc | 4 ++-- apt-pkg/sourcelist.cc | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc index 6310aff11..60281deb3 100644 --- a/apt-pkg/init.cc +++ b/apt-pkg/init.cc @@ -94,10 +94,10 @@ bool pkgInitConfig(Configuration &Cnf) // Read the configuration parts dir string Parts = Cnf.FindDir("Dir::Etc::parts"); - if (FileExists(Parts) == true) + if (DirectoryExists(Parts) == true) Res &= ReadConfigDir(Cnf,Parts); else - _error->WarningE("FileExists",_("Unable to read %s"),Parts.c_str()); + _error->WarningE("DirectoryExists",_("Unable to read %s"),Parts.c_str()); // Read the main config file string FName = Cnf.FindFile("Dir::Etc::main"); diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index 479cf3935..922efb0dd 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -291,9 +291,9 @@ bool ReadPinDir(pkgPolicy &Plcy,string Dir) if (Dir.empty() == true) Dir = _config->FindDir("Dir::Etc::PreferencesParts"); - if (FileExists(Dir) == false) + if (DirectoryExists(Dir) == false) { - _error->WarningE("FileExists",_("Unable to read %s"),Dir.c_str()); + _error->WarningE("DirectoryExists",_("Unable to read %s"),Dir.c_str()); return true; } diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index e13472fa6..c3ec9865a 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -199,15 +199,15 @@ bool pkgSourceList::ReadMainList() if (FileExists(Main) == true) Res &= ReadAppend(Main); - else if (FileExists(Parts) == false) + else if (DirectoryExists(Parts) == false) // Only warn if there are no sources.list.d. - _error->WarningE("FileExists",_("Unable to read %s"),Main.c_str()); + _error->WarningE("DirectoryExists", _("Unable to read %s"), Parts.c_str()); - if (FileExists(Parts) == true) + if (DirectoryExists(Parts) == true) Res &= ReadSourceDir(Parts); else if (FileExists(Main) == false) // Only warn if there is no sources.list file. - _error->WarningE("FileExists",_("Unable to read %s"),Parts.c_str()); + _error->WarningE("FileExists", _("Unable to read %s"), Main.c_str()); return Res; } -- cgit v1.2.3 From 6248b28e9c9013e074120ae74b6a9fccee75c318 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 11 May 2010 13:59:02 +0200 Subject: * apt-pkg/depcache.cc: - be doublesure that the killer query is empty before starting reinstall --- apt-pkg/depcache.cc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 4d1a08eb6..411ae5f62 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -804,17 +804,18 @@ void pkgDepCache::Update(OpProgress *Prog) /* FIXME: recheck breaks proper progress reporting as we don't know how many packages we need to recheck. To lower the effect a bit we increase with a kill, but we should do something more clever… */ - for(std::set::const_iterator p = recheck.begin(); - p != recheck.end(); ++p) { - if (Prog != 0 && Done%20 == 0) - Prog->Progress(Done); - PkgIterator P = PkgIterator(*Cache, Cache->PkgP + *p); - if (RemovePseudoInstalledPkg(P, recheck) == true) { - ++killed; - ++Done; + while(recheck.empty() == false) + for (std::set::const_iterator p = recheck.begin(); + p != recheck.end(); ++p) { + if (Prog != 0 && Done%20 == 0) + Prog->Progress(Done); + PkgIterator P = PkgIterator(*Cache, Cache->PkgP + *p); + if (RemovePseudoInstalledPkg(P, recheck) == true) { + ++killed; + ++Done; + } + recheck.erase(p); } - recheck.erase(p); - } /* Okay, we have killed a great amount of pseudopackages - we have killed so many that we have now arch "all" packages -- cgit v1.2.3 From e3ac3b464d4b084c524076c7e2ab2c737ccdb99c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 13 May 2010 15:20:07 +0200 Subject: =?UTF-8?q?*=20contrib/mmap.cc:=20=20=20-=20clarify=20"MMap=20reac?= =?UTF-8?q?hed=20size=20limit"=20error=20message,=20thanks=20Ivan=20Mas?= =?UTF-8?q?=C3=A1r!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apt-pkg/contrib/mmap.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc index b3f29032c..d233e51bc 100644 --- a/apt-pkg/contrib/mmap.cc +++ b/apt-pkg/contrib/mmap.cc @@ -392,8 +392,8 @@ unsigned long DynamicMMap::WriteString(const char *String, 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); + return _error->Error(_("Unable to increase the size of the MMap as the " + "limit of %lu bytes is already reached."), Limit); unsigned long const newSize = WorkSpace + 1024*1024; -- cgit v1.2.3 From b3514c569564ebd7ee90c04f0af325510e129386 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 24 May 2010 13:40:50 +0200 Subject: * apt-pkg/deb/dpkgpm.cc: - add 'disappear' to the known processing states, thanks Jonathan Nieder --- apt-pkg/deb/dpkgpm.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index ca8faa8a5..a640a0c77 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -50,6 +50,7 @@ namespace std::make_pair("configure", N_("Configuring %s")), std::make_pair("remove", N_("Removing %s")), std::make_pair("purge", N_("Completely removing %s")), + std::make_pair("disappear", N_("Noting disappearance of %s")), std::make_pair("trigproc", N_("Running post-installation trigger %s")) }; @@ -419,7 +420,8 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) 'processing: install: pkg' 'processing: configure: pkg' 'processing: remove: pkg' - 'processing: purge: pkg' - but for apt is it a ignored "unknown" action + 'processing: purge: pkg' + 'processing: disappear: pkg' 'processing: trigproc: trigger' */ -- cgit v1.2.3 From 642ebc1a04c9c7915474c57f1143a9389ee6636a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 24 May 2010 20:10:11 +0200 Subject: - show at the end of the install process a list of disappeared packages * apt-pkg/packagemanager.h: - export info about disappeared packages with GetDisappearedPackages() --- apt-pkg/deb/dpkgpm.cc | 5 +++++ apt-pkg/packagemanager.h | 16 ++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index a640a0c77..8318fe37f 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -468,6 +468,9 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; + + if (strncmp(action, "disappear", strlen("disappear")) == 0) + disappearedPkgs.insert(string(pkg_or_trigger)); return; } @@ -913,6 +916,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) { if((*I).Pkg.end() == true) continue; + if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end()) + continue; Args[n++] = I->Pkg.Name(); Size += strlen(Args[n-1]); } diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index af1476b7a..efd2cfac6 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -28,6 +28,7 @@ #include #include #include +#include using std::string; @@ -47,7 +48,15 @@ class pkgPackageManager : protected pkgCache::Namespace pkgDepCache &Cache; pkgOrderList *List; bool Debug; - + + /** \brief saves packages dpkg let disappear + + This way APT can retreat from trying to configure these + packages later on and a frontend can choose to display a + notice to inform the user about these disappears. + */ + std::set disappearedPkgs; + bool DepAdd(pkgOrderList &Order,PkgIterator P,int Depth = 0); void ImmediateAdd(PkgIterator P, bool UseInstallVer, unsigned const int &Depth = 0); virtual OrderResult OrderInstall(); @@ -93,7 +102,10 @@ class pkgPackageManager : protected pkgCache::Namespace // stuff that needs to be done after the fork OrderResult DoInstallPostFork(int statusFd=-1); bool FixMissing(); - + + /** \brief returns all packages dpkg let disappear */ + inline std::set GetDisappearedPackages() { return disappearedPkgs; }; + pkgPackageManager(pkgDepCache *Cache); virtual ~pkgPackageManager(); }; -- cgit v1.2.3 From 6cb1060b58d8add6e04cc30241d3ef0f45ad226d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 27 May 2010 15:17:52 +0200 Subject: * apt-pkg/deb/dpkgpm.cc: - write Disappeared also to the history.log --- apt-pkg/deb/dpkgpm.cc | 33 ++++++++++++++++++++++++--------- apt-pkg/deb/dpkgpm.h | 2 +- 2 files changed, 25 insertions(+), 10 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 8318fe37f..35b10975f 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -568,15 +568,15 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd) } /*}}}*/ // DPkgPM::WriteHistoryTag /*{{{*/ -void pkgDPkgPM::WriteHistoryTag(string tag, string value) +void pkgDPkgPM::WriteHistoryTag(string const &tag, string value) { - if (value.size() > 0) - { - // poor mans rstrip(", ") - if (value[value.size()-2] == ',' && value[value.size()-1] == ' ') - value.erase(value.size() - 2, 2); - fprintf(history_out, "%s: %s\n", tag.c_str(), value.c_str()); - } + size_t const length = value.length(); + if (length == 0) + return; + // poor mans rstrip(", ") + if (value[length-2] == ',' && value[length-1] == ' ') + value.erase(length - 2, 2); + fprintf(history_out, "%s: %s\n", tag.c_str(), value.c_str()); } /*}}}*/ // DPkgPM::OpenLog /*{{{*/ bool pkgDPkgPM::OpenLog() @@ -663,7 +663,22 @@ bool pkgDPkgPM::CloseLog() if(history_out) { - if (dpkg_error.size() > 0) + if (disappearedPkgs.empty() == false) + { + string disappear; + for (std::set::const_iterator d = disappearedPkgs.begin(); + d != disappearedPkgs.end(); ++d) + { + pkgCache::PkgIterator P = Cache.FindPkg(*d); + disappear.append(*d); + if (P.end() == true) + disappear.append(", "); + else + disappear.append(" (").append(Cache[P].CurVersion).append("), "); + } + WriteHistoryTag("Disappeared", disappear); + } + if (dpkg_error.empty() == false) fprintf(history_out, "Error: %s\n", dpkg_error.c_str()); fprintf(history_out, "End-Date: %s\n", timestr); fclose(history_out); diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 330c788a2..b1459b1f6 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -68,7 +68,7 @@ class pkgDPkgPM : public pkgPackageManager // Helpers bool RunScriptsWithPkgs(const char *Cnf); bool SendV2Pkgs(FILE *F); - void WriteHistoryTag(string tag, string value); + void WriteHistoryTag(string const &tag, string value); // dpkg log bool OpenLog(); -- cgit v1.2.3 From eb6f9bac96a2b1938df598f4fd7c68d22c68a230 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 27 May 2010 18:13:52 +0200 Subject: forward manual-installed bit on package disappearance --- apt-pkg/deb/dpkgpm.cc | 47 ++++++++++++++++++++++++++++++++++++++++++++++- apt-pkg/deb/dpkgpm.h | 15 +++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 35b10975f..0ac6ac168 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -470,7 +470,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) std::clog << "send: '" << status.str() << "'" << endl; if (strncmp(action, "disappear", strlen("disappear")) == 0) - disappearedPkgs.insert(string(pkg_or_trigger)); + handleDisappearAction(pkg_or_trigger); return; } @@ -530,6 +530,51 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << " action: " << action << endl; } /*}}}*/ +// DPkgPM::handleDisappearAction /*{{{*/ +void pkgDPkgPM::handleDisappearAction(string const &pkgname) +{ + // record the package name for display and stuff later + disappearedPkgs.insert(pkgname); + + pkgCache::PkgIterator Pkg = Cache.FindPkg(pkgname); + if (unlikely(Pkg.end() == true)) + return; + // the disappeared package was auto-installed - nothing to do + if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) + return; + pkgCache::VerIterator PkgVer = Pkg.CurrentVer(); + if (unlikely(PkgVer.end() == true)) + return; + /* search in the list of dependencies for (Pre)Depends, + check if this dependency has a Replaces on our package + and if so transfer the manual installed flag to it */ + for (pkgCache::DepIterator Dep = PkgVer.DependsList(); Dep.end() != true; ++Dep) + { + if (Dep->Type != pkgCache::Dep::Depends && + Dep->Type != pkgCache::Dep::PreDepends) + continue; + pkgCache::PkgIterator Tar = Dep.TargetPkg(); + if (unlikely(Tar.end() == true)) + continue; + // the package is already marked as manual + if ((Cache[Tar].Flags & pkgCache::Flag::Auto) != pkgCache::Flag::Auto) + continue; + pkgCache::VerIterator TarVer = Tar.CurrentVer(); + for (pkgCache::DepIterator Rep = TarVer.DependsList(); Rep.end() != true; ++Rep) + { + if (Rep->Type != pkgCache::Dep::Replaces) + continue; + if (Pkg != Rep.TargetPkg()) + continue; + // okay, they are strongly connected - transfer manual-bit + if (Debug == true) + std::clog << "transfer manual-bit from disappeared »" << pkgname << "« to »" << Tar.FullName() << "«" << std::endl; + Cache[Tar].Flags &= ~Flag::Auto; + break; + } + } +} + /*}}}*/ // DPkgPM::DoDpkgStatusFd /*{{{*/ // --------------------------------------------------------------------- /* diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index b1459b1f6..9a4478f7c 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -32,6 +32,21 @@ class pkgDPkgPM : public pkgPackageManager FILE *history_out; string dpkg_error; + /** \brief record the disappear action and handle accordingly + + dpkg let packages disappear then they have no files any longer and + nothing depends on them. We need to collect this as dpkg as well as + APT doesn't know beforehand that the package will disappear, so the + only possible option is to tell the user afterwards about it. + To enhance the experience we also try to forward the auto-install + flag so the disappear-causer(s) are not autoremoved next time - + for the transfer to happen the disappeared version needs to depend + on the package the flag should be forwarded to and this package + needs to declare a Replaces on the disappeared package. + \param pkgname Name of the package that disappeared + */ + void handleDisappearAction(string const &pkgname); + protected: // progress reporting -- cgit v1.2.3 From d34690e1dc76c1e572d9f7ac172dd6b12059f774 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 28 May 2010 14:10:00 +0200 Subject: * apt-pkg/deb/debsystem.cc: - add better config item for extended_states file --- apt-pkg/deb/debsystem.cc | 2 +- apt-pkg/depcache.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debsystem.cc b/apt-pkg/deb/debsystem.cc index 59f826d96..31c26ab2f 100644 --- a/apt-pkg/deb/debsystem.cc +++ b/apt-pkg/deb/debsystem.cc @@ -158,7 +158,7 @@ bool debSystem::Initialize(Configuration &Cnf) /* These really should be jammed into a generic 'Local Database' engine which is yet to be determined. The functions in pkgcachegen should be the only users of these */ - Cnf.CndSet("Dir::State::userstatus","status.user"); // Defunct + Cnf.CndSet("Dir::State::extended_states", Cnf.FindDir("Dir::State").append("extended_states")); Cnf.CndSet("Dir::State::status","/var/lib/dpkg/status"); Cnf.CndSet("Dir::Bin::dpkg","/usr/bin/dpkg"); diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 411ae5f62..bdb89b5ce 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -165,7 +165,7 @@ bool pkgDepCache::Init(OpProgress *Prog) bool pkgDepCache::readStateFile(OpProgress *Prog) /*{{{*/ { FileFd state_file; - string const state = _config->FindDir("Dir::State") + "extended_states"; + string const state = _config->FindFile("Dir::State::extended_states"); if(FileExists(state)) { state_file.Open(state, FileFd::ReadOnly); int const file_size = state_file.Size(); @@ -222,7 +222,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/ std::clog << "pkgDepCache::writeStateFile()" << std::endl; FileFd StateFile; - string const state = _config->FindDir("Dir::State") + "extended_states"; + string const state = _config->FindFile("Dir::State::extended_states"); // if it does not exist, create a empty one if(!FileExists(state)) -- cgit v1.2.3 From 8378913047031bd1433a5b17e9affc1e055a150e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 28 May 2010 19:04:53 +0200 Subject: * apt-pkg/depcache.cc: - do the autoremove mark process also for required packages to handle these illegally depending on lower priority packages (Closes: #583517) --- apt-pkg/depcache.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index bdb89b5ce..c29114a65 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1638,8 +1638,11 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) { if(!(PkgState[p->ID].Flags & Flag::Auto) || (p->Flags & Flag::Essential) || - userFunc.InRootSet(p)) - + userFunc.InRootSet(p) || + // be nice even then a required package violates the policy (#583517) + // and do the full mark process also for required packages + (p.CurrentVer().end() != true && + p.CurrentVer()->Priority == pkgCache::State::Required)) { // the package is installed (and set to keep) if(PkgState[p->ID].Keep() && !p.CurrentVer().end()) -- cgit v1.2.3 From 392a882ad8a299d55889e9c0fa581a266d6dd2c9 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 28 May 2010 19:30:19 +0200 Subject: try harder to find the other pseudo versions for autoremove multiarch --- apt-pkg/depcache.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index c29114a65..afec7ba83 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1719,10 +1719,6 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg, // If the version belongs to a Multi-Arch all package // we will mark all others in this Group with this version also - // Beware: We compare versions here the lazy way: string comparision - // this is bad if multiple repositories provide different versions - // of the package with an identical version number - but even in this - // case the dependencies are likely the same. if (ver->MultiArch == pkgCache::Version::All && strcmp(ver.Arch(true), "all") == 0) { @@ -1734,7 +1730,8 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg, for (VerIterator V = P.VersionList(); V.end() != true; ++V) { - if (strcmp(VerStr, V.VerStr()) != 0) + if (ver->Hash != V->Hash || + strcmp(VerStr, V.VerStr()) != 0) continue; MarkPackage(P, V, follow_recommends, follow_suggests); break; -- cgit v1.2.3 From 3152f4aa4a97ad06ef1073aabe137f999f787ee1 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 28 May 2010 23:11:36 +0200 Subject: * apt-pkg/aptconfiguration.cc: - remove duplicate architectures in getArchitectures() --- apt-pkg/aptconfiguration.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 2acf8dd9f..0c050d9dc 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -327,11 +327,24 @@ std::vector const Configuration::getArchitectures(bool const &Cache if (likely(Cached == true) && archs.empty() == false) return archs; - string const arch = _config->Find("APT::Architecture"); archs = _config->FindVector("APT::Architectures"); + string const arch = _config->Find("APT::Architecture"); + if (unlikely(arch.empty() == true)) + return archs; + if (archs.empty() == true || std::find(archs.begin(), archs.end(), arch) == archs.end()) archs.push_back(arch); + + // erase duplicates and empty strings + for (std::vector::reverse_iterator a = archs.rbegin(); + a != archs.rend(); ++a) { + if (a->empty() == true || std::find(a + 1, archs.rend(), *a) != archs.rend()) + archs.erase(a.base()-1); + if (a == archs.rend()) + break; + } + return archs; } /*}}}*/ -- cgit v1.2.3 From e1430400bf012ab7e29b00c78796a14ce9f97107 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 29 May 2010 12:04:51 +0200 Subject: * apt-pkg/indexrecords.{cc,h}: - add a constant Exists check for MetaKeys * apt-pkg/acquire-item.cc: - do not try PDiff if it is not listed in the Meta file --- apt-pkg/acquire-item.cc | 13 ++++++++----- apt-pkg/indexrecords.cc | 5 +++++ apt-pkg/indexrecords.h | 2 ++ 3 files changed, 15 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index c035b9163..9e29f8189 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -1105,13 +1105,16 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/ return; } } - - // Queue Packages file (either diff or full packages files, depending - // on the users option) - if(_config->FindB("Acquire::PDiffs",true) == true) + + /* Queue Packages file (either diff or full packages files, depending + on the users option) - we also check if the PDiff Index file is listed + in the Meta-Index file. Ideal would be if pkgAcqDiffIndex would test this + instead, but passing the required info to it is to much hassle */ + if(_config->FindB("Acquire::PDiffs",true) == true && (verify == false || + MetaIndexParser->Exists(string((*Target)->MetaKey).append(".diff/Index")) == true)) new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description, (*Target)->ShortDesc, ExpectedIndexHash); - else + else new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description, (*Target)->ShortDesc, ExpectedIndexHash); } diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc index 1fc27b1a1..9a9600531 100644 --- a/apt-pkg/indexrecords.cc +++ b/apt-pkg/indexrecords.cc @@ -31,6 +31,11 @@ const indexRecords::checkSum *indexRecords::Lookup(const string MetaKey) return Entries[MetaKey]; } +bool indexRecords::Exists(string const &MetaKey) const +{ + return Entries.count(MetaKey) == 1; +} + bool indexRecords::Load(const string Filename) /*{{{*/ { FileFd Fd(Filename, FileFd::ReadOnly); diff --git a/apt-pkg/indexrecords.h b/apt-pkg/indexrecords.h index 468d2bd0f..2e3103b70 100644 --- a/apt-pkg/indexrecords.h +++ b/apt-pkg/indexrecords.h @@ -34,6 +34,8 @@ class indexRecords // Lookup function virtual const checkSum *Lookup(const string MetaKey); + /** \brief tests if a checksum for this file is available */ + bool Exists(string const &MetaKey) const; std::vector MetaKeys(); virtual bool Load(string Filename); -- cgit v1.2.3 From b3fdb998016beb8bf3d8bedb3ad6218f9050eece Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 29 May 2010 15:44:47 +0200 Subject: * apt-pkg/cacheiterator.h: - let pkgCache::Iterator inherent std::iterator --- apt-pkg/cacheiterators.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index e2ca74683..3d58f7ec0 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -29,10 +29,12 @@ /*}}}*/ #ifndef PKGLIB_CACHEITERATORS_H #define PKGLIB_CACHEITERATORS_H +#include // abstract Iterator template /*{{{*/ /* This template provides the very basic iterator methods we need to have for doing some walk-over-the-cache magic */ -template class pkgCache::Iterator { +template class pkgCache::Iterator : + public std::iterator { protected: Str *S; pkgCache *Owner; -- cgit v1.2.3 From 461e4a5e0d30549e5b9758ce816027d92747f00d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 29 May 2010 19:02:32 +0200 Subject: * apt-pkg/depcache.cc: - correct "Dangerous iterator usage." pointed out by cppcheck --- apt-pkg/depcache.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index afec7ba83..6c73b9cfd 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -806,7 +806,7 @@ void pkgDepCache::Update(OpProgress *Prog) a bit we increase with a kill, but we should do something more clever… */ while(recheck.empty() == false) for (std::set::const_iterator p = recheck.begin(); - p != recheck.end(); ++p) { + p != recheck.end();) { if (Prog != 0 && Done%20 == 0) Prog->Progress(Done); PkgIterator P = PkgIterator(*Cache, Cache->PkgP + *p); @@ -814,7 +814,7 @@ void pkgDepCache::Update(OpProgress *Prog) ++killed; ++Done; } - recheck.erase(p); + recheck.erase(p++); } /* Okay, we have killed a great amount of pseudopackages - @@ -849,7 +849,7 @@ void pkgDepCache::Update(OpProgress *Prog) unsigned long const G = *g; recheck.erase(g); if (unlikely(ReInstallPseudoForGroup(G, recheck) == false)) - _error->Warning(_("Internal error, group '%s' has no installable pseudo package"), GrpIterator(*Cache, Cache->GrpP + *g).Name()); + _error->Warning(_("Internal error, group '%s' has no installable pseudo package"), GrpIterator(*Cache, Cache->GrpP + G).Name()); } } -- cgit v1.2.3 From e1dbde8dd006ca0ed6b7a6c383af7bbc60014912 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 30 May 2010 07:57:32 +0200 Subject: * apt-pkg/packageset.h: - add a simple wrapper around std::set for packages with it --- apt-pkg/makefile | 3 ++- apt-pkg/packageset.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 apt-pkg/packageset.h (limited to 'apt-pkg') diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 148ad581b..d4537859d 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -42,7 +42,8 @@ HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ acquire.h acquire-worker.h acquire-item.h acquire-method.h \ clean.h srcrecords.h cachefile.h versionmatch.h policy.h \ pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \ - vendorlist.h cdrom.h indexcopy.h aptconfiguration.h + vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \ + packageset.h # Source code for the debian specific components # In theory the deb headers do not need to be exported.. diff --git a/apt-pkg/packageset.h b/apt-pkg/packageset.h new file mode 100644 index 000000000..d80536942 --- /dev/null +++ b/apt-pkg/packageset.h @@ -0,0 +1,53 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/** \class APT::PackageSet + + Simple wrapper around a std::set to provide a similar interface to + a set of packages as to the complete set of all packages in the + pkgCache. +*/ + /*}}}*/ +#ifndef APT_PACKAGESET_H +#define APT_PACKAGESET_H +// Include Files /*{{{*/ +#include +#include + /*}}}*/ +namespace APT { +class PackageSet : public std::set { /*{{{*/ +public: /*{{{*/ + /** \brief smell like a pkgCache::PkgIterator */ + class const_iterator : public std::set::const_iterator { + public: + const_iterator(std::set::const_iterator x) : + std::set::const_iterator(x) {} + + inline const char *Name() const {return (*this)->Name(); } + inline std::string FullName(bool const &Pretty) const { return (*this)->FullName(Pretty); } + inline std::string FullName() const { return (*this)->FullName(); } + inline const char *Section() const {return (*this)->Section(); } + inline bool Purge() const {return (*this)->Purge(); } + inline const char *Arch() const {return (*this)->Arch(); } + inline pkgCache::GrpIterator Group() const { return (*this)->Group(); } + inline pkgCache::VerIterator VersionList() const { return (*this)->VersionList(); } + inline pkgCache::VerIterator CurrentVer() const { return (*this)->CurrentVer(); } + inline pkgCache::DepIterator RevDependsList() const { return (*this)->RevDependsList(); } + inline pkgCache::PrvIterator ProvidesList() const { return (*this)->ProvidesList(); } + inline pkgCache::PkgIterator::OkState State() const { return (*this)->State(); } + inline const char *CandVersion() const { return (*this)->CandVersion(); } + inline const char *CurVersion() const { return (*this)->CurVersion(); } + inline pkgCache *Cache() {return (*this)->Cache();}; + + friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, (*i)); } + + inline pkgCache::PkgIterator const * operator->() const { + return &**this; + }; + }; + // 103. set::iterator is required to be modifiable, but this allows modification of keys + typedef typename APT::PackageSet::const_iterator iterator; + /*}}}*/ +}; + /*}}}*/ +} +#endif -- cgit v1.2.3 From ffee1c2bed4accfe25b2ac9e9f0ab9a0ebae9b5b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 30 May 2010 23:12:41 +0200 Subject: move regex magic from apt-get to new FromRegEx method --- apt-pkg/cacheiterators.h | 2 +- apt-pkg/makefile | 2 +- apt-pkg/packageset.cc | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ apt-pkg/packageset.h | 24 ++++++++++++++++++- 4 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 apt-pkg/packageset.cc (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 3d58f7ec0..ee852f594 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -66,7 +66,7 @@ template class pkgCache::Iterator : inline operator Str const *() const {return S == OwnerPointer() ? 0 : S;}; inline Str &operator *() {return *S;}; inline Str const &operator *() const {return *S;}; - inline pkgCache *Cache() {return Owner;}; + inline pkgCache *Cache() const {return Owner;}; // Mixed stuff inline void operator =(const Itr &B) {S = B.S; Owner = B.Owner;}; diff --git a/apt-pkg/makefile b/apt-pkg/makefile index d4537859d..968275c5c 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -35,7 +35,7 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \ srcrecords.cc cachefile.cc versionmatch.cc policy.cc \ pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \ indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \ - aptconfiguration.cc + aptconfiguration.cc packageset.cc HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ orderlist.h sourcelist.h packagemanager.h tagfile.h \ init.h pkgcache.h version.h progress.h pkgrecords.h \ diff --git a/apt-pkg/packageset.cc b/apt-pkg/packageset.cc new file mode 100644 index 000000000..f452bc052 --- /dev/null +++ b/apt-pkg/packageset.cc @@ -0,0 +1,62 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + Simple wrapper around a std::set to provide a similar interface to + a set of packages as to the complete set of all packages in the + pkgCache. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include + +#include + +#include + /*}}}*/ +namespace APT { +// FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ +PackageSet PackageSet::FromRegEx(pkgCache &Cache, const char * const pattern, std::ostream &out) { + PackageSet pkgset; + + const char * I; + for (I = pattern; *I != 0; I++) + if (*I == '.' || *I == '?' || *I == '+' || *I == '*' || + *I == '|' || *I == '[' || *I == '^' || *I == '$') + break; + if (*I == 0) + return pkgset; + + regex_t Pattern; + int Res; + if ((Res = regcomp(&Pattern, pattern , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) { + char Error[300]; + regerror(Res, &Pattern, Error, sizeof(Error)); + _error->Error(_("Regex compilation error - %s"), Error); + return pkgset; + } + + for (pkgCache::GrpIterator Grp = Cache.GrpBegin(); Grp.end() == false; ++Grp) + { + if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0) + continue; + pkgCache::PkgIterator Pkg = Grp.FindPkg("native"); + if (unlikely(Pkg.end() == true)) + // FIXME: Fallback to different architectures here? + continue; + + ioprintf(out, _("Note, selecting %s for regex '%s'\n"), + Pkg.Name(), pattern); + + pkgset.insert(Pkg); + } + + regfree(&Pattern); + + return pkgset; +} + /*}}}*/ +} diff --git a/apt-pkg/packageset.h b/apt-pkg/packageset.h index d80536942..cd1430a2a 100644 --- a/apt-pkg/packageset.h +++ b/apt-pkg/packageset.h @@ -10,7 +10,11 @@ #ifndef APT_PACKAGESET_H #define APT_PACKAGESET_H // Include Files /*{{{*/ +#include +#include +#include #include + #include /*}}}*/ namespace APT { @@ -22,6 +26,8 @@ public: /*{{{*/ const_iterator(std::set::const_iterator x) : std::set::const_iterator(x) {} + operator pkgCache::PkgIterator(void) { return **this; } + inline const char *Name() const {return (*this)->Name(); } inline std::string FullName(bool const &Pretty) const { return (*this)->FullName(Pretty); } inline std::string FullName() const { return (*this)->FullName(); } @@ -36,7 +42,8 @@ public: /*{{{*/ inline pkgCache::PkgIterator::OkState State() const { return (*this)->State(); } inline const char *CandVersion() const { return (*this)->CandVersion(); } inline const char *CurVersion() const { return (*this)->CurVersion(); } - inline pkgCache *Cache() {return (*this)->Cache();}; + inline pkgCache *Cache() const { return (*this)->Cache(); }; + inline unsigned long Index() const {return (*this)->Index();}; friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, (*i)); } @@ -46,6 +53,21 @@ public: /*{{{*/ }; // 103. set::iterator is required to be modifiable, but this allows modification of keys typedef typename APT::PackageSet::const_iterator iterator; + + /** \brief returns all packages in the cache whose name matchs a given pattern + + A simple helper responsible for executing a regular expression on all + package names in the cache. Optional it prints a a notice about the + packages chosen cause of the given package. + \param Cache the packages are in + \param pattern regular expression for package names + \param out stream to print the notice to */ + static APT::PackageSet FromRegEx(pkgCache &Cache, const char *pattern, std::ostream &out); + static APT::PackageSet FromRegEx(pkgCache &Cache, const char *pattern) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::PackageSet::FromRegEx(Cache, pattern, out); + } + /*}}}*/ }; /*}}}*/ -- cgit v1.2.3 From 78c325968642255fd2325003f19729b617477666 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 31 May 2010 00:28:14 +0200 Subject: move cmdline parsing from apt-cache to new FromCommandLine method --- apt-pkg/packageset.cc | 42 ++++++++++++++++++++++++++++++++++++---- apt-pkg/packageset.h | 53 ++++++++++++++++++++++++++++++++++----------------- 2 files changed, 73 insertions(+), 22 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/packageset.cc b/apt-pkg/packageset.cc index f452bc052..baa1c211b 100644 --- a/apt-pkg/packageset.cc +++ b/apt-pkg/packageset.cc @@ -9,12 +9,15 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#include #include #include #include #include +#include + #include /*}}}*/ namespace APT { @@ -44,18 +47,49 @@ PackageSet PackageSet::FromRegEx(pkgCache &Cache, const char * const pattern, st if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0) continue; pkgCache::PkgIterator Pkg = Grp.FindPkg("native"); - if (unlikely(Pkg.end() == true)) - // FIXME: Fallback to different architectures here? - continue; + if (Pkg.end() == true) { + std::vector archs = APT::Configuration::getArchitectures(); + for (std::vector::const_iterator a = archs.begin(); + a != archs.end() || Pkg.end() != true; ++a) { + Pkg = Grp.FindPkg(*a); + } + if (Pkg.end() == true) + continue; + } ioprintf(out, _("Note, selecting %s for regex '%s'\n"), - Pkg.Name(), pattern); + Pkg.FullName(true).c_str(), pattern); pkgset.insert(Pkg); } regfree(&Pattern); + return pkgset; +} + /*}}}*/ +// FromCommandLine - Return all packages specified on commandline /*{{{*/ +PackageSet PackageSet::FromCommandLine(pkgCache &Cache, const char **cmdline, std::ostream &out) { + PackageSet pkgset; + for (const char **I = cmdline + 1; *I != 0; I++) { + pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); + if (Pkg.end() == true) { + std::vector archs = APT::Configuration::getArchitectures(); + for (std::vector::const_iterator a = archs.begin(); + a != archs.end() || Pkg.end() != true; ++a) { + Pkg = Cache.FindPkg(*I, *a); + } + if (Pkg.end() == true) { + PackageSet regex = FromRegEx(Cache, *I, out); + if (regex.empty() == true) + _error->Warning(_("Unable to locate package %s"),*I); + else + pkgset.insert(regex.begin(), regex.end()); + continue; + } + } + pkgset.insert(Pkg); + } return pkgset; } /*}}}*/ diff --git a/apt-pkg/packageset.h b/apt-pkg/packageset.h index cd1430a2a..0bd60c56b 100644 --- a/apt-pkg/packageset.h +++ b/apt-pkg/packageset.h @@ -28,27 +28,29 @@ public: /*{{{*/ operator pkgCache::PkgIterator(void) { return **this; } - inline const char *Name() const {return (*this)->Name(); } - inline std::string FullName(bool const &Pretty) const { return (*this)->FullName(Pretty); } - inline std::string FullName() const { return (*this)->FullName(); } - inline const char *Section() const {return (*this)->Section(); } - inline bool Purge() const {return (*this)->Purge(); } - inline const char *Arch() const {return (*this)->Arch(); } - inline pkgCache::GrpIterator Group() const { return (*this)->Group(); } - inline pkgCache::VerIterator VersionList() const { return (*this)->VersionList(); } - inline pkgCache::VerIterator CurrentVer() const { return (*this)->CurrentVer(); } - inline pkgCache::DepIterator RevDependsList() const { return (*this)->RevDependsList(); } - inline pkgCache::PrvIterator ProvidesList() const { return (*this)->ProvidesList(); } - inline pkgCache::PkgIterator::OkState State() const { return (*this)->State(); } - inline const char *CandVersion() const { return (*this)->CandVersion(); } - inline const char *CurVersion() const { return (*this)->CurVersion(); } - inline pkgCache *Cache() const { return (*this)->Cache(); }; - inline unsigned long Index() const {return (*this)->Index();}; + inline const char *Name() const {return (**this).Name(); } + inline std::string FullName(bool const &Pretty) const { return (**this).FullName(Pretty); } + inline std::string FullName() const { return (**this).FullName(); } + inline const char *Section() const {return (**this).Section(); } + inline bool Purge() const {return (**this).Purge(); } + inline const char *Arch() const {return (**this).Arch(); } + inline pkgCache::GrpIterator Group() const { return (**this).Group(); } + inline pkgCache::VerIterator VersionList() const { return (**this).VersionList(); } + inline pkgCache::VerIterator CurrentVer() const { return (**this).CurrentVer(); } + inline pkgCache::DepIterator RevDependsList() const { return (**this).RevDependsList(); } + inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); } + inline pkgCache::PkgIterator::OkState State() const { return (**this).State(); } + inline const char *CandVersion() const { return (**this).CandVersion(); } + inline const char *CurVersion() const { return (**this).CurVersion(); } + inline pkgCache *Cache() const { return (**this).Cache(); }; + inline unsigned long Index() const {return (**this).Index();}; + // we have only valid iterators here + inline bool end() const { return false; }; friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, (*i)); } - inline pkgCache::PkgIterator const * operator->() const { - return &**this; + inline pkgCache::Package const * operator->() const { + return &***this; }; }; // 103. set::iterator is required to be modifiable, but this allows modification of keys @@ -68,6 +70,21 @@ public: /*{{{*/ return APT::PackageSet::FromRegEx(Cache, pattern, out); } + /** \brief returns all packages specified on the commandline + + Get all package names from the commandline and executes regex's if needed. + No special package command is supported, just plain names. + \param Cache the packages are in + \param cmdline Command line the package names should be extracted from + \param out stream to print various notices to */ + static APT::PackageSet FromCommandLine(pkgCache &Cache, const char **cmdline, std::ostream &out); + static APT::PackageSet FromCommandLine(pkgCache &Cache, const char **cmdline) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::PackageSet::FromCommandLine(Cache, cmdline, out); + } + + + /*}}}*/ }; /*}}}*/ -- cgit v1.2.3 From 6e235c6640cdc6cb9a8c3eaa1e65a6141f463676 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 31 May 2010 14:16:44 +0200 Subject: improve the handling of regex together with the architecture modifier --- apt-pkg/packageset.cc | 35 +++++++++++++++++++++-------------- apt-pkg/packageset.h | 4 ++-- 2 files changed, 23 insertions(+), 16 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/packageset.cc b/apt-pkg/packageset.cc index baa1c211b..f296b7c45 100644 --- a/apt-pkg/packageset.cc +++ b/apt-pkg/packageset.cc @@ -22,20 +22,26 @@ /*}}}*/ namespace APT { // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ -PackageSet PackageSet::FromRegEx(pkgCache &Cache, const char * const pattern, std::ostream &out) { +PackageSet PackageSet::FromRegEx(pkgCache &Cache, std::string pattern, std::ostream &out) { PackageSet pkgset; + std::string arch = "native"; + static const char * const isregex = ".?+*|[^$"; - const char * I; - for (I = pattern; *I != 0; I++) - if (*I == '.' || *I == '?' || *I == '+' || *I == '*' || - *I == '|' || *I == '[' || *I == '^' || *I == '$') - break; - if (*I == 0) + if (pattern.find_first_of(isregex) == std::string::npos) return pkgset; + size_t archfound = pattern.find_last_of(':'); + if (archfound != std::string::npos) { + arch = pattern.substr(archfound+1); + if (arch.find_first_of(isregex) == std::string::npos) + pattern.erase(archfound); + else + arch = "native"; + } + regex_t Pattern; int Res; - if ((Res = regcomp(&Pattern, pattern , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) { + if ((Res = regcomp(&Pattern, pattern.c_str() , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) { char Error[300]; regerror(Res, &Pattern, Error, sizeof(Error)); _error->Error(_("Regex compilation error - %s"), Error); @@ -46,19 +52,20 @@ PackageSet PackageSet::FromRegEx(pkgCache &Cache, const char * const pattern, st { if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0) continue; - pkgCache::PkgIterator Pkg = Grp.FindPkg("native"); + pkgCache::PkgIterator Pkg = Grp.FindPkg(arch); if (Pkg.end() == true) { - std::vector archs = APT::Configuration::getArchitectures(); - for (std::vector::const_iterator a = archs.begin(); - a != archs.end() || Pkg.end() != true; ++a) { - Pkg = Grp.FindPkg(*a); + if (archfound == std::string::npos) { + std::vector archs = APT::Configuration::getArchitectures(); + for (std::vector::const_iterator a = archs.begin(); + a != archs.end() && Pkg.end() != true; ++a) + Pkg = Grp.FindPkg(*a); } if (Pkg.end() == true) continue; } ioprintf(out, _("Note, selecting %s for regex '%s'\n"), - Pkg.FullName(true).c_str(), pattern); + Pkg.FullName(true).c_str(), pattern.c_str()); pkgset.insert(Pkg); } diff --git a/apt-pkg/packageset.h b/apt-pkg/packageset.h index 0bd60c56b..9f80d60ed 100644 --- a/apt-pkg/packageset.h +++ b/apt-pkg/packageset.h @@ -64,8 +64,8 @@ public: /*{{{*/ \param Cache the packages are in \param pattern regular expression for package names \param out stream to print the notice to */ - static APT::PackageSet FromRegEx(pkgCache &Cache, const char *pattern, std::ostream &out); - static APT::PackageSet FromRegEx(pkgCache &Cache, const char *pattern) { + static APT::PackageSet FromRegEx(pkgCache &Cache, std::string pattern, std::ostream &out); + static APT::PackageSet FromRegEx(pkgCache &Cache, std::string const &pattern) { std::ostream out (std::ofstream("/dev/null").rdbuf()); return APT::PackageSet::FromRegEx(Cache, pattern, out); } -- cgit v1.2.3 From 093e9f5d30f37164dd28d639fedfb059e105e43e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 31 May 2010 17:22:04 +0200 Subject: * apt-pkg/contrib/cmdline.cc: - fix segfault in SaveInConfig caused by writing over char[] sizes --- apt-pkg/contrib/cmndline.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/cmndline.cc b/apt-pkg/contrib/cmndline.cc index 0b16bf51a..5a9944096 100644 --- a/apt-pkg/contrib/cmndline.cc +++ b/apt-pkg/contrib/cmndline.cc @@ -360,11 +360,11 @@ bool CommandLine::DispatchArg(Dispatch *Map,bool NoMatch) than nothing after all. */ void CommandLine::SaveInConfig(unsigned int const &argc, char const * const * const argv) { - char cmdline[300]; + char cmdline[100 + argc * 50]; unsigned int length = 0; bool lastWasOption = false; bool closeQuote = false; - for (unsigned int i = 0; i < argc; ++i, ++length) + for (unsigned int i = 0; i < argc && length < sizeof(cmdline); ++i, ++length) { for (unsigned int j = 0; argv[i][j] != '\0' && length < sizeof(cmdline)-1; ++j, ++length) { -- cgit v1.2.3 From bd2fb30a8647293f80b085d0308e66bb9219e662 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 31 May 2010 20:00:16 +0200 Subject: * apt-pkg/pkgcache.cc: - get the best matching arch package from a group with FindPreferredPkg --- apt-pkg/cacheiterators.h | 5 +++++ apt-pkg/pkgcache.cc | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index ee852f594..e5b23a818 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -104,6 +104,11 @@ class pkgCache::GrpIterator: public Iterator { inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;}; inline PkgIterator PackageList() const; PkgIterator FindPkg(string Arch = "any"); + /** \brief find the package with the "best" architecture + + The best architecture is either the "native" or the first + in the list of Architectures which is not an end-Pointer */ + PkgIterator FindPreferredPkg(); PkgIterator NextPkg(PkgIterator const &Pkg); // Constructors diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index a59a06d65..adaae9c89 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -340,6 +340,25 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) { break; } + return PkgIterator(*Owner, 0); +} + /*}}}*/ +// GrpIterator::FindPreferredPkg - Locate the "best" package /*{{{*/ +// --------------------------------------------------------------------- +/* Returns an End-Pointer on error, pointer to the package otherwise */ +pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg() { + pkgCache::PkgIterator Pkg = FindPkg("native"); + if (Pkg.end() == false) + return Pkg; + + std::vector const archs = APT::Configuration::getArchitectures(); + for (std::vector::const_iterator a = archs.begin(); + a != archs.end(); ++a) { + Pkg = FindPkg(*a); + if (Pkg.end() == false) + return Pkg; + } + return PkgIterator(*Owner, 0); } /*}}}*/ -- cgit v1.2.3 From 7959c5eda83bd6d69876942566cf47d74fc76530 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 31 May 2010 21:00:09 +0200 Subject: rename packageset into cacheset while it is not too late --- apt-pkg/cacheset.cc | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++ apt-pkg/cacheset.h | 96 ++++++++++++++++++++++++++++++++++++++++++++++ apt-pkg/makefile | 4 +- apt-pkg/packageset.cc | 103 -------------------------------------------------- apt-pkg/packageset.h | 92 -------------------------------------------- 5 files changed, 201 insertions(+), 197 deletions(-) create mode 100644 apt-pkg/cacheset.cc create mode 100644 apt-pkg/cacheset.h delete mode 100644 apt-pkg/packageset.cc delete mode 100644 apt-pkg/packageset.h (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc new file mode 100644 index 000000000..b49b36539 --- /dev/null +++ b/apt-pkg/cacheset.cc @@ -0,0 +1,103 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + Simple wrapper around a std::set to provide a similar interface to + a set of cache structures as to the complete set of all structures + in the pkgCache. Currently only Package is supported. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include + +#include + +#include + +#include + /*}}}*/ +namespace APT { +// FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ +PackageSet PackageSet::FromRegEx(pkgCache &Cache, std::string pattern, std::ostream &out) { + PackageSet pkgset; + std::string arch = "native"; + static const char * const isregex = ".?+*|[^$"; + + if (pattern.find_first_of(isregex) == std::string::npos) + return pkgset; + + size_t archfound = pattern.find_last_of(':'); + if (archfound != std::string::npos) { + arch = pattern.substr(archfound+1); + if (arch.find_first_of(isregex) == std::string::npos) + pattern.erase(archfound); + else + arch = "native"; + } + + regex_t Pattern; + int Res; + if ((Res = regcomp(&Pattern, pattern.c_str() , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) { + char Error[300]; + regerror(Res, &Pattern, Error, sizeof(Error)); + _error->Error(_("Regex compilation error - %s"), Error); + return pkgset; + } + + for (pkgCache::GrpIterator Grp = Cache.GrpBegin(); Grp.end() == false; ++Grp) + { + if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0) + continue; + pkgCache::PkgIterator Pkg = Grp.FindPkg(arch); + if (Pkg.end() == true) { + if (archfound == std::string::npos) { + std::vector archs = APT::Configuration::getArchitectures(); + for (std::vector::const_iterator a = archs.begin(); + a != archs.end() && Pkg.end() != true; ++a) + Pkg = Grp.FindPkg(*a); + } + if (Pkg.end() == true) + continue; + } + + ioprintf(out, _("Note, selecting %s for regex '%s'\n"), + Pkg.FullName(true).c_str(), pattern.c_str()); + + pkgset.insert(Pkg); + } + + regfree(&Pattern); + + return pkgset; +} + /*}}}*/ +// FromCommandLine - Return all packages specified on commandline /*{{{*/ +PackageSet PackageSet::FromCommandLine(pkgCache &Cache, const char **cmdline, std::ostream &out) { + PackageSet pkgset; + for (const char **I = cmdline + 1; *I != 0; I++) { + pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); + if (Pkg.end() == true) { + std::vector archs = APT::Configuration::getArchitectures(); + for (std::vector::const_iterator a = archs.begin(); + a != archs.end() || Pkg.end() != true; ++a) { + Pkg = Cache.FindPkg(*I, *a); + } + if (Pkg.end() == true) { + PackageSet regex = FromRegEx(Cache, *I, out); + if (regex.empty() == true) + _error->Warning(_("Unable to locate package %s"),*I); + else + pkgset.insert(regex.begin(), regex.end()); + continue; + } + } + pkgset.insert(Pkg); + } + return pkgset; +} + /*}}}*/ +} diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h new file mode 100644 index 000000000..7c05face6 --- /dev/null +++ b/apt-pkg/cacheset.h @@ -0,0 +1,96 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/** \file cacheset.h + Wrappers around std::set to have set::iterators which behave + similar to the Iterators of the cache structures. + + Provides also a few helper methods which work with these sets */ + /*}}}*/ +#ifndef APT_CACHESET_H +#define APT_CACHESET_H +// Include Files /*{{{*/ +#include +#include +#include +#include + +#include + /*}}}*/ +namespace APT { +/** \class APT::PackageSet + + Simple wrapper around a std::set to provide a similar interface to + a set of packages as to the complete set of all packages in the + pkgCache. */ +class PackageSet : public std::set { /*{{{*/ +public: /*{{{*/ + /** \brief smell like a pkgCache::PkgIterator */ + class const_iterator : public std::set::const_iterator { + public: + const_iterator(std::set::const_iterator x) : + std::set::const_iterator(x) {} + + operator pkgCache::PkgIterator(void) { return **this; } + + inline const char *Name() const {return (**this).Name(); } + inline std::string FullName(bool const &Pretty) const { return (**this).FullName(Pretty); } + inline std::string FullName() const { return (**this).FullName(); } + inline const char *Section() const {return (**this).Section(); } + inline bool Purge() const {return (**this).Purge(); } + inline const char *Arch() const {return (**this).Arch(); } + inline pkgCache::GrpIterator Group() const { return (**this).Group(); } + inline pkgCache::VerIterator VersionList() const { return (**this).VersionList(); } + inline pkgCache::VerIterator CurrentVer() const { return (**this).CurrentVer(); } + inline pkgCache::DepIterator RevDependsList() const { return (**this).RevDependsList(); } + inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); } + inline pkgCache::PkgIterator::OkState State() const { return (**this).State(); } + inline const char *CandVersion() const { return (**this).CandVersion(); } + inline const char *CurVersion() const { return (**this).CurVersion(); } + inline pkgCache *Cache() const { return (**this).Cache(); }; + inline unsigned long Index() const {return (**this).Index();}; + // we have only valid iterators here + inline bool end() const { return false; }; + + friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, (*i)); } + + inline pkgCache::Package const * operator->() const { + return &***this; + }; + }; + // 103. set::iterator is required to be modifiable, but this allows modification of keys + typedef typename APT::PackageSet::const_iterator iterator; + + /** \brief returns all packages in the cache whose name matchs a given pattern + + A simple helper responsible for executing a regular expression on all + package names in the cache. Optional it prints a a notice about the + packages chosen cause of the given package. + \param Cache the packages are in + \param pattern regular expression for package names + \param out stream to print the notice to */ + static APT::PackageSet FromRegEx(pkgCache &Cache, std::string pattern, std::ostream &out); + static APT::PackageSet FromRegEx(pkgCache &Cache, std::string const &pattern) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::PackageSet::FromRegEx(Cache, pattern, out); + } + + /** \brief returns all packages specified on the commandline + + Get all package names from the commandline and executes regex's if needed. + No special package command is supported, just plain names. + \param Cache the packages are in + \param cmdline Command line the package names should be extracted from + \param out stream to print various notices to */ + static APT::PackageSet FromCommandLine(pkgCache &Cache, const char **cmdline, std::ostream &out); + static APT::PackageSet FromCommandLine(pkgCache &Cache, const char **cmdline) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::PackageSet::FromCommandLine(Cache, cmdline, out); + } + + + + /*}}}*/ +}; + /*}}}*/ +} +#endif diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 968275c5c..1a7078693 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -35,7 +35,7 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \ srcrecords.cc cachefile.cc versionmatch.cc policy.cc \ pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \ indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \ - aptconfiguration.cc packageset.cc + aptconfiguration.cc cacheset.cc HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ orderlist.h sourcelist.h packagemanager.h tagfile.h \ init.h pkgcache.h version.h progress.h pkgrecords.h \ @@ -43,7 +43,7 @@ HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ clean.h srcrecords.h cachefile.h versionmatch.h policy.h \ pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \ vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \ - packageset.h + cacheset.h # Source code for the debian specific components # In theory the deb headers do not need to be exported.. diff --git a/apt-pkg/packageset.cc b/apt-pkg/packageset.cc deleted file mode 100644 index f296b7c45..000000000 --- a/apt-pkg/packageset.cc +++ /dev/null @@ -1,103 +0,0 @@ -// -*- mode: cpp; mode: fold -*- -// Description /*{{{*/ -/* ###################################################################### - - Simple wrapper around a std::set to provide a similar interface to - a set of packages as to the complete set of all packages in the - pkgCache. - - ##################################################################### */ - /*}}}*/ -// Include Files /*{{{*/ -#include -#include -#include -#include - -#include - -#include - -#include - /*}}}*/ -namespace APT { -// FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ -PackageSet PackageSet::FromRegEx(pkgCache &Cache, std::string pattern, std::ostream &out) { - PackageSet pkgset; - std::string arch = "native"; - static const char * const isregex = ".?+*|[^$"; - - if (pattern.find_first_of(isregex) == std::string::npos) - return pkgset; - - size_t archfound = pattern.find_last_of(':'); - if (archfound != std::string::npos) { - arch = pattern.substr(archfound+1); - if (arch.find_first_of(isregex) == std::string::npos) - pattern.erase(archfound); - else - arch = "native"; - } - - regex_t Pattern; - int Res; - if ((Res = regcomp(&Pattern, pattern.c_str() , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) { - char Error[300]; - regerror(Res, &Pattern, Error, sizeof(Error)); - _error->Error(_("Regex compilation error - %s"), Error); - return pkgset; - } - - for (pkgCache::GrpIterator Grp = Cache.GrpBegin(); Grp.end() == false; ++Grp) - { - if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0) - continue; - pkgCache::PkgIterator Pkg = Grp.FindPkg(arch); - if (Pkg.end() == true) { - if (archfound == std::string::npos) { - std::vector archs = APT::Configuration::getArchitectures(); - for (std::vector::const_iterator a = archs.begin(); - a != archs.end() && Pkg.end() != true; ++a) - Pkg = Grp.FindPkg(*a); - } - if (Pkg.end() == true) - continue; - } - - ioprintf(out, _("Note, selecting %s for regex '%s'\n"), - Pkg.FullName(true).c_str(), pattern.c_str()); - - pkgset.insert(Pkg); - } - - regfree(&Pattern); - - return pkgset; -} - /*}}}*/ -// FromCommandLine - Return all packages specified on commandline /*{{{*/ -PackageSet PackageSet::FromCommandLine(pkgCache &Cache, const char **cmdline, std::ostream &out) { - PackageSet pkgset; - for (const char **I = cmdline + 1; *I != 0; I++) { - pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); - if (Pkg.end() == true) { - std::vector archs = APT::Configuration::getArchitectures(); - for (std::vector::const_iterator a = archs.begin(); - a != archs.end() || Pkg.end() != true; ++a) { - Pkg = Cache.FindPkg(*I, *a); - } - if (Pkg.end() == true) { - PackageSet regex = FromRegEx(Cache, *I, out); - if (regex.empty() == true) - _error->Warning(_("Unable to locate package %s"),*I); - else - pkgset.insert(regex.begin(), regex.end()); - continue; - } - } - pkgset.insert(Pkg); - } - return pkgset; -} - /*}}}*/ -} diff --git a/apt-pkg/packageset.h b/apt-pkg/packageset.h deleted file mode 100644 index 9f80d60ed..000000000 --- a/apt-pkg/packageset.h +++ /dev/null @@ -1,92 +0,0 @@ -// -*- mode: cpp; mode: fold -*- -// Description /*{{{*/ -/** \class APT::PackageSet - - Simple wrapper around a std::set to provide a similar interface to - a set of packages as to the complete set of all packages in the - pkgCache. -*/ - /*}}}*/ -#ifndef APT_PACKAGESET_H -#define APT_PACKAGESET_H -// Include Files /*{{{*/ -#include -#include -#include -#include - -#include - /*}}}*/ -namespace APT { -class PackageSet : public std::set { /*{{{*/ -public: /*{{{*/ - /** \brief smell like a pkgCache::PkgIterator */ - class const_iterator : public std::set::const_iterator { - public: - const_iterator(std::set::const_iterator x) : - std::set::const_iterator(x) {} - - operator pkgCache::PkgIterator(void) { return **this; } - - inline const char *Name() const {return (**this).Name(); } - inline std::string FullName(bool const &Pretty) const { return (**this).FullName(Pretty); } - inline std::string FullName() const { return (**this).FullName(); } - inline const char *Section() const {return (**this).Section(); } - inline bool Purge() const {return (**this).Purge(); } - inline const char *Arch() const {return (**this).Arch(); } - inline pkgCache::GrpIterator Group() const { return (**this).Group(); } - inline pkgCache::VerIterator VersionList() const { return (**this).VersionList(); } - inline pkgCache::VerIterator CurrentVer() const { return (**this).CurrentVer(); } - inline pkgCache::DepIterator RevDependsList() const { return (**this).RevDependsList(); } - inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); } - inline pkgCache::PkgIterator::OkState State() const { return (**this).State(); } - inline const char *CandVersion() const { return (**this).CandVersion(); } - inline const char *CurVersion() const { return (**this).CurVersion(); } - inline pkgCache *Cache() const { return (**this).Cache(); }; - inline unsigned long Index() const {return (**this).Index();}; - // we have only valid iterators here - inline bool end() const { return false; }; - - friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, (*i)); } - - inline pkgCache::Package const * operator->() const { - return &***this; - }; - }; - // 103. set::iterator is required to be modifiable, but this allows modification of keys - typedef typename APT::PackageSet::const_iterator iterator; - - /** \brief returns all packages in the cache whose name matchs a given pattern - - A simple helper responsible for executing a regular expression on all - package names in the cache. Optional it prints a a notice about the - packages chosen cause of the given package. - \param Cache the packages are in - \param pattern regular expression for package names - \param out stream to print the notice to */ - static APT::PackageSet FromRegEx(pkgCache &Cache, std::string pattern, std::ostream &out); - static APT::PackageSet FromRegEx(pkgCache &Cache, std::string const &pattern) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::FromRegEx(Cache, pattern, out); - } - - /** \brief returns all packages specified on the commandline - - Get all package names from the commandline and executes regex's if needed. - No special package command is supported, just plain names. - \param Cache the packages are in - \param cmdline Command line the package names should be extracted from - \param out stream to print various notices to */ - static APT::PackageSet FromCommandLine(pkgCache &Cache, const char **cmdline, std::ostream &out); - static APT::PackageSet FromCommandLine(pkgCache &Cache, const char **cmdline) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::FromCommandLine(Cache, cmdline, out); - } - - - - /*}}}*/ -}; - /*}}}*/ -} -#endif -- cgit v1.2.3 From d4489d4983d5b9840bb2882a088dd1f363a280b9 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 31 May 2010 22:36:41 +0200 Subject: * apt-pkg/cacheset.{cc,h}: - add simple wrapper around std::set for cache structures --- apt-pkg/cacheiterators.h | 4 ++-- apt-pkg/cacheset.h | 49 +++++++++++++++++++++++++++++++++++++++++++++--- apt-pkg/pkgcache.cc | 2 +- 3 files changed, 49 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index e5b23a818..f0b40dbb5 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -205,8 +205,8 @@ class pkgCache::VerIterator : public Iterator { inline PrvIterator ProvidesList() const; inline VerFileIterator FileList() const; bool Downloadable() const; - inline const char *PriorityType() {return Owner->Priority(S->Priority);}; - string RelStr(); + inline const char *PriorityType() const {return Owner->Priority(S->Priority);}; + string RelStr() const; bool Automatic() const; bool Pseudo() const; diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index 7c05face6..f0131bfed 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -17,12 +17,12 @@ #include /*}}}*/ namespace APT { +class PackageSet : public std::set { /*{{{*/ /** \class APT::PackageSet Simple wrapper around a std::set to provide a similar interface to a set of packages as to the complete set of all packages in the pkgCache. */ -class PackageSet : public std::set { /*{{{*/ public: /*{{{*/ /** \brief smell like a pkgCache::PkgIterator */ class const_iterator : public std::set::const_iterator { @@ -86,11 +86,54 @@ public: /*{{{*/ std::ostream out (std::ofstream("/dev/null").rdbuf()); return APT::PackageSet::FromCommandLine(Cache, cmdline, out); } + /*}}}*/ +}; /*}}}*/ +class VersionSet : public std::set { /*{{{*/ +/** \class APT::VersionSet + Simple wrapper around a std::set to provide a similar interface to + a set of versions as to the complete set of all versions in the + pkgCache. */ +public: /*{{{*/ + /** \brief smell like a pkgCache::VerIterator */ + class const_iterator : public std::set::const_iterator { + public: + const_iterator(std::set::const_iterator x) : + std::set::const_iterator(x) {} + operator pkgCache::VerIterator(void) { return **this; } + + inline pkgCache *Cache() const { return (**this).Cache(); }; + inline unsigned long Index() const {return (**this).Index();}; + // we have only valid iterators here + inline bool end() const { return false; }; + + inline pkgCache::Version const * operator->() const { + return &***this; + }; + + inline int CompareVer(const pkgCache::VerIterator &B) const { return (**this).CompareVer(B); }; + inline const char *VerStr() const { return (**this).VerStr(); }; + inline const char *Section() const { return (**this).Section(); }; + inline const char *Arch() const { return (**this).Arch(); }; + inline const char *Arch(bool const pseudo) const { return (**this).Arch(pseudo); }; + inline pkgCache::PkgIterator ParentPkg() const { return (**this).ParentPkg(); }; + inline pkgCache::DescIterator DescriptionList() const { return (**this).DescriptionList(); }; + inline pkgCache::DescIterator TranslatedDescription() const { return (**this).TranslatedDescription(); }; + inline pkgCache::DepIterator DependsList() const { return (**this).DependsList(); }; + inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); }; + inline pkgCache::VerFileIterator FileList() const { return (**this).FileList(); }; + inline bool Downloadable() const { return (**this).Downloadable(); }; + inline const char *PriorityType() const { return (**this).PriorityType(); }; + inline string RelStr() const { return (**this).RelStr(); }; + inline bool Automatic() const { return (**this).Automatic(); }; + inline bool Pseudo() const { return (**this).Pseudo(); }; + inline pkgCache::VerFileIterator NewestFile() const { return (**this).NewestFile(); }; + }; + // 103. set::iterator is required to be modifiable, but this allows modification of keys + typedef typename APT::VersionSet::const_iterator iterator; /*}}}*/ -}; - /*}}}*/ +}; /*}}}*/ } #endif diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index adaae9c89..30bb41470 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -742,7 +742,7 @@ pkgCache::VerFileIterator pkgCache::VerIterator::NewestFile() const // --------------------------------------------------------------------- /* This describes the version from a release-centric manner. The output is a list of Label:Version/Archive */ -string pkgCache::VerIterator::RelStr() +string pkgCache::VerIterator::RelStr() const { bool First = true; string Res; -- cgit v1.2.3 From 96db74ce38e9451609fe33f9e25f3f9d42b1fe22 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 2 Jun 2010 16:40:40 +0200 Subject: * apt-pkg/deb/dpkgpm.cc: - add missing include * methods/mirror.{cc,h}: - add SelectNextMirror() and InitMirrors() functions - read all mirrors into the AllMirrors vector --- apt-pkg/deb/dpkgpm.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 18c731788..7e5171eda 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From 963b16dcebba149ae2c35bd255b34242923fbea0 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 2 Jun 2010 23:30:01 +0200 Subject: implement Fail-Ignore bool in FetchItem that tells the method that a failure of this item is ok and does not need to be tried on all mirrors --- apt-pkg/acquire-item.cc | 7 +++++++ apt-pkg/acquire-item.h | 1 + apt-pkg/acquire-method.cc | 1 + apt-pkg/acquire-method.h | 1 + 4 files changed, 10 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index a959253bc..3cc2c8717 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -820,6 +820,13 @@ pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner, string URI,string URIDesc,string ShortDesc) : pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashString(), "") { +} + /*}}}*/ +// AcqIndexTrans::Custom600Headers - Insert custom request headers /*{{{*/ +// --------------------------------------------------------------------- +string pkgAcqIndexTrans::Custom600Headers() +{ + return "\nFail-Ignore: true"; } /*}}}*/ // AcqIndexTrans::Failed - Silence failure messages for missing files /*{{{*/ diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index 06fcffc73..3ac8a19e2 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -573,6 +573,7 @@ class pkgAcqIndexTrans : public pkgAcqIndex public: virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); + virtual string Custom600Headers(); /** \brief Create a pkgAcqIndexTrans. * diff --git a/apt-pkg/acquire-method.cc b/apt-pkg/acquire-method.cc index 3008c8d1a..6e021a445 100644 --- a/apt-pkg/acquire-method.cc +++ b/apt-pkg/acquire-method.cc @@ -381,6 +381,7 @@ int pkgAcqMethod::Run(bool Single) if (StrToTime(LookupTag(Message,"Last-Modified"),Tmp->LastModified) == false) Tmp->LastModified = 0; Tmp->IndexFile = StringToBool(LookupTag(Message,"Index-File"),false); + Tmp->FailIgnore = StringToBool(LookupTag(Message,"Fail-Ignore"),false); Tmp->Next = 0; // Append it to the list diff --git a/apt-pkg/acquire-method.h b/apt-pkg/acquire-method.h index 99a4605b1..03851e823 100644 --- a/apt-pkg/acquire-method.h +++ b/apt-pkg/acquire-method.h @@ -37,6 +37,7 @@ class pkgAcqMethod string DestFile; time_t LastModified; bool IndexFile; + bool FailIgnore; }; struct FetchResult -- cgit v1.2.3 From e2c66de5c5e63d8400efb0522c31fbe1ec225f93 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 3 Jun 2010 09:22:00 +0200 Subject: * apt-pkg/pkgcache.h: - switch {,Install-}Size to unsigned long long * apt-pkg/depcache.cc: - deal with long long, not with int to remove 2GB Limit (LP: #250909) --- apt-pkg/acquire-item.h | 4 ++-- apt-pkg/deb/deblistparser.cc | 5 ++--- apt-pkg/depcache.cc | 14 +++++++------- apt-pkg/pkgcache.h | 4 ++-- apt-pkg/tagfile.cc | 24 ++++++++++++++++++++++++ apt-pkg/tagfile.h | 1 + 6 files changed, 38 insertions(+), 14 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index b338b2a41..36fc53b92 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -112,10 +112,10 @@ class pkgAcquire::Item : public WeakPointable string ErrorText; /** \brief The size of the object to fetch. */ - unsigned long FileSize; + unsigned long long FileSize; /** \brief How much of the object was already fetched. */ - unsigned long PartialSize; + unsigned long long PartialSize; /** \brief If not \b NULL, contains the name of a subprocess that * is operating on this object (for instance, "gzip" or "gpgv"). diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 0551a5f7c..83c5b8d2e 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -133,10 +133,9 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) } // Archive Size - Ver->Size = (unsigned)Section.FindI("Size"); - + Ver->Size = Section.FindULL("Size"); // Unpacked Size (in K) - Ver->InstalledSize = (unsigned)Section.FindI("Installed-Size"); + Ver->InstalledSize = Section.FindULL("Installed-Size"); Ver->InstalledSize *= 1024; // Priority diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 411ae5f62..6e0eeab5b 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -422,8 +422,8 @@ void pkgDepCache::AddSizes(const PkgIterator &Pkg,signed long Mult) // Compute the size data if (P.NewInstall() == true) { - iUsrSize += (signed)(Mult*P.InstVerIter(*this)->InstalledSize); - iDownloadSize += (signed)(Mult*P.InstVerIter(*this)->Size); + iUsrSize += (signed long long)(Mult*P.InstVerIter(*this)->InstalledSize); + iDownloadSize += (signed long long)(Mult*P.InstVerIter(*this)->Size); return; } @@ -432,9 +432,9 @@ void pkgDepCache::AddSizes(const PkgIterator &Pkg,signed long Mult) (P.InstallVer != (Version *)Pkg.CurrentVer() || (P.iFlags & ReInstall) == ReInstall) && P.InstallVer != 0) { - iUsrSize += (signed)(Mult*((signed)P.InstVerIter(*this)->InstalledSize - - (signed)Pkg.CurrentVer()->InstalledSize)); - iDownloadSize += (signed)(Mult*P.InstVerIter(*this)->Size); + iUsrSize += (signed long long)(Mult*((signed long long)P.InstVerIter(*this)->InstalledSize - + (signed long long)Pkg.CurrentVer()->InstalledSize)); + iDownloadSize += (signed long long)(Mult*P.InstVerIter(*this)->Size); return; } @@ -442,14 +442,14 @@ void pkgDepCache::AddSizes(const PkgIterator &Pkg,signed long Mult) if (Pkg.State() == pkgCache::PkgIterator::NeedsUnpack && P.Delete() == false) { - iDownloadSize += (signed)(Mult*P.InstVerIter(*this)->Size); + iDownloadSize += (signed long long)(Mult*P.InstVerIter(*this)->Size); return; } // Removing if (Pkg->CurrentVer != 0 && P.InstallVer == 0) { - iUsrSize -= (signed)(Mult*Pkg.CurrentVer()->InstalledSize); + iUsrSize -= (signed long long)(Mult*Pkg.CurrentVer()->InstalledSize); return; } } diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 643f240b0..426bb9f13 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -532,9 +532,9 @@ struct pkgCache::Version /** \brief archive size for this version For Debian this is the size of the .deb file. */ - map_ptrloc Size; // These are the .deb size + unsigned long long Size; // These are the .deb size /** \brief uncompressed size for this version */ - map_ptrloc InstalledSize; + unsigned long long InstalledSize; /** \brief characteristic value representing this version No two packages in existence should have the same VerStr diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 0d4999ee7..1394d7e24 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -365,6 +365,30 @@ signed int pkgTagSection::FindI(const char *Tag,signed long Default) const return Result; } /*}}}*/ +// TagSection::FindULL - Find an unsigned long long integer /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned long long pkgTagSection::FindULL(const char *Tag, unsigned long long const &Default) const +{ + const char *Start; + const char *Stop; + if (Find(Tag,Start,Stop) == false) + return Default; + + // Copy it into a temp buffer so we can use strtoull + char S[100]; + if ((unsigned)(Stop - Start) >= sizeof(S)) + return Default; + strncpy(S,Start,Stop-Start); + S[Stop - Start] = 0; + + char *End; + unsigned long long Result = strtoull(S,&End,10); + if (S == End) + return Default; + return Result; +} + /*}}}*/ // TagSection::FindFlag - Locate a yes/no type flag /*{{{*/ // --------------------------------------------------------------------- /* The bits marked in Flag are masked on/off in Flags */ diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h index f63a51d07..6891c1d81 100644 --- a/apt-pkg/tagfile.h +++ b/apt-pkg/tagfile.h @@ -57,6 +57,7 @@ class pkgTagSection bool Find(const char *Tag,unsigned &Pos) const; string FindS(const char *Tag) const; signed int FindI(const char *Tag,signed long Default = 0) const ; + unsigned long long FindULL(const char *Tag, unsigned long long const &Default = 0) const; bool FindFlag(const char *Tag,unsigned long &Flags, unsigned long Flag) const; bool Scan(const char *Start,unsigned long MaxLength); -- cgit v1.2.3 From 81305a0b30cc12aa6d32081bbdcf930907ecfbbe Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 3 Jun 2010 09:50:06 +0200 Subject: deprecate AddSize with Multiplier as it is unused and switch to boolean instead to handle the sizes more gracefully. --- apt-pkg/depcache.cc | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++-- apt-pkg/depcache.h | 5 ++-- 2 files changed, 74 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 6e0eeab5b..786b20ec0 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -407,8 +407,11 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res) /*}}}*/ // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/ // --------------------------------------------------------------------- -/* Call with Mult = -1 to preform the inverse opration */ -void pkgDepCache::AddSizes(const PkgIterator &Pkg,signed long Mult) +/* Call with Mult = -1 to preform the inverse opration + The Mult increases the complexity of the calulations here and is unused - + or do we really have a usecase for removing the size of a package two + times? So let us replace it with a simple bool and be done with it… */ +__deprecated void pkgDepCache::AddSizes(const PkgIterator &Pkg,signed long Mult) { StateCache &P = PkgState[Pkg->ID]; @@ -454,6 +457,72 @@ void pkgDepCache::AddSizes(const PkgIterator &Pkg,signed long Mult) } } /*}}}*/ +// DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/ +// --------------------------------------------------------------------- +/* Call with Inverse = true to preform the inverse opration */ +void pkgDepCache::AddSizes(const PkgIterator &Pkg, bool const &Inverse) +{ + StateCache &P = PkgState[Pkg->ID]; + + if (Pkg->VersionList == 0) + return; + + if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && + P.Keep() == true) + return; + + // Compute the size data + if (P.NewInstall() == true) + { + if (Inverse == false) { + iUsrSize += P.InstVerIter(*this)->InstalledSize; + iDownloadSize += P.InstVerIter(*this)->Size; + } else { + iUsrSize -= P.InstVerIter(*this)->InstalledSize; + iDownloadSize -= P.InstVerIter(*this)->Size; + } + return; + } + + // Upgrading + if (Pkg->CurrentVer != 0 && + (P.InstallVer != (Version *)Pkg.CurrentVer() || + (P.iFlags & ReInstall) == ReInstall) && P.InstallVer != 0) + { + if (Inverse == false) { + iUsrSize -= Pkg.CurrentVer()->InstalledSize; + iUsrSize += P.InstVerIter(*this)->InstalledSize; + iDownloadSize += P.InstVerIter(*this)->Size; + } else { + iUsrSize -= P.InstVerIter(*this)->InstalledSize; + iUsrSize += Pkg.CurrentVer()->InstalledSize; + iDownloadSize -= P.InstVerIter(*this)->Size; + } + return; + } + + // Reinstall + if (Pkg.State() == pkgCache::PkgIterator::NeedsUnpack && + P.Delete() == false) + { + if (Inverse == false) + iDownloadSize += P.InstVerIter(*this)->Size; + else + iDownloadSize -= P.InstVerIter(*this)->Size; + return; + } + + // Removing + if (Pkg->CurrentVer != 0 && P.InstallVer == 0) + { + if (Inverse == false) + iUsrSize -= Pkg.CurrentVer()->InstalledSize; + else + iUsrSize += Pkg.CurrentVer()->InstalledSize; + return; + } +} + /*}}}*/ // DepCache::AddStates - Add the package to the state counter /*{{{*/ // --------------------------------------------------------------------- /* This routine is tricky to use, you must make sure that it is never diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 3decc7a5f..d4258438f 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -321,8 +321,9 @@ class pkgDepCache : protected pkgCache::Namespace void Update(PkgIterator const &P); // Count manipulators - void AddSizes(const PkgIterator &Pkg,signed long Mult = 1); - inline void RemoveSizes(const PkgIterator &Pkg) {AddSizes(Pkg,-1);}; + void AddSizes(const PkgIterator &Pkg, bool const &Invert = false); + inline void RemoveSizes(const PkgIterator &Pkg) {AddSizes(Pkg, true);}; + void AddSizes(const PkgIterator &Pkg,signed long Mult) __deprecated; void AddStates(const PkgIterator &Pkg,int Add = 1); inline void RemoveStates(const PkgIterator &Pkg) {AddStates(Pkg,-1);}; -- cgit v1.2.3 From a3c4c81afe25377020470ff71c1362136437397c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 3 Jun 2010 10:45:58 +0200 Subject: * apt-pkg/depcache.cc: - switch i{Download,Usr}Size from double to (un)signed long long The biggest reason is that this saves a lot of float point operations we do in AddSizes() on integers. The only reason i see that this was a double is that it was 64bit long and can therefore store bigger values than int/long, but with the availablity of (un)signed long long we are now also at 64bit and can store sizes more than 8 Exabytes big - by the time this will be a limit the C/C++ Standard will have bigger types, hopefully. --- apt-pkg/acquire.cc | 12 ++++++------ apt-pkg/acquire.h | 6 +++--- apt-pkg/depcache.h | 12 +++++++----- 3 files changed, 16 insertions(+), 14 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index 832eaa02c..63825da93 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -506,9 +506,9 @@ bool pkgAcquire::Clean(string Dir) // Acquire::TotalNeeded - Number of bytes to fetch /*{{{*/ // --------------------------------------------------------------------- /* This is the total number of bytes needed */ -double pkgAcquire::TotalNeeded() +unsigned long long pkgAcquire::TotalNeeded() { - double Total = 0; + unsigned long long Total = 0; for (ItemCIterator I = ItemsBegin(); I != ItemsEnd(); I++) Total += (*I)->FileSize; return Total; @@ -517,9 +517,9 @@ double pkgAcquire::TotalNeeded() // Acquire::FetchNeeded - Number of bytes needed to get /*{{{*/ // --------------------------------------------------------------------- /* This is the number of bytes that is not local */ -double pkgAcquire::FetchNeeded() +unsigned long long pkgAcquire::FetchNeeded() { - double Total = 0; + unsigned long long Total = 0; for (ItemCIterator I = ItemsBegin(); I != ItemsEnd(); I++) if ((*I)->Local == false) Total += (*I)->FileSize; @@ -529,9 +529,9 @@ double pkgAcquire::FetchNeeded() // Acquire::PartialPresent - Number of partial bytes we already have /*{{{*/ // --------------------------------------------------------------------- /* This is the number of bytes that is not local */ -double pkgAcquire::PartialPresent() +unsigned long long pkgAcquire::PartialPresent() { - double Total = 0; + unsigned long long Total = 0; for (ItemCIterator I = ItemsBegin(); I != ItemsEnd(); I++) if ((*I)->Local == false) Total += (*I)->PartialSize; diff --git a/apt-pkg/acquire.h b/apt-pkg/acquire.h index 8e2c21151..82be8b843 100644 --- a/apt-pkg/acquire.h +++ b/apt-pkg/acquire.h @@ -323,17 +323,17 @@ class pkgAcquire /** \return the total size in bytes of all the items included in * this download. */ - double TotalNeeded(); + unsigned long long TotalNeeded(); /** \return the size in bytes of all non-local items included in * this download. */ - double FetchNeeded(); + unsigned long long FetchNeeded(); /** \return the amount of data to be fetched that is already * present on the filesystem. */ - double PartialPresent(); + unsigned long long PartialPresent(); /** \brief Delayed constructor * diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index d4258438f..c6f245a80 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -286,9 +286,11 @@ class pkgDepCache : protected pkgCache::Namespace pkgCache *Cache; StateCache *PkgState; unsigned char *DepState; - - double iUsrSize; - double iDownloadSize; + + /** Stores the space changes after installation */ + signed long long iUsrSize; + /** Stores how much we need to download to get the packages */ + unsigned long long iDownloadSize; unsigned long iInstCount; unsigned long iDelCount; unsigned long iKeepCount; @@ -452,8 +454,8 @@ class pkgDepCache : protected pkgCache::Namespace bool writeStateFile(OpProgress *prog, bool InstalledOnly=true); // Size queries - inline double UsrSize() {return iUsrSize;}; - inline double DebSize() {return iDownloadSize;}; + inline signed long long UsrSize() {return iUsrSize;}; + inline unsigned long long DebSize() {return iDownloadSize;}; inline unsigned long DelCount() {return iDelCount;}; inline unsigned long KeepCount() {return iKeepCount;}; inline unsigned long InstCount() {return iInstCount;}; -- cgit v1.2.3 From 2e5f4e45f593535e2c88181ff7a9e2d32a5e60f9 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 4 Jun 2010 14:43:03 +0200 Subject: * apt-pkg/cachefile.{cc,h}: - split Open() into submethods to be able to build only parts - make the OpProgress optional in the Cache buildprocess --- apt-pkg/cachefile.cc | 50 ++++++++++++++++++++++++++++++++------------- apt-pkg/cachefile.h | 15 ++++++++------ apt-pkg/deb/debindexfile.cc | 18 ++++++++-------- apt-pkg/deb/debindexfile.h | 6 +++--- apt-pkg/indexfile.h | 8 ++++++-- apt-pkg/pkgcachegen.cc | 45 +++++++++++++++++++++++++--------------- apt-pkg/pkgcachegen.h | 10 +++++++-- 7 files changed, 100 insertions(+), 52 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cachefile.cc b/apt-pkg/cachefile.cc index 790312dc8..b0f8bc424 100644 --- a/apt-pkg/cachefile.cc +++ b/apt-pkg/cachefile.cc @@ -46,7 +46,7 @@ pkgCacheFile::~pkgCacheFile() // CacheFile::BuildCaches - Open and build the cache files /*{{{*/ // --------------------------------------------------------------------- /* */ -bool pkgCacheFile::BuildCaches(OpProgress &Progress,bool WithLock) +bool pkgCacheFile::BuildCaches(OpProgress *Progress, bool WithLock) { const bool ErrorWasEmpty = _error->empty(); if (WithLock == true) @@ -65,8 +65,9 @@ bool pkgCacheFile::BuildCaches(OpProgress &Progress,bool WithLock) return _error->Error(_("The list of sources could not be read.")); // Read the caches - bool Res = pkgMakeStatusCache(List,Progress,&Map,!WithLock); - Progress.Done(); + bool Res = pkgCacheGenerator::MakeStatusCache(List,Progress,&Map,!WithLock); + if (Progress != NULL) + Progress->Done(); if (Res == false) return _error->Error(_("The package lists or status file could not be parsed or opened.")); @@ -80,29 +81,50 @@ bool pkgCacheFile::BuildCaches(OpProgress &Progress,bool WithLock) return true; } /*}}}*/ -// CacheFile::Open - Open the cache files, creating if necessary /*{{{*/ +// CacheFile::BuildPolicy - Open and build all relevant preferences /*{{{*/ // --------------------------------------------------------------------- /* */ -bool pkgCacheFile::Open(OpProgress &Progress,bool WithLock) +bool pkgCacheFile::BuildPolicy(OpProgress *Progress) { - if (BuildCaches(Progress,WithLock) == false) - return false; - - // The policy engine Policy = new pkgPolicy(Cache); if (_error->PendingError() == true) return false; if (ReadPinFile(*Policy) == false || ReadPinDir(*Policy) == false) return false; - - // Create the dependency cache + + return true; +} + /*}}}*/ +// CacheFile::BuildDepCache - Open and build the dependency cache /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgCacheFile::BuildDepCache(OpProgress *Progress) +{ DCache = new pkgDepCache(Cache,Policy); if (_error->PendingError() == true) return false; - - DCache->Init(&Progress); - Progress.Done(); + + DCache->Init(Progress); + return true; +} + /*}}}*/ +// CacheFile::Open - Open the cache files, creating if necessary /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgCacheFile::Open(OpProgress *Progress, bool WithLock) +{ + if (BuildCaches(Progress,WithLock) == false) + return false; + + if (BuildPolicy(Progress) == false) + return false; + + if (BuildDepCache(Progress) == false) + return false; + + if (Progress != NULL) + Progress->Done(); if (_error->PendingError() == true) return false; diff --git a/apt-pkg/cachefile.h b/apt-pkg/cachefile.h index 3b057951c..b75a7dbe4 100644 --- a/apt-pkg/cachefile.h +++ b/apt-pkg/cachefile.h @@ -30,11 +30,10 @@ class pkgCacheFile MMap *Map; pkgCache *Cache; pkgDepCache *DCache; - + pkgPolicy *Policy; + public: - pkgPolicy *Policy; - // We look pretty much exactly like a pointer to a dep cache inline operator pkgCache &() {return *Cache;}; inline operator pkgCache *() {return Cache;}; @@ -45,12 +44,16 @@ class pkgCacheFile inline pkgDepCache::StateCache &operator [](pkgCache::PkgIterator const &I) {return (*DCache)[I];}; inline unsigned char &operator [](pkgCache::DepIterator const &I) {return (*DCache)[I];}; - bool BuildCaches(OpProgress &Progress,bool WithLock = true); - bool Open(OpProgress &Progress,bool WithLock = true); + bool BuildCaches(OpProgress *Progress = NULL,bool WithLock = true); + __deprecated bool BuildCaches(OpProgress &Progress,bool const &WithLock = true) { return BuildCaches(&Progress, WithLock); }; + bool BuildPolicy(OpProgress *Progress = NULL); + bool BuildDepCache(OpProgress *Progress = NULL); + bool Open(OpProgress *Progress = NULL, bool WithLock = true); + __deprecated bool Open(OpProgress &Progress,bool const &WithLock = true) { return Open(&Progress, WithLock); }; void Close(); pkgCacheFile(); - ~pkgCacheFile(); + virtual ~pkgCacheFile(); }; #endif diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index b89429d86..6d9e99497 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -262,15 +262,15 @@ unsigned long debPackagesIndex::Size() const // PackagesIndex::Merge - Load the index file into a cache /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const +bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const { string PackageFile = IndexFile("Packages"); FileFd Pkg(PackageFile,FileFd::ReadOnly); debListParser Parser(&Pkg, Architecture); if (_error->PendingError() == true) return _error->Error("Problem opening %s",PackageFile.c_str()); - - Prog.SubProgress(0,Info("Packages")); + if (Prog != NULL) + Prog->SubProgress(0,Info("Packages")); ::URI Tmp(URI); if (Gen.SelectFile(PackageFile,Tmp.Host,*this) == false) return _error->Error("Problem with SelectFile %s",PackageFile.c_str()); @@ -445,7 +445,7 @@ unsigned long debTranslationsIndex::Size() const // TranslationsIndex::Merge - Load the index file into a cache /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const +bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const { // Check the translation file, if in use string TranslationFile = IndexFile(Language); @@ -456,7 +456,8 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const if (_error->PendingError() == true) return false; - Prog.SubProgress(0, Info(TranslationFile.c_str())); + if (Prog != NULL) + Prog->SubProgress(0, Info(TranslationFile.c_str())); if (Gen.SelectFile(TranslationFile,string(),*this) == false) return _error->Error("Problem with SelectFile %s",TranslationFile.c_str()); @@ -529,7 +530,7 @@ unsigned long debStatusIndex::Size() const // StatusIndex::Merge - Load the index file into a cache /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const +bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const { FileFd Pkg(File,FileFd::ReadOnly); if (_error->PendingError() == true) @@ -537,8 +538,9 @@ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const debListParser Parser(&Pkg); if (_error->PendingError() == true) return false; - - Prog.SubProgress(0,File); + + if (Prog != NULL) + Prog->SubProgress(0,File); if (Gen.SelectFile(File,string(),*this,pkgCache::Flag::NotSource) == false) return _error->Error("Problem with SelectFile %s",File.c_str()); diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h index 766e8b214..b5085992d 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@ -35,7 +35,7 @@ class debStatusIndex : public pkgIndexFile virtual bool Exists() const; virtual bool HasPackages() const {return true;}; virtual unsigned long Size() const; - virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const; + virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; debStatusIndex(string File); @@ -67,7 +67,7 @@ class debPackagesIndex : public pkgIndexFile virtual bool Exists() const; virtual bool HasPackages() const {return true;}; virtual unsigned long Size() const; - virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const; + virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; debPackagesIndex(string const &URI, string const &Dist, string const &Section, @@ -99,7 +99,7 @@ class debTranslationsIndex : public pkgIndexFile virtual bool Exists() const; virtual bool HasPackages() const; virtual unsigned long Size() const; - virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const; + virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; debTranslationsIndex(string URI,string Dist,string Section, char const * const Language); diff --git a/apt-pkg/indexfile.h b/apt-pkg/indexfile.h index 3cc501629..2b5ae6342 100644 --- a/apt-pkg/indexfile.h +++ b/apt-pkg/indexfile.h @@ -74,8 +74,12 @@ class pkgIndexFile virtual bool Exists() const = 0; virtual bool HasPackages() const = 0; virtual unsigned long Size() const = 0; - virtual bool Merge(pkgCacheGenerator &/*Gen*/,OpProgress &/*Prog*/) const {return false;}; - virtual bool MergeFileProvides(pkgCacheGenerator &/*Gen*/,OpProgress &/*Prog*/) const {return true;}; + virtual bool Merge(pkgCacheGenerator &/*Gen*/,OpProgress* /*Prog*/) const { return false; }; + __deprecated virtual bool Merge(pkgCacheGenerator &Gen, OpProgress &Prog) const + { return Merge(Gen, &Prog); }; + virtual bool MergeFileProvides(pkgCacheGenerator &/*Gen*/,OpProgress* /*Prog*/) const {return true;}; + __deprecated virtual bool MergeFileProvides(pkgCacheGenerator &Gen, OpProgress &Prog) const + {return MergeFileProvides(Gen, &Prog);}; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; static bool TranslationsAvailable(); diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index d96d3370f..5649cd6f8 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -526,7 +526,7 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, // CacheGenerator::FinishCache - do various finish operations /*{{{*/ // --------------------------------------------------------------------- /* This prepares the Cache for delivery */ -bool pkgCacheGenerator::FinishCache(OpProgress &Progress) +bool pkgCacheGenerator::FinishCache(OpProgress *Progress) { // FIXME: add progress reporting for this operation // Do we have different architectures in your groups ? @@ -923,7 +923,7 @@ static unsigned long ComputeSize(FileIterator Start,FileIterator End) // --------------------------------------------------------------------- /* */ static bool BuildCache(pkgCacheGenerator &Gen, - OpProgress &Progress, + OpProgress *Progress, unsigned long &CurrentSize,unsigned long TotalSize, FileIterator Start, FileIterator End) { @@ -944,7 +944,8 @@ static bool BuildCache(pkgCacheGenerator &Gen, } unsigned long Size = (*I)->Size(); - Progress.OverallProgress(CurrentSize,TotalSize,Size,_("Reading package lists")); + if (Progress != NULL) + Progress->OverallProgress(CurrentSize,TotalSize,Size,_("Reading package lists")); CurrentSize += Size; if ((*I)->Merge(Gen,Progress) == false) @@ -953,13 +954,15 @@ static bool BuildCache(pkgCacheGenerator &Gen, if (Gen.HasFileDeps() == true) { - Progress.Done(); + if (Progress != NULL) + Progress->Done(); TotalSize = ComputeSize(Start, End); CurrentSize = 0; for (I = Start; I != End; I++) { unsigned long Size = (*I)->Size(); - Progress.OverallProgress(CurrentSize,TotalSize,Size,_("Collecting File Provides")); + if (Progress != NULL) + Progress->OverallProgress(CurrentSize,TotalSize,Size,_("Collecting File Provides")); CurrentSize += Size; if ((*I)->MergeFileProvides(Gen,Progress) == false) return false; @@ -969,7 +972,7 @@ static bool BuildCache(pkgCacheGenerator &Gen, return true; } /*}}}*/ -// MakeStatusCache - Construct the status cache /*{{{*/ +// CacheGenerator::MakeStatusCache - Construct the status cache /*{{{*/ // --------------------------------------------------------------------- /* This makes sure that the status cache (the cache that has all index files from the sources list and all local ones) is ready @@ -977,7 +980,10 @@ static bool BuildCache(pkgCacheGenerator &Gen, the cache will be stored there. This is pretty much mandetory if you are using AllowMem. AllowMem lets the function be run as non-root where it builds the cache 'fast' into a memory buffer. */ -bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, +__deprecated bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, + MMap **OutMap, bool AllowMem) + { return pkgCacheGenerator::MakeStatusCache(List, &Progress, OutMap, AllowMem); } +bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress, MMap **OutMap,bool AllowMem) { bool const Debug = _config->FindB("Debug::pkgCacheGen", false); @@ -1028,13 +1034,15 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, if (Writeable == false && AllowMem == false && CacheFile.empty() == false) return _error->Error(_("Unable to write to %s"),flNotFile(CacheFile).c_str()); - - Progress.OverallProgress(0,1,1,_("Reading package lists")); - + + if (Progress != NULL) + Progress->OverallProgress(0,1,1,_("Reading package lists")); + // Cache is OK, Fin. if (CheckValidity(CacheFile,Files.begin(),Files.end(),OutMap) == true) { - Progress.OverallProgress(1,1,1,_("Reading package lists")); + if (Progress != NULL) + Progress->OverallProgress(1,1,1,_("Reading package lists")); if (Debug == true) std::clog << "pkgcache.bin is valid - no need to build anything" << std::endl; return true; @@ -1084,7 +1092,7 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, TotalSize = ComputeSize(Files.begin()+EndOfSource,Files.end()); // Build the status cache - pkgCacheGenerator Gen(Map.Get(),&Progress); + pkgCacheGenerator Gen(Map.Get(),Progress); if (_error->PendingError() == true) return false; if (BuildCache(Gen,Progress,CurrentSize,TotalSize, @@ -1101,7 +1109,7 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, TotalSize = ComputeSize(Files.begin(),Files.end()); // Build the source cache - pkgCacheGenerator Gen(Map.Get(),&Progress); + pkgCacheGenerator Gen(Map.Get(),Progress); if (_error->PendingError() == true) return false; if (BuildCache(Gen,Progress,CurrentSize,TotalSize, @@ -1160,10 +1168,12 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, return true; } /*}}}*/ -// MakeOnlyStatusCache - Build a cache with just the status files /*{{{*/ +// CacheGenerator::MakeOnlyStatusCache - Build only a status files cache/*{{{*/ // --------------------------------------------------------------------- /* */ -bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap) +__deprecated bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap) + { return pkgCacheGenerator::MakeOnlyStatusCache(&Progress, OutMap); } +bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap) { unsigned long MapSize = _config->FindI("APT::Cache-Limit",20*1024*1024); vector Files; @@ -1178,8 +1188,9 @@ bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap) TotalSize = ComputeSize(Files.begin()+EndOfSource,Files.end()); // Build the status cache - Progress.OverallProgress(0,1,1,_("Reading package lists")); - pkgCacheGenerator Gen(Map.Get(),&Progress); + if (Progress != NULL) + Progress->OverallProgress(0,1,1,_("Reading package lists")); + pkgCacheGenerator Gen(Map.Get(),Progress); if (_error->PendingError() == true) return false; if (BuildCache(Gen,Progress,CurrentSize,TotalSize, diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index 46d0cd893..ff0941e0c 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -76,7 +76,11 @@ class pkgCacheGenerator /*{{{*/ bool HasFileDeps() {return FoundFileDeps;}; bool MergeFileProvides(ListParser &List); - bool FinishCache(OpProgress &Progress); + bool FinishCache(OpProgress *Progress); + + static bool MakeStatusCache(pkgSourceList &List,OpProgress *Progress, + MMap **OutMap = 0,bool AllowMem = false); + static bool MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap); pkgCacheGenerator(DynamicMMap *Map,OpProgress *Progress); ~pkgCacheGenerator(); @@ -134,10 +138,12 @@ class pkgCacheGenerator::ListParser virtual ~ListParser() {}; }; /*}}}*/ + bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, MMap **OutMap = 0,bool AllowMem = false); bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap); + #ifdef APT_COMPATIBILITY #if APT_COMPATIBILITY != 986 #warning "Using APT_COMPATIBILITY" @@ -145,7 +151,7 @@ bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap); MMap *pkgMakeStatusCacheMem(pkgSourceList &List,OpProgress &Progress) { MMap *Map = 0; - if (pkgMakeStatusCache(List,Progress,&Map,true) == false) + if (pkgCacheGenerator::MakeStatusCache(List,&Progress,&Map,true) == false) return 0; return Map; } -- cgit v1.2.3 From 3f8621c5effb167a51944b86334867e2fe8fedb3 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 4 Jun 2010 22:58:57 +0200 Subject: store also the SourceList we use internally for export --- apt-pkg/cachefile.cc | 58 +++++++++++++++++++++++++++++++++++++++++----------- apt-pkg/cachefile.h | 15 +++++++++++++- 2 files changed, 60 insertions(+), 13 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cachefile.cc b/apt-pkg/cachefile.cc index b0f8bc424..01598386c 100644 --- a/apt-pkg/cachefile.cc +++ b/apt-pkg/cachefile.cc @@ -27,7 +27,8 @@ // CacheFile::CacheFile - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgCacheFile::pkgCacheFile() : Map(0), Cache(0), DCache(0), Policy(0) +pkgCacheFile::pkgCacheFile() : Map(NULL), Cache(NULL), DCache(NULL), + Policy(NULL), SrcList(NULL) { } /*}}}*/ @@ -38,16 +39,30 @@ pkgCacheFile::~pkgCacheFile() { delete DCache; delete Policy; + delete SrcList; delete Cache; delete Map; _system->UnLock(true); -} +} /*}}}*/ // CacheFile::BuildCaches - Open and build the cache files /*{{{*/ // --------------------------------------------------------------------- /* */ bool pkgCacheFile::BuildCaches(OpProgress *Progress, bool WithLock) { + if (Cache != NULL) + return true; + + if (_config->FindB("pkgCacheFile::Generate", true) == false) + { + Map = new MMap(*new FileFd(_config->FindFile("Dir::Cache::pkgcache"), + FileFd::ReadOnly),MMap::Public|MMap::ReadOnly); + Cache = new pkgCache(Map); + if (_error->PendingError() == true) + return false; + return true; + } + const bool ErrorWasEmpty = _error->empty(); if (WithLock == true) if (_system->Lock() == false) @@ -58,14 +73,11 @@ bool pkgCacheFile::BuildCaches(OpProgress *Progress, bool WithLock) if (_error->PendingError() == true) return false; - - // Read the source list - pkgSourceList List; - if (List.ReadMainList() == false) - return _error->Error(_("The list of sources could not be read.")); + + BuildSourceList(Progress); // Read the caches - bool Res = pkgCacheGenerator::MakeStatusCache(List,Progress,&Map,!WithLock); + bool Res = pkgCacheGenerator::MakeStatusCache(*SrcList,Progress,&Map,!WithLock); if (Progress != NULL) Progress->Done(); if (Res == false) @@ -81,11 +93,28 @@ bool pkgCacheFile::BuildCaches(OpProgress *Progress, bool WithLock) return true; } /*}}}*/ +// CacheFile::BuildSourceList - Open and build all relevant sources.list/*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgCacheFile::BuildSourceList(OpProgress *Progress) +{ + if (SrcList != NULL) + return true; + + SrcList = new pkgSourceList(); + if (SrcList->ReadMainList() == false) + return _error->Error(_("The list of sources could not be read.")); + return true; +} + /*}}}*/ // CacheFile::BuildPolicy - Open and build all relevant preferences /*{{{*/ // --------------------------------------------------------------------- /* */ bool pkgCacheFile::BuildPolicy(OpProgress *Progress) { + if (Policy != NULL) + return true; + Policy = new pkgPolicy(Cache); if (_error->PendingError() == true) return false; @@ -101,6 +130,9 @@ bool pkgCacheFile::BuildPolicy(OpProgress *Progress) /* */ bool pkgCacheFile::BuildDepCache(OpProgress *Progress) { + if (DCache != NULL) + return true; + DCache = new pkgDepCache(Cache,Policy); if (_error->PendingError() == true) return false; @@ -139,12 +171,14 @@ void pkgCacheFile::Close() delete DCache; delete Policy; delete Cache; + delete SrcList; delete Map; _system->UnLock(true); - Map = 0; - DCache = 0; - Policy = 0; - Cache = 0; + Map = NULL; + DCache = NULL; + Policy = NULL; + Cache = NULL; + SrcList = NULL; } /*}}}*/ diff --git a/apt-pkg/cachefile.h b/apt-pkg/cachefile.h index b75a7dbe4..1647aff8e 100644 --- a/apt-pkg/cachefile.h +++ b/apt-pkg/cachefile.h @@ -23,6 +23,7 @@ #include class pkgPolicy; +class pkgSourceList; class pkgCacheFile { protected: @@ -31,6 +32,7 @@ class pkgCacheFile pkgCache *Cache; pkgDepCache *DCache; pkgPolicy *Policy; + pkgSourceList *SrcList; public: @@ -39,6 +41,10 @@ class pkgCacheFile inline operator pkgCache *() {return Cache;}; inline operator pkgDepCache &() {return *DCache;}; inline operator pkgDepCache *() {return DCache;}; + inline operator pkgPolicy &() {return *Policy;}; + inline operator pkgPolicy *() {return Policy;}; + inline operator pkgSourceList &() {return *SrcList;}; + inline operator pkgSourceList *() {return SrcList;}; inline pkgDepCache *operator ->() {return DCache;}; inline pkgDepCache &operator *() {return *DCache;}; inline pkgDepCache::StateCache &operator [](pkgCache::PkgIterator const &I) {return (*DCache)[I];}; @@ -46,12 +52,19 @@ class pkgCacheFile bool BuildCaches(OpProgress *Progress = NULL,bool WithLock = true); __deprecated bool BuildCaches(OpProgress &Progress,bool const &WithLock = true) { return BuildCaches(&Progress, WithLock); }; + bool BuildSourceList(OpProgress *Progress = NULL); bool BuildPolicy(OpProgress *Progress = NULL); bool BuildDepCache(OpProgress *Progress = NULL); bool Open(OpProgress *Progress = NULL, bool WithLock = true); + inline bool ReadOnlyOpen(OpProgress *Progress = NULL) { return Open(Progress, false); }; __deprecated bool Open(OpProgress &Progress,bool const &WithLock = true) { return Open(&Progress, WithLock); }; void Close(); - + + inline pkgCache* GetPkgCache() { BuildCaches(NULL, false); return Cache; }; + inline pkgDepCache* GetDepCache() { BuildDepCache(); return DCache; }; + inline pkgPolicy* GetPolicy() { BuildPolicy(); return Policy; }; + inline pkgSourceList* GetSourceList() { BuildSourceList(); return SrcList; }; + pkgCacheFile(); virtual ~pkgCacheFile(); }; -- cgit v1.2.3 From 856d3b06a6eb6a7f455294c69fc13604e099fd56 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 5 Jun 2010 09:20:29 +0200 Subject: Add a method to get a VersionSet from the Commandline and refactor the existing methods a bit to reuse them easier intern --- apt-pkg/cacheset.cc | 140 +++++++++++++++++++++++++++++++++++++++++++++------- apt-pkg/cacheset.h | 74 +++++++++++++++++++++++++-- 2 files changed, 191 insertions(+), 23 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index b49b36539..7372c909e 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -22,7 +23,7 @@ /*}}}*/ namespace APT { // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ -PackageSet PackageSet::FromRegEx(pkgCache &Cache, std::string pattern, std::ostream &out) { +PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { PackageSet pkgset; std::string arch = "native"; static const char * const isregex = ".?+*|[^$"; @@ -48,7 +49,7 @@ PackageSet PackageSet::FromRegEx(pkgCache &Cache, std::string pattern, std::ostr return pkgset; } - for (pkgCache::GrpIterator Grp = Cache.GrpBegin(); Grp.end() == false; ++Grp) + for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) { if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0) continue; @@ -76,28 +77,129 @@ PackageSet PackageSet::FromRegEx(pkgCache &Cache, std::string pattern, std::ostr } /*}}}*/ // FromCommandLine - Return all packages specified on commandline /*{{{*/ -PackageSet PackageSet::FromCommandLine(pkgCache &Cache, const char **cmdline, std::ostream &out) { +PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out) { PackageSet pkgset; for (const char **I = cmdline + 1; *I != 0; I++) { - pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); - if (Pkg.end() == true) { - std::vector archs = APT::Configuration::getArchitectures(); - for (std::vector::const_iterator a = archs.begin(); - a != archs.end() || Pkg.end() != true; ++a) { - Pkg = Cache.FindPkg(*I, *a); - } - if (Pkg.end() == true) { - PackageSet regex = FromRegEx(Cache, *I, out); - if (regex.empty() == true) - _error->Warning(_("Unable to locate package %s"),*I); - else - pkgset.insert(regex.begin(), regex.end()); - continue; + PackageSet pset = FromString(Cache, *I, out); + pkgset.insert(pset.begin(), pset.end()); + } + return pkgset; +} + /*}}}*/ +// FromString - Return all packages matching a specific string /*{{{*/ +PackageSet PackageSet::FromString(pkgCacheFile &Cache, const char * const str, std::ostream &out) { + pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(str); + if (Grp.end() == false) { + pkgCache::PkgIterator Pkg = Grp.FindPreferredPkg(); + PackageSet pkgset; + pkgset.insert(Pkg); + return pkgset; + } + PackageSet regex = FromRegEx(Cache, str, out); + if (regex.empty() == true) + _error->Warning(_("Unable to locate package %s"), str); + return regex; +} + /*}}}*/ +// FromCommandLine - Return all versions specified on commandline /*{{{*/ +APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, + APT::VersionSet::Version const &fallback, std::ostream &out) { + VersionSet verset; + for (const char **I = cmdline + 1; *I != 0; I++) { + std::string pkg = *I; + std::string ver; + bool verIsRel = false; + size_t const vertag = pkg.find_last_of("/="); + if (vertag != string::npos) { + ver = pkg.substr(vertag+1); + verIsRel = (pkg[vertag] == '/'); + pkg.erase(vertag); + } + PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), out); + for (PackageSet::const_iterator P = pkgset.begin(); + P != pkgset.end(); ++P) { + if (vertag != string::npos) { + pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release : + pkgVersionMatch::Version)); + pkgCache::VerIterator V = Match.Find(P); + if (V.end() == true) { + if (verIsRel == true) + _error->Error(_("Release '%s' for '%s' was not found"), + ver.c_str(), P.FullName(true).c_str()); + else + _error->Error(_("Version '%s' for '%s' was not found"), + ver.c_str(), P.FullName(true).c_str()); + continue; + } + if (strcmp(ver.c_str(), V.VerStr()) != 0) + ioprintf(out, _("Selected version %s (%s) for %s\n"), + V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); + verset.insert(V); + } else { + pkgCache::VerIterator V; + switch(fallback) { + case VersionSet::ALL: + for (V = P.VersionList(); V.end() != true; ++V) + verset.insert(V); + break; + case VersionSet::CANDANDINST: + verset.insert(getInstalledVer(Cache, P)); + verset.insert(getCandidateVer(Cache, P)); + break; + case VersionSet::CANDIDATE: + verset.insert(getCandidateVer(Cache, P)); + break; + case VersionSet::INSTALLED: + verset.insert(getInstalledVer(Cache, P)); + break; + case VersionSet::CANDINST: + V = getCandidateVer(Cache, P, true); + if (V.end() == true) + V = getInstalledVer(Cache, P, true); + if (V.end() == false) + verset.insert(V); + else + _error->Error(_("Can't select installed nor candidate version from package %s as it has neither of them"), P.FullName(true).c_str()); + break; + case VersionSet::INSTCAND: + V = getInstalledVer(Cache, P, true); + if (V.end() == true) + V = getCandidateVer(Cache, P, true); + if (V.end() == false) + verset.insert(V); + else + _error->Error(_("Can't select installed nor candidate version from package %s as it has neither of them"), P.FullName(true).c_str()); + break; + case VersionSet::NEWEST: + if (P->VersionList != 0) + verset.insert(P.VersionList()); + else + _error->Error(_("Can't select newest version from package %s as it is purely virtual"), P.FullName(true).c_str()); + break; + } } } - pkgset.insert(Pkg); } - return pkgset; + return verset; +} + /*}}}*/ +// getCandidateVer - Returns the candidate version of the given package /*{{{*/ +pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, bool const &AllowError) { + if (unlikely(Cache.BuildDepCache() == false)) + return pkgCache::VerIterator(*Cache); + pkgCache::VerIterator Cand = Cache[Pkg].InstVerIter(Cache); + if (AllowError == false && Cand.end() == true) + _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str()); + return Cand; +} + /*}}}*/ +// getInstalledVer - Returns the installed version of the given package /*{{{*/ +pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, bool const &AllowError) { + if (AllowError == false && Pkg->CurrentVer == 0) + _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str()); + return Pkg.CurrentVer(); } /*}}}*/ } diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index f0131bfed..708531b4a 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -14,6 +14,7 @@ #include #include +#include #include /*}}}*/ namespace APT { @@ -68,12 +69,23 @@ public: /*{{{*/ \param Cache the packages are in \param pattern regular expression for package names \param out stream to print the notice to */ - static APT::PackageSet FromRegEx(pkgCache &Cache, std::string pattern, std::ostream &out); - static APT::PackageSet FromRegEx(pkgCache &Cache, std::string const &pattern) { + static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out); + static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string const &pattern) { std::ostream out (std::ofstream("/dev/null").rdbuf()); return APT::PackageSet::FromRegEx(Cache, pattern, out); } + /** \brief returns all packages specified by a string + + \param Cache the packages are in + \param string String the package name(s) should be extracted from + \param out stream to print various notices to */ + static APT::PackageSet FromString(pkgCacheFile &Cache, const char * const string, std::ostream &out); + static APT::PackageSet FromString(pkgCacheFile &Cache, const char * const string) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::PackageSet::FromString(Cache, string, out); + } + /** \brief returns all packages specified on the commandline Get all package names from the commandline and executes regex's if needed. @@ -81,8 +93,8 @@ public: /*{{{*/ \param Cache the packages are in \param cmdline Command line the package names should be extracted from \param out stream to print various notices to */ - static APT::PackageSet FromCommandLine(pkgCache &Cache, const char **cmdline, std::ostream &out); - static APT::PackageSet FromCommandLine(pkgCache &Cache, const char **cmdline) { + static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out); + static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { std::ostream out (std::ofstream("/dev/null").rdbuf()); return APT::PackageSet::FromCommandLine(Cache, cmdline, out); } @@ -133,6 +145,60 @@ public: /*{{{*/ // 103. set::iterator is required to be modifiable, but this allows modification of keys typedef typename APT::VersionSet::const_iterator iterator; + /** \brief specifies which version(s) will be returned if non is given */ + enum Version { + /** All versions */ + ALL, + /** Candidate and installed version */ + CANDANDINST, + /** Candidate version */ + CANDIDATE, + /** Installed version */ + INSTALLED, + /** Candidate or if non installed version */ + CANDINST, + /** Installed or if non candidate version */ + INSTCAND, + /** Newest version */ + NEWEST + }; + + /** \brief returns all versions specified on the commandline + + Get all versions from the commandline, uses given default version if + non specifically requested and executes regex's if needed on names. + \param Cache the packages and versions are in + \param cmdline Command line the versions should be extracted from + \param out stream to print various notices to */ + static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, + APT::VersionSet::Version const &fallback, std::ostream &out); + static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, + APT::VersionSet::Version const &fallback) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::VersionSet::FromCommandLine(Cache, cmdline, fallback, out); + } + static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { + return APT::VersionSet::FromCommandLine(Cache, cmdline, CANDINST); + } + /*}}}*/ +protected: /*{{{*/ + + /** \brief returns the candidate version of the package + + \param Cache to be used to query for information + \param Pkg we want the candidate version from this package + \param AllowError add an error to the stack if not */ + static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, bool const &AllowError = false); + + /** \brief returns the installed version of the package + + \param Cache to be used to query for information + \param Pkg we want the installed version from this package + \param AllowError add an error to the stack if not */ + static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, bool const &AllowError = false); + /*}}}*/ }; /*}}}*/ } -- cgit v1.2.3 From 9f1f17ccd4f84c23410ae62911c85f5836c3b503 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 5 Jun 2010 13:09:18 +0200 Subject: Don't increase the commandline parameter in the library but in the application to be really generic. --- apt-pkg/cacheset.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index 7372c909e..5dbd1a4df 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -79,7 +79,7 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std:: // FromCommandLine - Return all packages specified on commandline /*{{{*/ PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out) { PackageSet pkgset; - for (const char **I = cmdline + 1; *I != 0; I++) { + for (const char **I = cmdline; *I != 0; ++I) { PackageSet pset = FromString(Cache, *I, out); pkgset.insert(pset.begin(), pset.end()); } @@ -105,7 +105,7 @@ PackageSet PackageSet::FromString(pkgCacheFile &Cache, const char * const str, s APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, APT::VersionSet::Version const &fallback, std::ostream &out) { VersionSet verset; - for (const char **I = cmdline + 1; *I != 0; I++) { + for (const char **I = cmdline; *I != 0; ++I) { std::string pkg = *I; std::string ver; bool verIsRel = false; -- cgit v1.2.3 From c45f2d1995a58c7a5a8616c6fbf9f95ee4ccfd49 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 5 Jun 2010 13:38:17 +0200 Subject: do not insert end() Iterators into the CacheSet even if requested --- apt-pkg/cacheset.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index 708531b4a..b65e053e6 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -61,6 +61,9 @@ public: /*{{{*/ // 103. set::iterator is required to be modifiable, but this allows modification of keys typedef typename APT::PackageSet::const_iterator iterator; + using std::set::insert; + inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set::insert(P); }; + /** \brief returns all packages in the cache whose name matchs a given pattern A simple helper responsible for executing a regular expression on all @@ -145,6 +148,9 @@ public: /*{{{*/ // 103. set::iterator is required to be modifiable, but this allows modification of keys typedef typename APT::VersionSet::const_iterator iterator; + using std::set::insert; + inline void insert(pkgCache::VerIterator const &V) { if (V.end() == false) std::set::insert(V); }; + /** \brief specifies which version(s) will be returned if non is given */ enum Version { /** All versions */ -- cgit v1.2.3 From fe870febbfc1145d4a2a6b86985b0253419d52a8 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 5 Jun 2010 15:47:16 +0200 Subject: handle :arch modifier in PackageSet::FromString correctly --- apt-pkg/cacheset.cc | 26 ++++++++++++++++++++------ apt-pkg/cacheset.h | 4 ++-- 2 files changed, 22 insertions(+), 8 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index 5dbd1a4df..8fcffaf9a 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -87,17 +87,31 @@ PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline } /*}}}*/ // FromString - Return all packages matching a specific string /*{{{*/ -PackageSet PackageSet::FromString(pkgCacheFile &Cache, const char * const str, std::ostream &out) { - pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(str); - if (Grp.end() == false) { - pkgCache::PkgIterator Pkg = Grp.FindPreferredPkg(); +PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, std::ostream &out) { + std::string pkg = str; + size_t archfound = pkg.find_last_of(':'); + std::string arch; + if (archfound != std::string::npos) { + arch = pkg.substr(archfound+1); + pkg.erase(archfound); + } + + pkgCache::PkgIterator Pkg; + if (arch.empty() == true) { + pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(pkg); + if (Grp.end() == false) + Pkg = Grp.FindPreferredPkg(); + } else + Pkg = Cache.GetPkgCache()->FindPkg(pkg, arch); + + if (Pkg.end() == false) { PackageSet pkgset; pkgset.insert(Pkg); return pkgset; } PackageSet regex = FromRegEx(Cache, str, out); if (regex.empty() == true) - _error->Warning(_("Unable to locate package %s"), str); + _error->Warning(_("Unable to locate package %s"), str.c_str()); return regex; } /*}}}*/ @@ -188,7 +202,7 @@ pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, bool const &AllowError) { if (unlikely(Cache.BuildDepCache() == false)) return pkgCache::VerIterator(*Cache); - pkgCache::VerIterator Cand = Cache[Pkg].InstVerIter(Cache); + pkgCache::VerIterator Cand = Cache[Pkg].CandidateVerIter(Cache); if (AllowError == false && Cand.end() == true) _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str()); return Cand; diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index b65e053e6..4f7be4caa 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -83,8 +83,8 @@ public: /*{{{*/ \param Cache the packages are in \param string String the package name(s) should be extracted from \param out stream to print various notices to */ - static APT::PackageSet FromString(pkgCacheFile &Cache, const char * const string, std::ostream &out); - static APT::PackageSet FromString(pkgCacheFile &Cache, const char * const string) { + static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, std::ostream &out); + static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string) { std::ostream out (std::ofstream("/dev/null").rdbuf()); return APT::PackageSet::FromString(Cache, string, out); } -- cgit v1.2.3 From 84910ad5090b8cffc81d7942497ca09cc5d93244 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 5 Jun 2010 18:00:00 +0200 Subject: support special release-modifier 'installed' and 'candidate' --- apt-pkg/cacheset.cc | 126 ++++++++++++++++++++++++++++++++-------------------- apt-pkg/cacheset.h | 5 +++ 2 files changed, 82 insertions(+), 49 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index 8fcffaf9a..c0b06ba32 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -132,10 +132,19 @@ APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cm PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), out); for (PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P) { - if (vertag != string::npos) { + if (vertag == string::npos) { + AddSelectedVersion(Cache, verset, P, fallback); + continue; + } + pkgCache::VerIterator V; + if (ver == "installed") + V = getInstalledVer(Cache, P); + else if (ver == "candidate") + V = getCandidateVer(Cache, P); + else { pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release : - pkgVersionMatch::Version)); - pkgCache::VerIterator V = Match.Find(P); + pkgVersionMatch::Version)); + V = Match.Find(P); if (V.end() == true) { if (verIsRel == true) _error->Error(_("Release '%s' for '%s' was not found"), @@ -145,58 +154,77 @@ APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cm ver.c_str(), P.FullName(true).c_str()); continue; } - if (strcmp(ver.c_str(), V.VerStr()) != 0) - ioprintf(out, _("Selected version %s (%s) for %s\n"), - V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); - verset.insert(V); - } else { - pkgCache::VerIterator V; - switch(fallback) { - case VersionSet::ALL: - for (V = P.VersionList(); V.end() != true; ++V) - verset.insert(V); - break; - case VersionSet::CANDANDINST: - verset.insert(getInstalledVer(Cache, P)); - verset.insert(getCandidateVer(Cache, P)); - break; - case VersionSet::CANDIDATE: - verset.insert(getCandidateVer(Cache, P)); - break; - case VersionSet::INSTALLED: - verset.insert(getInstalledVer(Cache, P)); - break; - case VersionSet::CANDINST: - V = getCandidateVer(Cache, P, true); - if (V.end() == true) - V = getInstalledVer(Cache, P, true); - if (V.end() == false) - verset.insert(V); - else - _error->Error(_("Can't select installed nor candidate version from package %s as it has neither of them"), P.FullName(true).c_str()); - break; - case VersionSet::INSTCAND: - V = getInstalledVer(Cache, P, true); - if (V.end() == true) - V = getCandidateVer(Cache, P, true); - if (V.end() == false) - verset.insert(V); - else - _error->Error(_("Can't select installed nor candidate version from package %s as it has neither of them"), P.FullName(true).c_str()); - break; - case VersionSet::NEWEST: - if (P->VersionList != 0) - verset.insert(P.VersionList()); - else - _error->Error(_("Can't select newest version from package %s as it is purely virtual"), P.FullName(true).c_str()); - break; - } } + if (V.end() == true) + continue; + if (ver == V.VerStr()) + ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), + V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); + verset.insert(V); } } return verset; } /*}}}*/ +// AddSelectedVersion - add version from package based on fallback /*{{{*/ +bool VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, + pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, + bool const &AllowError) { + pkgCache::VerIterator V; + switch(fallback) { + case VersionSet::ALL: + if (P->VersionList != 0) + for (V = P.VersionList(); V.end() != true; ++V) + verset.insert(V); + else if (AllowError == false) + return _error->Error(_("Can't select versions from package '%s' as it purely virtual"), P.FullName(true).c_str()); + else + return false; + break; + case VersionSet::CANDANDINST: + verset.insert(getInstalledVer(Cache, P, AllowError)); + verset.insert(getCandidateVer(Cache, P, AllowError)); + break; + case VersionSet::CANDIDATE: + verset.insert(getCandidateVer(Cache, P, AllowError)); + break; + case VersionSet::INSTALLED: + verset.insert(getInstalledVer(Cache, P, AllowError)); + break; + case VersionSet::CANDINST: + V = getCandidateVer(Cache, P, true); + if (V.end() == true) + V = getInstalledVer(Cache, P, true); + if (V.end() == false) + verset.insert(V); + else if (AllowError == false) + return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str()); + else + return false; + break; + case VersionSet::INSTCAND: + V = getInstalledVer(Cache, P, true); + if (V.end() == true) + V = getCandidateVer(Cache, P, true); + if (V.end() == false) + verset.insert(V); + else if (AllowError == false) + return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str()); + else + return false; + break; + case VersionSet::NEWEST: + if (P->VersionList != 0) + verset.insert(P.VersionList()); + else if (AllowError == false) + return _error->Error(_("Can't select newest version from package '%s' as it is purely virtual"), P.FullName(true).c_str()); + else + return false; + break; + } + return true; +} + /*}}}*/ // getCandidateVer - Returns the candidate version of the given package /*{{{*/ pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, bool const &AllowError) { diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index 4f7be4caa..0f3a87a3d 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -205,6 +205,11 @@ protected: /*{{{*/ static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, bool const &AllowError = false); + + static bool AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, + pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, + bool const &AllowError = false); + /*}}}*/ }; /*}}}*/ } -- cgit v1.2.3 From 9cc83a6fbc089ccf9cb8d52ee9f380cf5df62d5c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 6 Jun 2010 21:41:27 +0200 Subject: add a GroupedFromCommandLine method to the PackageSet to split the packages on the commandline into groups based on modifiers --- apt-pkg/cacheset.cc | 33 +++++++++++++++++++++++++++++++++ apt-pkg/cacheset.h | 23 +++++++++++++++++++++++ 2 files changed, 56 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index c0b06ba32..43ade4b4e 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -76,6 +76,39 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std:: return pkgset; } /*}}}*/ +// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ +std::map PackageSet::GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, std::ostream &out) { + std::map pkgsets; + for (const char **I = cmdline; *I != 0; ++I) { + unsigned short modID = fallback; + std::string str = *I; + for (std::list::const_iterator mod = mods.begin(); + mod != mods.end(); ++mod) { + size_t const alength = strlen(mod->Alias); + switch(mod->Pos) { + case PackageSet::Modifier::POSTFIX: + if (str.compare(str.length() - alength, alength, + mod->Alias, 0, alength) != 0) + continue; + str.erase(str.length() - alength); + modID = mod->ID; + break; + case PackageSet::Modifier::PREFIX: + continue; + case PackageSet::Modifier::NONE: + continue; + } + break; + } + PackageSet pset = PackageSet::FromString(Cache, str, out); + pkgsets[modID].insert(pset.begin(), pset.end()); + } + return pkgsets; +} + /*}}}*/ // FromCommandLine - Return all packages specified on commandline /*{{{*/ PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out) { PackageSet pkgset; diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index 0f3a87a3d..c9d121083 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -11,6 +11,8 @@ // Include Files /*{{{*/ #include #include +#include +#include #include #include @@ -101,6 +103,27 @@ public: /*{{{*/ std::ostream out (std::ofstream("/dev/null").rdbuf()); return APT::PackageSet::FromCommandLine(Cache, cmdline, out); } + + struct Modifier { + enum Position { NONE, PREFIX, POSTFIX }; + unsigned short ID; + const char * const Alias; + Position Pos; + Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {}; + }; + + static std::map GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, std::ostream &out); + static std::map GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::PackageSet::GroupedFromCommandLine(Cache, cmdline, + mods, fallback, out); + } /*}}}*/ }; /*}}}*/ class VersionSet : public std::set { /*{{{*/ -- cgit v1.2.3 From 1ddb859611d2e0f3d9ea12085001810f689e8c99 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 8 Jun 2010 19:27:49 +0200 Subject: * apt-pkg/indexrecords.cc: - backport forgotten Valid-Until patch from the obsolete experimental branch to prevent replay attacks better, thanks to Thomas Viehmann for the initial patch! (Closes: #499897) --- apt-pkg/acquire-item.cc | 12 +++++++++++- apt-pkg/indexrecords.cc | 38 ++++++++++++++++++++++++++++++++++++-- apt-pkg/indexrecords.h | 4 ++++ 3 files changed, 51 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index c035b9163..4a846804e 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -33,6 +33,7 @@ #include #include #include +#include /*}}}*/ using namespace std; @@ -1177,6 +1178,15 @@ bool pkgAcqMetaIndex::VerifyVendor(string Message) /*{{{*/ Transformed = ""; } + if (_config->FindB("Acquire::Check-Valid-Until", true)) { + if (MetaIndexParser->GetValidUntil() > 0 && + time(NULL) > MetaIndexParser->GetValidUntil()) { + return _error->Error(_("Release file expired, ignoring %s (valid until %s)"), + RealURI.c_str(), + TimeRFC1123(MetaIndexParser->GetValidUntil()).c_str()); + } + } + if (_config->FindB("Debug::pkgAcquire::Auth", false)) { std::cerr << "Got Codename: " << MetaIndexParser->GetDist() << std::endl; @@ -1194,7 +1204,7 @@ bool pkgAcqMetaIndex::VerifyVendor(string Message) /*{{{*/ // return false; if (!Transformed.empty()) { - _error->Warning("Conflicting distribution: %s (expected %s but got %s)", + _error->Warning(_("Conflicting distribution: %s (expected %s but got %s)"), Desc.Description.c_str(), Transformed.c_str(), MetaIndexParser->GetDist().c_str()); diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc index 1fc27b1a1..24ed02ba5 100644 --- a/apt-pkg/indexrecords.cc +++ b/apt-pkg/indexrecords.cc @@ -7,8 +7,11 @@ #include #include #include +#include #include #include +#include + /*}}}*/ string indexRecords::GetDist() const { @@ -26,6 +29,11 @@ string indexRecords::GetExpectedDist() const return this->ExpectedDist; } +time_t indexRecords::GetValidUntil() const +{ + return this->ValidUntil; +} + const indexRecords::checkSum *indexRecords::Lookup(const string MetaKey) { return Entries[MetaKey]; @@ -82,7 +90,33 @@ bool indexRecords::Load(const string Filename) /*{{{*/ return false; } - string Strdate = Section.FindS("Date"); // FIXME: verify this somehow? + string Label = Section.FindS("Label"); + string StrDate = Section.FindS("Date"); + string StrValidUntil = Section.FindS("Valid-Until"); + + // if we have a Valid-Until header, use it + if (!StrValidUntil.empty()) + { + // set ValidUntil based on the information in the Release file + if(!StrToTime(StrValidUntil, ValidUntil)) + { + ErrorText = _(("Invalid 'Valid-Until' entry in Release file " + Filename).c_str()); + return false; + } + } else { + // if we don't have a valid-until string, check if we have a default + if (!Label.empty()) + { + int MaxAge = _config->FindI(string("apt::acquire::max-default-age::"+Label).c_str(),0); + if(MaxAge > 0 && !StrToTime(StrDate, ValidUntil)) + { + ErrorText = _(("Invalid 'Date' entry in Release file " + Filename).c_str()); + return false; + } + ValidUntil += 24*60*60*MaxAge; + } + } + return true; } /*}}}*/ @@ -160,6 +194,6 @@ indexRecords::indexRecords() } indexRecords::indexRecords(const string ExpectedDist) : - ExpectedDist(ExpectedDist) + ExpectedDist(ExpectedDist), ValidUntil(0) { } diff --git a/apt-pkg/indexrecords.h b/apt-pkg/indexrecords.h index 468d2bd0f..500cf23c4 100644 --- a/apt-pkg/indexrecords.h +++ b/apt-pkg/indexrecords.h @@ -12,6 +12,7 @@ #include #include +#include class indexRecords { @@ -25,6 +26,8 @@ class indexRecords string Dist; string Suite; string ExpectedDist; + time_t ValidUntil; + std::map Entries; public: @@ -38,6 +41,7 @@ class indexRecords virtual bool Load(string Filename); string GetDist() const; + time_t GetValidUntil() const; virtual bool CheckDist(const string MaybeDist) const; string GetExpectedDist() const; virtual ~indexRecords(){}; -- cgit v1.2.3 From cd8cf88f0e64e222e9fdcbf86e6cbbe09306040e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 8 Jun 2010 22:46:42 +0200 Subject: * apt-pkg/contrib/strutl.cc: - split StrToTime() into HTTP1.1 and FTP date parser methods and use strptime() instead of some selfmade scanf mangling --- apt-pkg/contrib/strutl.cc | 36 ++++++++++++++++++++++++++++++++++++ apt-pkg/contrib/strutl.h | 4 +++- 2 files changed, 39 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index c7d63ce8a..96e8143ec 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -855,6 +855,42 @@ static time_t timegm(struct tm *t) } #endif /*}}}*/ +// FullDateToTime - Converts a HTTP1.1 full date strings into a time_t /*{{{*/ +// --------------------------------------------------------------------- +/* tries to parses a full date as specified in RFC2616 Section 3.3.1 + with one exception: All timezones (%Z) are accepted but the protocol + says that it MUST be GMT, but this one is equal to UTC which we will + encounter from time to time (e.g. in Release files) so we accept all + here and just assume it is GMT (or UTC) later on */ +bool RFC1123StrToTime(const char* const str,time_t &time) +{ + struct tm Tm; + // Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 + if (strptime(str, "%a, %d %b %Y %H:%M:%S %Z", &Tm) == NULL && + // Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 + strptime(str, "%A, %d-%b-%y %H:%M:%S %Z", &Tm) == NULL && + // Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format + strptime(str, "%a %b %d %H:%M:%S %Y", &Tm) == NULL) + return false; + + time = timegm(&Tm); + return true; +} + /*}}}*/ +// FTPMDTMStrToTime - Converts a ftp modification date into a time_t /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool FTPMDTMStrToTime(const char* const str,time_t &time) +{ + struct tm Tm; + // MDTM includes no whitespaces but recommend and ignored by strptime + if (strptime(str, "%Y %m %d %H %M %S", &Tm) == NULL) + return false; + + time = timegm(&Tm); + return true; +} + /*}}}*/ // StrToTime - Converts a string into a time_t /*{{{*/ // --------------------------------------------------------------------- /* This handles all 3 populare time formats including RFC 1123, RFC 1036 diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index e509145f9..b5de0802e 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -45,7 +45,9 @@ string Base64Encode(const string &Str); string OutputInDepth(const unsigned long Depth, const char* Separator=" "); string URItoFileName(const string &URI); string TimeRFC1123(time_t Date); -bool StrToTime(const string &Val,time_t &Result); +bool RFC1123StrToTime(const char* const str,time_t &time) __attrib_const; +bool FTPMDTMStrToTime(const char* const str,time_t &time) __attrib_const; +__deprecated bool StrToTime(const string &Val,time_t &Result); string LookupTag(const string &Message,const char *Tag,const char *Default = 0); int StringToBool(const string &Text,int Default = -1); bool ReadMessages(int Fd, vector &List); -- cgit v1.2.3 From 0323317c08c0b08bf0ba1ac37a37a8de333cdb40 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 8 Jun 2010 22:55:42 +0200 Subject: enhance the Valid-Until code a bit by using the correct RFC1123StrToTime method and allow for better translations of the error messages --- apt-pkg/acquire-item.cc | 16 +++++++++------- apt-pkg/indexrecords.cc | 24 ++++++++++++------------ 2 files changed, 21 insertions(+), 19 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 4a846804e..ac84c2e5e 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -1178,13 +1178,15 @@ bool pkgAcqMetaIndex::VerifyVendor(string Message) /*{{{*/ Transformed = ""; } - if (_config->FindB("Acquire::Check-Valid-Until", true)) { - if (MetaIndexParser->GetValidUntil() > 0 && - time(NULL) > MetaIndexParser->GetValidUntil()) { - return _error->Error(_("Release file expired, ignoring %s (valid until %s)"), - RealURI.c_str(), - TimeRFC1123(MetaIndexParser->GetValidUntil()).c_str()); - } + if (_config->FindB("Acquire::Check-Valid-Until", true) == true && + MetaIndexParser->GetValidUntil() > 0) { + time_t const invalid_since = time(NULL) - MetaIndexParser->GetValidUntil(); + if (invalid_since > 0) + // TRANSLATOR: The first %s is the URL of the bad Release file, the second is + // the time since then the file is invalid - formated in the same way as in + // the download progress display (e.g. 7d 3h 42min 1s) + return _error->Error(_("Release file expired, ignoring %s (invalid since %s)"), + RealURI.c_str(), TimeToStr(invalid_since).c_str()); } if (_config->FindB("Debug::pkgAcquire::Auth", false)) diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc index 24ed02ba5..1312e6818 100644 --- a/apt-pkg/indexrecords.cc +++ b/apt-pkg/indexrecords.cc @@ -91,30 +91,30 @@ bool indexRecords::Load(const string Filename) /*{{{*/ } string Label = Section.FindS("Label"); - string StrDate = Section.FindS("Date"); + string StrDate = Section.FindS("Date"); string StrValidUntil = Section.FindS("Valid-Until"); // if we have a Valid-Until header, use it - if (!StrValidUntil.empty()) + if (StrValidUntil.empty() == false) { // set ValidUntil based on the information in the Release file - if(!StrToTime(StrValidUntil, ValidUntil)) + if(RFC1123StrToTime(StrValidUntil.c_str(), ValidUntil) == false) { - ErrorText = _(("Invalid 'Valid-Until' entry in Release file " + Filename).c_str()); + strprintf(ErrorText, _("Invalid 'Valid-Until' entry in Release file %s"), Filename.c_str()); return false; } } else { // if we don't have a valid-until string, check if we have a default - if (!Label.empty()) + int MaxAge = _config->FindI("APT::Acquire::Max-Default-Age", 0); + if (Label.empty() == true) + MaxAge = _config->FindI(string("APT::Acquire::Max-Default-Age::"+Label).c_str(), MaxAge); + + if(MaxAge > 0 && RFC1123StrToTime(StrDate.c_str(), ValidUntil) == false) { - int MaxAge = _config->FindI(string("apt::acquire::max-default-age::"+Label).c_str(),0); - if(MaxAge > 0 && !StrToTime(StrDate, ValidUntil)) - { - ErrorText = _(("Invalid 'Date' entry in Release file " + Filename).c_str()); - return false; - } - ValidUntil += 24*60*60*MaxAge; + strprintf(ErrorText, _("Invalid 'Date' entry in Release file %s"), Filename.c_str()); + return false; } + ValidUntil += 24*60*60*MaxAge; } return true; -- cgit v1.2.3 From bbde96a611f39f5040b332dae1515207db341743 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 8 Jun 2010 23:38:34 +0200 Subject: use the Valid-Until header from the Release file but if the user provides a setting in the configuration prefer the date which is earlier. --- apt-pkg/indexrecords.cc | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc index 1312e6818..cdc2897bf 100644 --- a/apt-pkg/indexrecords.cc +++ b/apt-pkg/indexrecords.cc @@ -88,34 +88,39 @@ bool indexRecords::Load(const string Filename) /*{{{*/ { strprintf(ErrorText, _("No Hash entry in Release file %s"), Filename.c_str()); return false; - } + } string Label = Section.FindS("Label"); string StrDate = Section.FindS("Date"); string StrValidUntil = Section.FindS("Valid-Until"); - // if we have a Valid-Until header, use it + // if we have a Valid-Until header in the Release file, use it as default if (StrValidUntil.empty() == false) { - // set ValidUntil based on the information in the Release file if(RFC1123StrToTime(StrValidUntil.c_str(), ValidUntil) == false) { strprintf(ErrorText, _("Invalid 'Valid-Until' entry in Release file %s"), Filename.c_str()); return false; } - } else { - // if we don't have a valid-until string, check if we have a default - int MaxAge = _config->FindI("APT::Acquire::Max-Default-Age", 0); - if (Label.empty() == true) - MaxAge = _config->FindI(string("APT::Acquire::Max-Default-Age::"+Label).c_str(), MaxAge); + } + // get the user settings for this archive and use what expires earlier + int MaxAge = _config->FindI("APT::Acquire::Max-Default-Age", 0); + if (Label.empty() == true) + MaxAge = _config->FindI(string("APT::Acquire::Max-Default-Age::" + Label).c_str(), MaxAge); - if(MaxAge > 0 && RFC1123StrToTime(StrDate.c_str(), ValidUntil) == false) - { - strprintf(ErrorText, _("Invalid 'Date' entry in Release file %s"), Filename.c_str()); - return false; - } - ValidUntil += 24*60*60*MaxAge; + if(MaxAge == 0) // No user settings, use the one from the Release file + return true; + + time_t date; + if (RFC1123StrToTime(StrDate.c_str(), date) == false) + { + strprintf(ErrorText, _("Invalid 'Date' entry in Release file %s"), Filename.c_str()); + return false; } + date += 24*60*60*MaxAge; + + if (ValidUntil == 0 || ValidUntil > date) + ValidUntil = date; return true; } -- cgit v1.2.3 From 550891457ff63db01b57d9057a5fe447a165e10c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 9 Jun 2010 00:27:22 +0200 Subject: use the portable timegm shown in his manpage instead of a strange looking code copycat from wget --- apt-pkg/contrib/strutl.cc | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 96e8143ec..160450366 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -827,31 +827,27 @@ static int MonthConv(char *Month) } } /*}}}*/ -// timegm - Internal timegm function if gnu is not available /*{{{*/ +// timegm - Internal timegm if the gnu version is not available /*{{{*/ // --------------------------------------------------------------------- -/* Ripped this evil little function from wget - I prefer the use of - GNU timegm if possible as this technique will have interesting problems - with leap seconds, timezones and other. - - Converts struct tm to time_t, assuming the data in tm is UTC rather +/* Converts struct tm to time_t, assuming the data in tm is UTC rather than local timezone (mktime assumes the latter). - - Contributed by Roger Beeman , with the help of - Mark Baushke and the rest of the Gurus at CISCO. */ - -/* Turned it into an autoconf check, because GNU is not the only thing which - can provide timegm. -- 2002-09-22, Joel Baker */ -#ifndef HAVE_TIMEGM // Now with autoconf! + This function is a nonstandard GNU extension that is also present on + the BSDs and maybe other systems. For others we follow the advice of + the manpage of timegm and use his portable replacement. */ +#ifndef HAVE_TIMEGM static time_t timegm(struct tm *t) { - time_t tl, tb; - - tl = mktime (t); - if (tl == -1) - return -1; - tb = mktime (gmtime (&tl)); - return (tl <= tb ? (tl + (tl - tb)) : (tl - (tb - tl))); + char *tz = getenv("TZ"); + setenv("TZ", "", 1); + tzset(); + time_t ret = mktime(t); + if (tz) + setenv("TZ", tz, 1); + else + unsetenv("TZ"); + tzset(); + return ret; } #endif /*}}}*/ -- cgit v1.2.3 From 96cc64a521957d63704de72ed95f1c839698c53c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 9 Jun 2010 00:53:44 +0200 Subject: move the users away from the deprecated StrToTime() method --- apt-pkg/acquire-method.cc | 2 +- apt-pkg/contrib/strutl.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-method.cc b/apt-pkg/acquire-method.cc index fe066741c..b82dceecb 100644 --- a/apt-pkg/acquire-method.cc +++ b/apt-pkg/acquire-method.cc @@ -373,7 +373,7 @@ int pkgAcqMethod::Run(bool Single) Tmp->Uri = LookupTag(Message,"URI"); Tmp->DestFile = LookupTag(Message,"FileName"); - if (StrToTime(LookupTag(Message,"Last-Modified"),Tmp->LastModified) == false) + if (RFC1123StrToTime(LookupTag(Message,"Last-Modified").c_str(),Tmp->LastModified) == false) Tmp->LastModified = 0; Tmp->IndexFile = StringToBool(LookupTag(Message,"Index-File"),false); Tmp->Next = 0; diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index b5de0802e..a457ff047 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -45,8 +45,8 @@ string Base64Encode(const string &Str); string OutputInDepth(const unsigned long Depth, const char* Separator=" "); string URItoFileName(const string &URI); string TimeRFC1123(time_t Date); -bool RFC1123StrToTime(const char* const str,time_t &time) __attrib_const; -bool FTPMDTMStrToTime(const char* const str,time_t &time) __attrib_const; +bool RFC1123StrToTime(const char* const str,time_t &time) __must_check; +bool FTPMDTMStrToTime(const char* const str,time_t &time) __must_check; __deprecated bool StrToTime(const string &Val,time_t &Result); string LookupTag(const string &Message,const char *Tag,const char *Default = 0); int StringToBool(const string &Text,int Default = -1); -- cgit v1.2.3 From b02fffa64833e1f8e2617669d89de0a6d0882747 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 9 Jun 2010 10:46:35 +0200 Subject: rename the options, document them and reorder the changelog a bit --- apt-pkg/indexrecords.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc index cdc2897bf..3bde7437d 100644 --- a/apt-pkg/indexrecords.cc +++ b/apt-pkg/indexrecords.cc @@ -104,9 +104,9 @@ bool indexRecords::Load(const string Filename) /*{{{*/ } } // get the user settings for this archive and use what expires earlier - int MaxAge = _config->FindI("APT::Acquire::Max-Default-Age", 0); + int MaxAge = _config->FindI("Acquire::Max-ValidTime", 0); if (Label.empty() == true) - MaxAge = _config->FindI(string("APT::Acquire::Max-Default-Age::" + Label).c_str(), MaxAge); + MaxAge = _config->FindI(string("Acquire::Max-ValidTime::" + Label).c_str(), MaxAge); if(MaxAge == 0) // No user settings, use the one from the Release file return true; -- cgit v1.2.3 From a3a03f5d7436c870edac9c0eb92e85e1fcaf6bca Mon Sep 17 00:00:00 2001 From: "martin@piware.de" <> Date: Wed, 9 Jun 2010 14:08:20 +0200 Subject: * apt-pkg/contrib/fileutl.{h,cc}: - Add support for transparent reading of gzipped files. - Link against zlib (in apt-pkg/makefile) and add zlib build dependency. --- apt-pkg/contrib/fileutl.cc | 47 ++++++++++++++++++++++++++++++++++++++++------ apt-pkg/contrib/fileutl.h | 9 ++++++--- apt-pkg/makefile | 2 +- 3 files changed, 48 insertions(+), 10 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index da32983f1..11a9e7f7b 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -11,6 +11,7 @@ Most of this source is placed in the Public Domain, do with it what you will It was originally written by Jason Gunthorpe . + FileFd gzip support added by Martin Pitt The exception is RunScripts() it is under the GPLv2 @@ -603,6 +604,13 @@ bool FileFd::Open(string FileName,OpenMode Mode, unsigned long Perms) { case ReadOnly: iFd = open(FileName.c_str(),O_RDONLY); + if (iFd > 0 && FileName.compare(FileName.size()-3, 3, ".gz") == 0) { + gz = gzdopen (iFd, "r"); + if (gz == NULL) { + close (iFd); + iFd = -1; + } + } break; case WriteEmpty: @@ -658,7 +666,10 @@ bool FileFd::Read(void *To,unsigned long Size,unsigned long *Actual) do { - Res = read(iFd,To,Size); + if (gz != NULL) + Res = gzread(gz,To,Size); + else + Res = read(iFd,To,Size); if (Res < 0 && errno == EINTR) continue; if (Res < 0) @@ -697,7 +708,10 @@ bool FileFd::Write(const void *From,unsigned long Size) errno = 0; do { - Res = write(iFd,From,Size); + if (gz != NULL) + Res = gzwrite(gz,From,Size); + else + Res = write(iFd,From,Size); if (Res < 0 && errno == EINTR) continue; if (Res < 0) @@ -723,7 +737,12 @@ bool FileFd::Write(const void *From,unsigned long Size) /* */ bool FileFd::Seek(unsigned long To) { - if (lseek(iFd,To,SEEK_SET) != (signed)To) + int res; + if (gz) + res = gzseek(gz,To,SEEK_SET); + else + res = lseek(iFd,To,SEEK_SET); + if (res != (signed)To) { Flags |= Fail; return _error->Error("Unable to seek to %lu",To); @@ -737,7 +756,12 @@ bool FileFd::Seek(unsigned long To) /* */ bool FileFd::Skip(unsigned long Over) { - if (lseek(iFd,Over,SEEK_CUR) < 0) + int res; + if (gz) + res = gzseek(gz,Over,SEEK_CUR); + else + res = lseek(iFd,Over,SEEK_CUR); + if (res < 0) { Flags |= Fail; return _error->Error("Unable to seek ahead %lu",Over); @@ -751,6 +775,11 @@ bool FileFd::Skip(unsigned long Over) /* */ bool FileFd::Truncate(unsigned long To) { + if (gz) + { + Flags |= Fail; + return _error->Error("Truncating gzipped files is not implemented (%s)", FileName.c_str()); + } if (ftruncate(iFd,To) != 0) { Flags |= Fail; @@ -765,7 +794,11 @@ bool FileFd::Truncate(unsigned long To) /* */ unsigned long FileFd::Tell() { - off_t Res = lseek(iFd,0,SEEK_CUR); + off_t Res; + if (gz) + Res = gztell(gz); + else + Res = lseek(iFd,0,SEEK_CUR); if (Res == (off_t)-1) _error->Errno("lseek","Failed to determine the current file position"); return Res; @@ -776,6 +809,7 @@ unsigned long FileFd::Tell() /* */ unsigned long FileFd::Size() { + //TODO: For gz, do we need the actual file size here or the uncompressed length? struct stat Buf; if (fstat(iFd,&Buf) != 0) return _error->Errno("fstat","Unable to determine the file size"); @@ -789,9 +823,10 @@ bool FileFd::Close() { bool Res = true; if ((Flags & AutoClose) == AutoClose) - if (iFd >= 0 && close(iFd) != 0) + if ((gz != NULL && gzclose(gz) != 0) || (gz == NULL && iFd > 0 && close(iFd) != 0)) Res &= _error->Errno("close",_("Problem closing the file")); iFd = -1; + gz = NULL; if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail && FileName.empty() == false) diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 85a94898c..9925bbed4 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -25,6 +25,8 @@ #include #include +#include + using std::string; class FileFd @@ -36,6 +38,7 @@ class FileFd HitEof = (1<<3)}; unsigned long Flags; string FileName; + gzFile gz; public: enum OpenMode {ReadOnly,WriteEmpty,WriteExists,WriteAny,WriteTemp}; @@ -69,12 +72,12 @@ class FileFd inline string &Name() {return FileName;}; FileFd(string FileName,OpenMode Mode,unsigned long Perms = 0666) : iFd(-1), - Flags(0) + Flags(0), gz(NULL) { Open(FileName,Mode,Perms); }; - FileFd(int Fd = -1) : iFd(Fd), Flags(AutoClose) {}; - FileFd(int Fd,bool) : iFd(Fd), Flags(0) {}; + FileFd(int Fd = -1) : iFd(Fd), Flags(AutoClose), gz(NULL) {}; + FileFd(int Fd,bool) : iFd(Fd), Flags(0), gz(NULL) {}; virtual ~FileFd(); }; diff --git a/apt-pkg/makefile b/apt-pkg/makefile index bdd49c089..4cf07f3a8 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -14,7 +14,7 @@ include ../buildlib/libversion.mak LIBRARY=apt-pkg MAJOR=$(LIBAPTPKG_MAJOR) MINOR=$(LIBAPTPKG_RELEASE) -SLIBS=$(PTHREADLIB) $(INTLLIBS) -lutil -ldl +SLIBS=$(PTHREADLIB) $(INTLLIBS) -lutil -ldl -lz APT_DOMAIN:=libapt-pkg$(LIBAPTPKG_MAJOR) # Source code for the contributed non-core things -- cgit v1.2.3 From ec7a129eeb1611ec097bc99a148d6d3a3dccf044 Mon Sep 17 00:00:00 2001 From: "martin@piware.de" <> Date: Wed, 9 Jun 2010 14:09:42 +0200 Subject: * apt-pkg/deb/debindexfile.cc: - If we do not find uncompressed package/source/translation indexes, look for gzip compressed ones. --- apt-pkg/deb/debindexfile.cc | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index 7379ca997..e87c21f13 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -106,8 +106,14 @@ string debSourcesIndex::Info(const char *Type) const /* */ inline string debSourcesIndex::IndexFile(const char *Type) const { - return URItoFileName(IndexURI(Type)); + string s = URItoFileName(IndexURI(Type)); + string sgzip = s + ".gz"; + if (!FileExists(s) && FileExists(sgzip)) + return sgzip; + else + return s; } + string debSourcesIndex::IndexURI(const char *Type) const { string Res; @@ -213,7 +219,12 @@ string debPackagesIndex::Info(const char *Type) const /* */ inline string debPackagesIndex::IndexFile(const char *Type) const { - return _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); + string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); + string sgzip = s + ".gz"; + if (!FileExists(s) && FileExists(sgzip)) + return sgzip; + else + return s; } string debPackagesIndex::IndexURI(const char *Type) const { @@ -340,7 +351,12 @@ debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section /* */ inline string debTranslationsIndex::IndexFile(const char *Type) const { - return _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); + string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); + string sgzip = s + ".gz"; + if (!FileExists(s) && FileExists(sgzip)) + return sgzip; + else + return s; } string debTranslationsIndex::IndexURI(const char *Type) const { -- cgit v1.2.3 From 6d052eba8cc67245b21d333ece2e76efb22f82db Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 9 Jun 2010 14:18:56 +0200 Subject: remove the "typename" from the const_iterators as gcc-4.4 doesn't like them and gcc-4.5 does the right thing (TM) with and without them --- apt-pkg/cacheset.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index c9d121083..668d8039e 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -61,7 +61,7 @@ public: /*{{{*/ }; }; // 103. set::iterator is required to be modifiable, but this allows modification of keys - typedef typename APT::PackageSet::const_iterator iterator; + typedef APT::PackageSet::const_iterator iterator; using std::set::insert; inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set::insert(P); }; @@ -169,7 +169,7 @@ public: /*{{{*/ inline pkgCache::VerFileIterator NewestFile() const { return (**this).NewestFile(); }; }; // 103. set::iterator is required to be modifiable, but this allows modification of keys - typedef typename APT::VersionSet::const_iterator iterator; + typedef APT::VersionSet::const_iterator iterator; using std::set::insert; inline void insert(pkgCache::VerIterator const &V) { if (V.end() == false) std::set::insert(V); }; -- cgit v1.2.3 From 9ee8287e5ea8a993fbb4c5beb8fe8bbddadfa7a0 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 9 Jun 2010 14:20:27 +0200 Subject: * apt-pkg/policy.cc: - get the candidate right for a not-installed pseudo package if his non-pseudo friend is installed --- apt-pkg/policy.cc | 32 +++++++++++++++++++++----------- apt-pkg/policy.h | 4 ++-- 2 files changed, 23 insertions(+), 13 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index 922efb0dd..a3286391b 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -115,7 +115,7 @@ bool pkgPolicy::InitDefaults() // --------------------------------------------------------------------- /* Evaluate the package pins and the default list to deteremine what the best package is. */ -pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator Pkg) +pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pkg) { // Look for a package pin and evaluate it. signed Max = GetPriority(Pkg); @@ -147,6 +147,16 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator Pkg) */ for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; Ver++) { + /* Lets see if this version is the installed version */ + bool instVer = (Pkg.CurrentVer() == Ver); + if (Ver.Pseudo() == true && instVer == false) + { + pkgCache::PkgIterator const allPkg = Ver.ParentPkg().Group().FindPkg("all"); + if (allPkg->CurrentVer != 0 && allPkg.CurrentVer()->Hash == Ver->Hash && + strcmp(allPkg.CurVersion(), Ver.VerStr()) == 0) + instVer = true; + } + for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false; VF++) { /* If this is the status file, and the current version is not the @@ -155,9 +165,9 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator Pkg) out bogus entries that may be due to config-file states, or other. */ if ((VF.File()->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource && - Pkg.CurrentVer() != Ver) + instVer == false) continue; - + signed Prio = PFPriority[VF.File()->ID]; if (Prio > Max) { @@ -171,7 +181,7 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator Pkg) } } - if (Pkg.CurrentVer() == Ver && Max < 1000) + if (instVer == true && Max < 1000) { /* Elevate our current selection (or the status file itself) to the Pseudo-status priority. */ @@ -189,6 +199,7 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator Pkg) // will always be a candidate (Closes: #512318) if (!Pref.IsGood() && MaxAlt > 0) Pref = PrefAlt; + return Pref; } /*}}}*/ @@ -238,15 +249,14 @@ void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name, // Policy::GetMatch - Get the matching version for a package pin /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgCache::VerIterator pkgPolicy::GetMatch(pkgCache::PkgIterator Pkg) +pkgCache::VerIterator pkgPolicy::GetMatch(pkgCache::PkgIterator const &Pkg) { const Pin &PPkg = Pins[Pkg->ID]; - if (PPkg.Type != pkgVersionMatch::None) - { - pkgVersionMatch Match(PPkg.Data,PPkg.Type); - return Match.Find(Pkg); - } - return pkgCache::VerIterator(*Pkg.Cache()); + if (PPkg.Type == pkgVersionMatch::None) + return pkgCache::VerIterator(*Pkg.Cache()); + + pkgVersionMatch Match(PPkg.Data,PPkg.Type); + return Match.Find(Pkg); } /*}}}*/ // Policy::GetPriority - Get the priority of the package pin /*{{{*/ diff --git a/apt-pkg/policy.h b/apt-pkg/policy.h index 4894682fa..28cb3ccbb 100644 --- a/apt-pkg/policy.h +++ b/apt-pkg/policy.h @@ -72,10 +72,10 @@ class pkgPolicy : public pkgDepCache::Policy inline signed short GetPriority(pkgCache::PkgFileIterator const &File) {return PFPriority[File->ID];}; signed short GetPriority(pkgCache::PkgIterator const &Pkg); - pkgCache::VerIterator GetMatch(pkgCache::PkgIterator Pkg); + pkgCache::VerIterator GetMatch(pkgCache::PkgIterator const &Pkg); // Things for the cache interface. - virtual pkgCache::VerIterator GetCandidateVer(pkgCache::PkgIterator Pkg); + virtual pkgCache::VerIterator GetCandidateVer(pkgCache::PkgIterator const &Pkg); virtual bool IsImportantDep(pkgCache::DepIterator Dep) {return pkgDepCache::Policy::IsImportantDep(Dep);}; bool InitDefaults(); -- cgit v1.2.3 From a319c4eeae62511d1cb58986742491d3e224bf20 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 9 Jun 2010 17:19:40 +0200 Subject: * apt-pkg/indexcopy.cc: - move the gpg codecopy to a new method and use it also in methods/gpgv.cc --- apt-pkg/indexcopy.cc | 109 +++++++++++++++++++++++++++++++++------------------ apt-pkg/indexcopy.h | 3 ++ 2 files changed, 73 insertions(+), 39 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc index 53eb11172..47eaefc5c 100644 --- a/apt-pkg/indexcopy.cc +++ b/apt-pkg/indexcopy.cc @@ -590,66 +590,39 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector &SigList, indexRecords *MetaIndex = new indexRecords; string prefix = *I; + string const releasegpg = *I+"Release.gpg"; + string const release = *I+"Release"; + // a Release.gpg without a Release should never happen - if(!FileExists(*I+"Release")) + if(FileExists(release) == false) { delete MetaIndex; continue; } - - // verify the gpg signature of "Release" - // gpg --verify "*I+Release.gpg", "*I+Release" - const char *Args[400]; - unsigned int i = 0; - - string gpgvpath = _config->Find("Dir::Bin::gpg", "/usr/bin/gpgv"); - string pubringpath = _config->Find("Apt::GPGV::TrustedKeyring", "/etc/apt/trusted.gpg"); - string releasegpg = *I+"Release.gpg"; - string release = *I+"Release"; - - Args[i++] = gpgvpath.c_str(); - Args[i++] = "--keyring"; - Args[i++] = pubringpath.c_str(); - Configuration::Item const *Opts; - Opts = _config->Tree("Acquire::gpgv::Options"); - if (Opts != 0) - { - Opts = Opts->Child; - for (; Opts != 0; Opts = Opts->Next) - { - if (Opts->Value.empty() == true) - continue; - Args[i++] = Opts->Value.c_str(); - if(i >= 390) { - _error->Error("Argument list from Acquire::gpgv::Options too long. Exiting."); - return false; - } - } - } - - Args[i++] = releasegpg.c_str(); - Args[i++] = release.c_str(); - Args[i++] = NULL; - pid_t pid = ExecFork(); if(pid < 0) { _error->Error("Fork failed"); return false; } if(pid == 0) { - execvp(gpgvpath.c_str(), (char**)Args); + string const gpgvpath = _config->Find("Dir::Bin::gpg", "/usr/bin/gpgv"); + std::vector Args = GetGPGVCommandLine(); + Args.push_back(releasegpg.c_str()); + Args.push_back(release.c_str()); + Args.push_back(NULL); + execvp(gpgvpath.c_str(), (char**) &Args[0]); } if(!ExecWait(pid, "gpgv")) { _error->Warning("Signature verification failed for: %s", - string(*I+"Release.gpg").c_str()); + releasegpg.c_str()); // something went wrong, don't copy the Release.gpg // FIXME: delete any existing gpg file? continue; } // Open the Release file and add it to the MetaIndex - if(!MetaIndex->Load(*I+"Release")) + if(!MetaIndex->Load(release)) { _error->Error("%s",MetaIndex->ErrorText.c_str()); return false; @@ -679,6 +652,64 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector &SigList, return true; } /*}}}*/ +// SigVerify::GetGPGVCommandLine - returns the command needed for verify/*{{{*/ +// --------------------------------------------------------------------- +/* Generating the commandline for calling gpgv is somehow complicated as + we need to add multiple keyrings and user supplied options. Also, as + the cdrom code currently can not use the gpgv method we have two places + these need to be done - so the place for this method is wrong but better + than code duplication… */ +std::vector SigVerify::GetGPGVCommandLine() +{ + string const gpgvpath = _config->Find("Dir::Bin::gpg", "/usr/bin/gpgv"); + // FIXME: remove support for deprecated APT::GPGV setting + string const trustedFile = _config->FindFile("Dir::Etc::Trusted", + _config->Find("APT::GPGV::TrustedKeyring", "/etc/apt/trusted.gpg").c_str()); + string const trustedPath = _config->FindDir("Dir::Etc::TrustedParts", "/etc/apt/trusted.gpg.d"); + + if (_config->FindB("Debug::Acquire::gpgv", false) == true) + { + std::clog << "gpgv path: " << gpgvpath << std::endl; + std::clog << "Keyring file: " << trustedFile << std::endl; + std::clog << "Keyring path: " << trustedPath << std::endl; + } + + std::vector keyrings = GetListOfFilesInDir(trustedPath, "gpg", false); + if (FileExists(trustedFile) == true) + keyrings.push_back(trustedFile); + + std::vector Args; + Args.reserve(30); + + if (keyrings.empty() == true) + return Args; + + Args.push_back(gpgvpath.c_str()); + Args.push_back("--ignore-time-conflict"); + + for (vector::const_iterator K = keyrings.begin(); + K != keyrings.end(); ++K) + { + Args.push_back("--keyring"); + Args.push_back(K->c_str()); + } + + Configuration::Item const *Opts; + Opts = _config->Tree("Acquire::gpgv::Options"); + if (Opts != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + Args.push_back(Opts->Value.c_str()); + } + } + + return Args; +} + /*}}}*/ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/ vector &List, pkgCdromStatus *log) { diff --git a/apt-pkg/indexcopy.h b/apt-pkg/indexcopy.h index 9e5ad4e43..ee6557a3d 100644 --- a/apt-pkg/indexcopy.h +++ b/apt-pkg/indexcopy.h @@ -89,6 +89,9 @@ class SigVerify /*{{{*/ public: bool CopyAndVerify(string CDROM,string Name,vector &SigList, vector PkgList,vector SrcList); + + /** \brief generates the command to verify a file with gpgv */ + static std::vector GetGPGVCommandLine(); }; /*}}}*/ -- cgit v1.2.3 From 24d7b6267ef3e475a153d4e2c4bcb30e1d14e671 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 9 Jun 2010 18:23:23 +0200 Subject: be sure that the RFC1123StrToTime method is run in a LANG=C environment --- apt-pkg/contrib/strutl.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 160450366..ace74cb37 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -861,12 +861,16 @@ static time_t timegm(struct tm *t) bool RFC1123StrToTime(const char* const str,time_t &time) { struct tm Tm; + setlocale (LC_ALL,"C"); + bool const invalid = // Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 - if (strptime(str, "%a, %d %b %Y %H:%M:%S %Z", &Tm) == NULL && + (strptime(str, "%a, %d %b %Y %H:%M:%S %Z", &Tm) == NULL && // Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 strptime(str, "%A, %d-%b-%y %H:%M:%S %Z", &Tm) == NULL && // Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format - strptime(str, "%a %b %d %H:%M:%S %Y", &Tm) == NULL) + strptime(str, "%a %b %d %H:%M:%S %Y", &Tm) == NULL); + setlocale (LC_ALL,""); + if (invalid == true) return false; time = timegm(&Tm); -- cgit v1.2.3 From c91d9a630bfe95f152d574a0ca420fde2afc6b2c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 9 Jun 2010 21:15:52 +0200 Subject: sent Last-Modified header also for Translation files --- apt-pkg/acquire-item.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 4d9a152ab..58754a5c0 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -140,7 +140,8 @@ void pkgAcquire::Item::Rename(string From,string To) } } /*}}}*/ - +// Acquire::Item::ReportMirrorFailure /*{{{*/ +// --------------------------------------------------------------------- void pkgAcquire::Item::ReportMirrorFailure(string FailCode) { // we only act if a mirror was used at all @@ -182,7 +183,7 @@ void pkgAcquire::Item::ReportMirrorFailure(string FailCode) _config->Find("Methods::Mirror::ProblemReporting").c_str()); } } - + /*}}}*/ // AcqDiffIndex::AcqDiffIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- /* Get the DiffIndex file first and see if there are patches availabe @@ -835,7 +836,13 @@ pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner, // --------------------------------------------------------------------- string pkgAcqIndexTrans::Custom600Headers() { - return "\nFail-Ignore: true"; + string Final = _config->FindDir("Dir::State::lists"); + Final += URItoFileName(RealURI); + + struct stat Buf; + if (stat(Final.c_str(),&Buf) != 0) + return "\nFail-Ignore: true"; + return "\nFail-Ignore: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); } /*}}}*/ // AcqIndexTrans::Failed - Silence failure messages for missing files /*{{{*/ -- cgit v1.2.3 From cf440facb498fa0ec70148723b13d6d019758c0e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 9 Jun 2010 23:20:26 +0200 Subject: enhance the split out of the gpgv commandline mangling by splitting out the call completely --- apt-pkg/indexcopy.cc | 62 +++++++++++++++++++++++++++++++++++++++++----------- apt-pkg/indexcopy.h | 10 +++++++-- 2 files changed, 57 insertions(+), 15 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc index 47eaefc5c..621c18716 100644 --- a/apt-pkg/indexcopy.cc +++ b/apt-pkg/indexcopy.cc @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include /*}}}*/ @@ -605,14 +607,9 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector &SigList, _error->Error("Fork failed"); return false; } - if(pid == 0) { - string const gpgvpath = _config->Find("Dir::Bin::gpg", "/usr/bin/gpgv"); - std::vector Args = GetGPGVCommandLine(); - Args.push_back(releasegpg.c_str()); - Args.push_back(release.c_str()); - Args.push_back(NULL); - execvp(gpgvpath.c_str(), (char**) &Args[0]); - } + if(pid == 0) + RunGPGV(release, releasegpg); + if(!ExecWait(pid, "gpgv")) { _error->Warning("Signature verification failed for: %s", releasegpg.c_str()); @@ -652,14 +649,15 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector &SigList, return true; } /*}}}*/ -// SigVerify::GetGPGVCommandLine - returns the command needed for verify/*{{{*/ +// SigVerify::RunGPGV - returns the command needed for verify /*{{{*/ // --------------------------------------------------------------------- /* Generating the commandline for calling gpgv is somehow complicated as we need to add multiple keyrings and user supplied options. Also, as the cdrom code currently can not use the gpgv method we have two places these need to be done - so the place for this method is wrong but better than code duplication… */ -std::vector SigVerify::GetGPGVCommandLine() +bool SigVerify::RunGPGV(std::string const &File, std::string const &FileGPG, + int const &statusfd, int fd[2]) { string const gpgvpath = _config->Find("Dir::Bin::gpg", "/usr/bin/gpgv"); // FIXME: remove support for deprecated APT::GPGV setting @@ -667,7 +665,9 @@ std::vector SigVerify::GetGPGVCommandLine() _config->Find("APT::GPGV::TrustedKeyring", "/etc/apt/trusted.gpg").c_str()); string const trustedPath = _config->FindDir("Dir::Etc::TrustedParts", "/etc/apt/trusted.gpg.d"); - if (_config->FindB("Debug::Acquire::gpgv", false) == true) + bool const Debug = _config->FindB("Debug::Acquire::gpgv", false); + + if (Debug == true) { std::clog << "gpgv path: " << gpgvpath << std::endl; std::clog << "Keyring file: " << trustedFile << std::endl; @@ -682,11 +682,19 @@ std::vector SigVerify::GetGPGVCommandLine() Args.reserve(30); if (keyrings.empty() == true) - return Args; + return false; Args.push_back(gpgvpath.c_str()); Args.push_back("--ignore-time-conflict"); + if (statusfd != -1) + { + Args.push_back("--status-fd"); + char fd[10]; + snprintf(fd, sizeof(fd), "%i", statusfd); + Args.push_back(fd); + } + for (vector::const_iterator K = keyrings.begin(); K != keyrings.end(); ++K) { @@ -707,7 +715,35 @@ std::vector SigVerify::GetGPGVCommandLine() } } - return Args; + Args.push_back(FileGPG.c_str()); + Args.push_back(File.c_str()); + Args.push_back(NULL); + + if (Debug == true) + { + std::clog << "Preparing to exec: " << gpgvpath; + for (std::vector::const_iterator a = Args.begin(); *a != NULL; ++a) + std::clog << " " << *a; + std::clog << std::endl; + } + + if (statusfd != -1) + { + int const nullfd = open("/dev/null", O_RDONLY); + close(fd[0]); + // Redirect output to /dev/null; we read from the status fd + dup2(nullfd, STDOUT_FILENO); + dup2(nullfd, STDERR_FILENO); + // Redirect the pipe to the status fd (3) + dup2(fd[1], statusfd); + + putenv((char *)"LANG="); + putenv((char *)"LC_ALL="); + putenv((char *)"LC_MESSAGES="); + } + + execvp(gpgvpath.c_str(), (char **) &Args[0]); + return true; } /*}}}*/ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/ diff --git a/apt-pkg/indexcopy.h b/apt-pkg/indexcopy.h index ee6557a3d..6fcd3b8ce 100644 --- a/apt-pkg/indexcopy.h +++ b/apt-pkg/indexcopy.h @@ -90,8 +90,14 @@ class SigVerify /*{{{*/ bool CopyAndVerify(string CDROM,string Name,vector &SigList, vector PkgList,vector SrcList); - /** \brief generates the command to verify a file with gpgv */ - static std::vector GetGPGVCommandLine(); + /** \brief generates and run the command to verify a file with gpgv */ + static bool RunGPGV(std::string const &File, std::string const &FileOut, + int const &statusfd, int fd[2]); + inline static bool RunGPGV(std::string const &File, std::string const &FileOut, + int const &statusfd = -1) { + int fd[2]; + return RunGPGV(File, FileOut, statusfd, fd); + }; }; /*}}}*/ -- cgit v1.2.3 From a8ef7efd6df81d4fb9e52419695f10df9fe76cda Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 10 Jun 2010 13:09:23 +0200 Subject: * apt-pkg/cacheset.cc: - get the candidate either from an already built depcache or use the policy which is a bit faster than depcache generation --- apt-pkg/cachefile.h | 8 ++++++-- apt-pkg/cacheset.cc | 11 ++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cachefile.h b/apt-pkg/cachefile.h index 1647aff8e..c68f06ed8 100644 --- a/apt-pkg/cachefile.h +++ b/apt-pkg/cachefile.h @@ -20,10 +20,9 @@ #include #include +#include #include -class pkgPolicy; -class pkgSourceList; class pkgCacheFile { protected: @@ -65,6 +64,11 @@ class pkgCacheFile inline pkgPolicy* GetPolicy() { BuildPolicy(); return Policy; }; inline pkgSourceList* GetSourceList() { BuildSourceList(); return SrcList; }; + inline bool IsPkgCacheBuilt() const { return (Cache != NULL); }; + inline bool IsDepCacheBuilt() const { return (DCache != NULL); }; + inline bool IsPolicyBuilt() const { return (Policy != NULL); }; + inline bool IsSrcListBuilt() const { return (SrcList != NULL); }; + pkgCacheFile(); virtual ~pkgCacheFile(); }; diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index 43ade4b4e..e91b56997 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -261,9 +261,14 @@ bool VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, // getCandidateVer - Returns the candidate version of the given package /*{{{*/ pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, bool const &AllowError) { - if (unlikely(Cache.BuildDepCache() == false)) - return pkgCache::VerIterator(*Cache); - pkgCache::VerIterator Cand = Cache[Pkg].CandidateVerIter(Cache); + pkgCache::VerIterator Cand; + if (Cache.IsDepCacheBuilt() == true) + Cand = Cache[Pkg].CandidateVerIter(Cache); + else { + if (unlikely(Cache.BuildPolicy() == false)) + return pkgCache::VerIterator(*Cache); + Cand = Cache.GetPolicy()->GetCandidateVer(Pkg); + } if (AllowError == false && Cand.end() == true) _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str()); return Cand; -- cgit v1.2.3 From 01606def78105c9d64f12c89e387d37ed46925b6 Mon Sep 17 00:00:00 2001 From: "martin@piware.de" <> Date: Thu, 10 Jun 2010 13:20:27 +0200 Subject: * apt-pkg/acquire-item.cc: - If the Acquire::GzipIndexes option is true and we download a gzipped index file, keep it as it is (and rename to .gz) instead of uncompressing it. --- apt-pkg/acquire-item.cc | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 6d4336425..eab34e26c 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -620,6 +620,8 @@ string pkgAcqIndex::Custom600Headers() { string Final = _config->FindDir("Dir::State::lists"); Final += URItoFileName(RealURI); + if (_config->FindB("Acquire::GzipIndexes",false)) + Final += ".gz"; struct stat Buf; if (stat(Final.c_str(),&Buf) != 0) @@ -714,6 +716,23 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash, Erase = false; Complete = true; + string compExt = flExtension(flNotDir(URI(Desc.URI).Path)); + + // If we enable compressed indexes and already have gzip, keep it + if (_config->FindB("Acquire::GzipIndexes",false) && compExt == "gz") { + string FinalFile = _config->FindDir("Dir::State::lists"); + FinalFile += URItoFileName(RealURI) + ".gz"; + //if(Debug) + // std::clog << "pkgAcqIndex: keeping gzipped " << FinalFile << endl; + Rename(DestFile,FinalFile); + chmod(FinalFile.c_str(),0644); + + // Update DestFile for .gz suffix so that the clean operation keeps it + DestFile = _config->FindDir("Dir::State::lists") + "partial/"; + DestFile += URItoFileName(RealURI) + ".gz"; + return; + } + // Handle the unzipd case string FileName = LookupTag(Message,"Alt-Filename"); if (FileName.empty() == false) @@ -746,7 +765,6 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash, else Local = true; - string compExt = flExtension(flNotDir(URI(Desc.URI).Path)); string decompProg; // get the binary name for your used compression type -- cgit v1.2.3 From c0ba35fc916d2adf0ba1fbd8cca62a83ce83d789 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 10 Jun 2010 15:10:38 +0200 Subject: * apt-pkg/orderlist.cc: - untouched packages are never missing * apt-pkg/packagemanager.cc: - packages that are not touched doesn't need to be unpacked --- apt-pkg/orderlist.cc | 3 ++- apt-pkg/packagemanager.cc | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc index 7c950292a..55f9cb9cc 100644 --- a/apt-pkg/orderlist.cc +++ b/apt-pkg/orderlist.cc @@ -117,7 +117,8 @@ bool pkgOrderList::IsMissing(PkgIterator Pkg) return false; // Skip Packages that need configure only. - if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && + if ((Pkg.State() == pkgCache::PkgIterator::NeedsConfigure || + Pkg.State() == pkgCache::PkgIterator::NeedsNothing) && Cache[Pkg].Keep() == true) return false; diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index eef79cccd..49776aac7 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -602,7 +602,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) // configured we don't need to unpack it again… PkgIterator const P = Pkg.Group().FindPkg("all"); if (List->IsFlag(P,pkgOrderList::UnPacked) != true && - List->IsFlag(P,pkgOrderList::Configured) != true) { + List->IsFlag(P,pkgOrderList::Configured) != true && + P.State() != pkgCache::PkgIterator::NeedsNothing) { if (SmartUnPack(P) == false) return false; } -- cgit v1.2.3 From 6b2f7a60c3d7d22d1d6b0e300ef526d48ff20048 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 10 Jun 2010 16:15:57 +0200 Subject: * apt-pkg/cachefile.h: - make pkgPolicy public again, libapt-pkg-perl (and probably others) get unhappy without that --- apt-pkg/cachefile.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cachefile.h b/apt-pkg/cachefile.h index 1647aff8e..63bc3de47 100644 --- a/apt-pkg/cachefile.h +++ b/apt-pkg/cachefile.h @@ -31,10 +31,10 @@ class pkgCacheFile MMap *Map; pkgCache *Cache; pkgDepCache *DCache; - pkgPolicy *Policy; pkgSourceList *SrcList; public: + pkgPolicy *Policy; // We look pretty much exactly like a pointer to a dep cache inline operator pkgCache &() {return *Cache;}; -- cgit v1.2.3 From bb109d0b14218cde4fccc45856cf67e5513c0cc9 Mon Sep 17 00:00:00 2001 From: "martin@piware.de" <> Date: Fri, 11 Jun 2010 10:43:43 +0200 Subject: Fix compressed index retrieval for current timestamps Fix a thinko in r1973, which did the Acquire::GzipIndexes test ealier than the IMS-Hit test. This led to rename errors. --- apt-pkg/acquire-item.cc | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index eab34e26c..83fb5328b 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -716,23 +716,6 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash, Erase = false; Complete = true; - string compExt = flExtension(flNotDir(URI(Desc.URI).Path)); - - // If we enable compressed indexes and already have gzip, keep it - if (_config->FindB("Acquire::GzipIndexes",false) && compExt == "gz") { - string FinalFile = _config->FindDir("Dir::State::lists"); - FinalFile += URItoFileName(RealURI) + ".gz"; - //if(Debug) - // std::clog << "pkgAcqIndex: keeping gzipped " << FinalFile << endl; - Rename(DestFile,FinalFile); - chmod(FinalFile.c_str(),0644); - - // Update DestFile for .gz suffix so that the clean operation keeps it - DestFile = _config->FindDir("Dir::State::lists") + "partial/"; - DestFile += URItoFileName(RealURI) + ".gz"; - return; - } - // Handle the unzipd case string FileName = LookupTag(Message,"Alt-Filename"); if (FileName.empty() == false) @@ -765,8 +748,24 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash, else Local = true; + string compExt = flExtension(flNotDir(URI(Desc.URI).Path)); string decompProg; + // If we enable compressed indexes and already have gzip, keep it + if (_config->FindB("Acquire::GzipIndexes",false) && compExt == "gz") { + string FinalFile = _config->FindDir("Dir::State::lists"); + FinalFile += URItoFileName(RealURI) + ".gz"; + //if(Debug) + // std::clog << "pkgAcqIndex: keeping gzipped " << FinalFile << endl; + Rename(DestFile,FinalFile); + chmod(FinalFile.c_str(),0644); + + // Update DestFile for .gz suffix so that the clean operation keeps it + DestFile = _config->FindDir("Dir::State::lists") + "partial/"; + DestFile += URItoFileName(RealURI) + ".gz"; + return; + } + // get the binary name for your used compression type decompProg = _config->Find(string("Acquire::CompressionTypes::").append(compExt),""); if(decompProg.empty() == false); -- cgit v1.2.3 From b26e2415ee2d4f611966488954f8d4f30fcf827c Mon Sep 17 00:00:00 2001 From: "martin@piware.de" <> Date: Fri, 11 Jun 2010 18:59:06 +0200 Subject: * apt-pkg/acquire-item.cc: - Fix return value of pkgAcqFile::Custom600Headers() in the non-index case, to avoid returning NULL and causing crashers in callers. This also fixes a compiler warning. --- apt-pkg/acquire-item.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 83fb5328b..bcfe6a98a 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -1688,5 +1688,7 @@ string pkgAcqFile::Custom600Headers() { if (IsIndexFile) return "\nIndex-File: true"; + else + return ""; } /*}}}*/ -- cgit v1.2.3 From 94e8c9d4df70d2532e1640dfe2700dd63a094a4f Mon Sep 17 00:00:00 2001 From: "martin@piware.de" <> Date: Fri, 11 Jun 2010 19:23:08 +0200 Subject: apt-pkg/deb/debindexfile.cc: Fix one more place to check for gzipped indexes, to work with apt-get source as well --- apt-pkg/deb/debindexfile.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index e87c21f13..9832329c0 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -63,9 +63,13 @@ string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record, /* */ pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const { - string SourcesURI = URItoFileName(IndexURI("Sources")); - return new debSrcRecordParser(_config->FindDir("Dir::State::lists") + - SourcesURI,this); + string SourcesURI = _config->FindDir("Dir::State::lists") + + URItoFileName(IndexURI("Sources")); + string SourcesURIgzip = SourcesURI + ".gz"; + if (!FileExists(SourcesURI) && FileExists(SourcesURIgzip)) + SourcesURI = SourcesURIgzip; + + return new debSrcRecordParser(SourcesURI,this); } /*}}}*/ // SourcesIndex::Describe - Give a descriptive path to the index /*{{{*/ -- cgit v1.2.3 From 55c59998a046e8d60b5bf51772bd7db5cd43ca7c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 15 Jun 2010 20:29:50 +0200 Subject: Add a GroupedFromCommandLine for the VersionSet similar to the one for PackageSet and refactor the existing VersionSet methods to simplify that. --- apt-pkg/cacheset.cc | 123 +++++++++++++++++++++++++++++++++++----------------- apt-pkg/cacheset.h | 35 +++++++++++++++ 2 files changed, 119 insertions(+), 39 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index e91b56997..fde52168a 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -91,7 +91,7 @@ std::map PackageSet::GroupedFromCommandLine( switch(mod->Pos) { case PackageSet::Modifier::POSTFIX: if (str.compare(str.length() - alength, alength, - mod->Alias, 0, alength) != 0) + mod->Alias, 0, alength) != 0) continue; str.erase(str.length() - alength); modID = mod->ID; @@ -148,53 +148,98 @@ PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, s return regex; } /*}}}*/ +// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ +std::map VersionSet::GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, std::ostream &out) { + std::map versets; + for (const char **I = cmdline; *I != 0; ++I) { + unsigned short modID = fallback; + VersionSet::Version select = VersionSet::NEWEST; + std::string str = *I; + for (std::list::const_iterator mod = mods.begin(); + mod != mods.end(); ++mod) { + if (modID == fallback && mod->ID == fallback) + select = mod->SelectVersion; + size_t const alength = strlen(mod->Alias); + switch(mod->Pos) { + case VersionSet::Modifier::POSTFIX: + if (str.compare(str.length() - alength, alength, + mod->Alias, 0, alength) != 0) + continue; + str.erase(str.length() - alength); + modID = mod->ID; + select = mod->SelectVersion; + break; + case VersionSet::Modifier::PREFIX: + continue; + case VersionSet::Modifier::NONE: + continue; + } + break; + } + VersionSet vset = VersionSet::FromString(Cache, str, select , out); + versets[modID].insert(vset.begin(), vset.end()); + } + return versets; +} + /*}}}*/ // FromCommandLine - Return all versions specified on commandline /*{{{*/ APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, APT::VersionSet::Version const &fallback, std::ostream &out) { VersionSet verset; for (const char **I = cmdline; *I != 0; ++I) { - std::string pkg = *I; - std::string ver; - bool verIsRel = false; - size_t const vertag = pkg.find_last_of("/="); - if (vertag != string::npos) { - ver = pkg.substr(vertag+1); - verIsRel = (pkg[vertag] == '/'); - pkg.erase(vertag); + VersionSet vset = VersionSet::FromString(Cache, *I, fallback, out); + verset.insert(vset.begin(), vset.end()); + } + return verset; +} + /*}}}*/ +// FromString - Returns all versions spedcified by a string /*{{{*/ +APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, + APT::VersionSet::Version const &fallback, std::ostream &out) { + std::string ver; + bool verIsRel = false; + size_t const vertag = pkg.find_last_of("/="); + if (vertag != string::npos) { + ver = pkg.substr(vertag+1); + verIsRel = (pkg[vertag] == '/'); + pkg.erase(vertag); + } + PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), out); + VersionSet verset; + for (PackageSet::const_iterator P = pkgset.begin(); + P != pkgset.end(); ++P) { + if (vertag == string::npos) { + AddSelectedVersion(Cache, verset, P, fallback); + continue; } - PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), out); - for (PackageSet::const_iterator P = pkgset.begin(); - P != pkgset.end(); ++P) { - if (vertag == string::npos) { - AddSelectedVersion(Cache, verset, P, fallback); + pkgCache::VerIterator V; + if (ver == "installed") + V = getInstalledVer(Cache, P); + else if (ver == "candidate") + V = getCandidateVer(Cache, P); + else { + pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release : + pkgVersionMatch::Version)); + V = Match.Find(P); + if (V.end() == true) { + if (verIsRel == true) + _error->Error(_("Release '%s' for '%s' was not found"), + ver.c_str(), P.FullName(true).c_str()); + else + _error->Error(_("Version '%s' for '%s' was not found"), + ver.c_str(), P.FullName(true).c_str()); continue; } - pkgCache::VerIterator V; - if (ver == "installed") - V = getInstalledVer(Cache, P); - else if (ver == "candidate") - V = getCandidateVer(Cache, P); - else { - pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release : - pkgVersionMatch::Version)); - V = Match.Find(P); - if (V.end() == true) { - if (verIsRel == true) - _error->Error(_("Release '%s' for '%s' was not found"), - ver.c_str(), P.FullName(true).c_str()); - else - _error->Error(_("Version '%s' for '%s' was not found"), - ver.c_str(), P.FullName(true).c_str()); - continue; - } - } - if (V.end() == true) - continue; - if (ver == V.VerStr()) - ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), - V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); - verset.insert(V); } + if (V.end() == true) + continue; + if (ver == V.VerStr()) + ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), + V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); + verset.insert(V); } return verset; } diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index 668d8039e..2bc268380 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -209,6 +209,41 @@ public: /*{{{*/ static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { return APT::VersionSet::FromCommandLine(Cache, cmdline, CANDINST); } + + static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, + APT::VersionSet::Version const &fallback, std::ostream &out); + static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, + APT::VersionSet::Version const &fallback) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::VersionSet::FromString(Cache, pkg, fallback, out); + } + static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg) { + return APT::VersionSet::FromString(Cache, pkg, CANDINST); + } + + struct Modifier { + enum Position { NONE, PREFIX, POSTFIX }; + unsigned short ID; + const char * const Alias; + Position Pos; + VersionSet::Version SelectVersion; + Modifier (unsigned short const &id, const char * const alias, Position const &pos, + VersionSet::Version const &select) : ID(id), Alias(alias), Pos(pos), + SelectVersion(select) {}; + }; + + static std::map GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, std::ostream &out); + static std::map GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::VersionSet::GroupedFromCommandLine(Cache, cmdline, + mods, fallback, out); + } /*}}}*/ protected: /*{{{*/ -- cgit v1.2.3 From d8276801a1c84582a85ed9ea1f2eb4e66e052e6b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 15 Jun 2010 20:46:09 +0200 Subject: * cmdline/cacheset.cc: - doesn't include it in the library for now as it is too volatile --- apt-pkg/cacheset.cc | 330 ---------------------------------------------------- apt-pkg/cacheset.h | 274 ------------------------------------------- apt-pkg/makefile | 5 +- 3 files changed, 2 insertions(+), 607 deletions(-) delete mode 100644 apt-pkg/cacheset.cc delete mode 100644 apt-pkg/cacheset.h (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc deleted file mode 100644 index fde52168a..000000000 --- a/apt-pkg/cacheset.cc +++ /dev/null @@ -1,330 +0,0 @@ -// -*- mode: cpp; mode: fold -*- -// Description /*{{{*/ -/* ###################################################################### - - Simple wrapper around a std::set to provide a similar interface to - a set of cache structures as to the complete set of all structures - in the pkgCache. Currently only Package is supported. - - ##################################################################### */ - /*}}}*/ -// Include Files /*{{{*/ -#include -#include -#include -#include -#include - -#include - -#include - -#include - /*}}}*/ -namespace APT { -// FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ -PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { - PackageSet pkgset; - std::string arch = "native"; - static const char * const isregex = ".?+*|[^$"; - - if (pattern.find_first_of(isregex) == std::string::npos) - return pkgset; - - size_t archfound = pattern.find_last_of(':'); - if (archfound != std::string::npos) { - arch = pattern.substr(archfound+1); - if (arch.find_first_of(isregex) == std::string::npos) - pattern.erase(archfound); - else - arch = "native"; - } - - regex_t Pattern; - int Res; - if ((Res = regcomp(&Pattern, pattern.c_str() , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) { - char Error[300]; - regerror(Res, &Pattern, Error, sizeof(Error)); - _error->Error(_("Regex compilation error - %s"), Error); - return pkgset; - } - - for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) - { - if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0) - continue; - pkgCache::PkgIterator Pkg = Grp.FindPkg(arch); - if (Pkg.end() == true) { - if (archfound == std::string::npos) { - std::vector archs = APT::Configuration::getArchitectures(); - for (std::vector::const_iterator a = archs.begin(); - a != archs.end() && Pkg.end() != true; ++a) - Pkg = Grp.FindPkg(*a); - } - if (Pkg.end() == true) - continue; - } - - ioprintf(out, _("Note, selecting %s for regex '%s'\n"), - Pkg.FullName(true).c_str(), pattern.c_str()); - - pkgset.insert(Pkg); - } - - regfree(&Pattern); - - return pkgset; -} - /*}}}*/ -// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ -std::map PackageSet::GroupedFromCommandLine( - pkgCacheFile &Cache, const char **cmdline, - std::list const &mods, - unsigned short const &fallback, std::ostream &out) { - std::map pkgsets; - for (const char **I = cmdline; *I != 0; ++I) { - unsigned short modID = fallback; - std::string str = *I; - for (std::list::const_iterator mod = mods.begin(); - mod != mods.end(); ++mod) { - size_t const alength = strlen(mod->Alias); - switch(mod->Pos) { - case PackageSet::Modifier::POSTFIX: - if (str.compare(str.length() - alength, alength, - mod->Alias, 0, alength) != 0) - continue; - str.erase(str.length() - alength); - modID = mod->ID; - break; - case PackageSet::Modifier::PREFIX: - continue; - case PackageSet::Modifier::NONE: - continue; - } - break; - } - PackageSet pset = PackageSet::FromString(Cache, str, out); - pkgsets[modID].insert(pset.begin(), pset.end()); - } - return pkgsets; -} - /*}}}*/ -// FromCommandLine - Return all packages specified on commandline /*{{{*/ -PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out) { - PackageSet pkgset; - for (const char **I = cmdline; *I != 0; ++I) { - PackageSet pset = FromString(Cache, *I, out); - pkgset.insert(pset.begin(), pset.end()); - } - return pkgset; -} - /*}}}*/ -// FromString - Return all packages matching a specific string /*{{{*/ -PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, std::ostream &out) { - std::string pkg = str; - size_t archfound = pkg.find_last_of(':'); - std::string arch; - if (archfound != std::string::npos) { - arch = pkg.substr(archfound+1); - pkg.erase(archfound); - } - - pkgCache::PkgIterator Pkg; - if (arch.empty() == true) { - pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(pkg); - if (Grp.end() == false) - Pkg = Grp.FindPreferredPkg(); - } else - Pkg = Cache.GetPkgCache()->FindPkg(pkg, arch); - - if (Pkg.end() == false) { - PackageSet pkgset; - pkgset.insert(Pkg); - return pkgset; - } - PackageSet regex = FromRegEx(Cache, str, out); - if (regex.empty() == true) - _error->Warning(_("Unable to locate package %s"), str.c_str()); - return regex; -} - /*}}}*/ -// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ -std::map VersionSet::GroupedFromCommandLine( - pkgCacheFile &Cache, const char **cmdline, - std::list const &mods, - unsigned short const &fallback, std::ostream &out) { - std::map versets; - for (const char **I = cmdline; *I != 0; ++I) { - unsigned short modID = fallback; - VersionSet::Version select = VersionSet::NEWEST; - std::string str = *I; - for (std::list::const_iterator mod = mods.begin(); - mod != mods.end(); ++mod) { - if (modID == fallback && mod->ID == fallback) - select = mod->SelectVersion; - size_t const alength = strlen(mod->Alias); - switch(mod->Pos) { - case VersionSet::Modifier::POSTFIX: - if (str.compare(str.length() - alength, alength, - mod->Alias, 0, alength) != 0) - continue; - str.erase(str.length() - alength); - modID = mod->ID; - select = mod->SelectVersion; - break; - case VersionSet::Modifier::PREFIX: - continue; - case VersionSet::Modifier::NONE: - continue; - } - break; - } - VersionSet vset = VersionSet::FromString(Cache, str, select , out); - versets[modID].insert(vset.begin(), vset.end()); - } - return versets; -} - /*}}}*/ -// FromCommandLine - Return all versions specified on commandline /*{{{*/ -APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, - APT::VersionSet::Version const &fallback, std::ostream &out) { - VersionSet verset; - for (const char **I = cmdline; *I != 0; ++I) { - VersionSet vset = VersionSet::FromString(Cache, *I, fallback, out); - verset.insert(vset.begin(), vset.end()); - } - return verset; -} - /*}}}*/ -// FromString - Returns all versions spedcified by a string /*{{{*/ -APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, - APT::VersionSet::Version const &fallback, std::ostream &out) { - std::string ver; - bool verIsRel = false; - size_t const vertag = pkg.find_last_of("/="); - if (vertag != string::npos) { - ver = pkg.substr(vertag+1); - verIsRel = (pkg[vertag] == '/'); - pkg.erase(vertag); - } - PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), out); - VersionSet verset; - for (PackageSet::const_iterator P = pkgset.begin(); - P != pkgset.end(); ++P) { - if (vertag == string::npos) { - AddSelectedVersion(Cache, verset, P, fallback); - continue; - } - pkgCache::VerIterator V; - if (ver == "installed") - V = getInstalledVer(Cache, P); - else if (ver == "candidate") - V = getCandidateVer(Cache, P); - else { - pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release : - pkgVersionMatch::Version)); - V = Match.Find(P); - if (V.end() == true) { - if (verIsRel == true) - _error->Error(_("Release '%s' for '%s' was not found"), - ver.c_str(), P.FullName(true).c_str()); - else - _error->Error(_("Version '%s' for '%s' was not found"), - ver.c_str(), P.FullName(true).c_str()); - continue; - } - } - if (V.end() == true) - continue; - if (ver == V.VerStr()) - ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), - V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); - verset.insert(V); - } - return verset; -} - /*}}}*/ -// AddSelectedVersion - add version from package based on fallback /*{{{*/ -bool VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, - pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, - bool const &AllowError) { - pkgCache::VerIterator V; - switch(fallback) { - case VersionSet::ALL: - if (P->VersionList != 0) - for (V = P.VersionList(); V.end() != true; ++V) - verset.insert(V); - else if (AllowError == false) - return _error->Error(_("Can't select versions from package '%s' as it purely virtual"), P.FullName(true).c_str()); - else - return false; - break; - case VersionSet::CANDANDINST: - verset.insert(getInstalledVer(Cache, P, AllowError)); - verset.insert(getCandidateVer(Cache, P, AllowError)); - break; - case VersionSet::CANDIDATE: - verset.insert(getCandidateVer(Cache, P, AllowError)); - break; - case VersionSet::INSTALLED: - verset.insert(getInstalledVer(Cache, P, AllowError)); - break; - case VersionSet::CANDINST: - V = getCandidateVer(Cache, P, true); - if (V.end() == true) - V = getInstalledVer(Cache, P, true); - if (V.end() == false) - verset.insert(V); - else if (AllowError == false) - return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str()); - else - return false; - break; - case VersionSet::INSTCAND: - V = getInstalledVer(Cache, P, true); - if (V.end() == true) - V = getCandidateVer(Cache, P, true); - if (V.end() == false) - verset.insert(V); - else if (AllowError == false) - return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str()); - else - return false; - break; - case VersionSet::NEWEST: - if (P->VersionList != 0) - verset.insert(P.VersionList()); - else if (AllowError == false) - return _error->Error(_("Can't select newest version from package '%s' as it is purely virtual"), P.FullName(true).c_str()); - else - return false; - break; - } - return true; -} - /*}}}*/ -// getCandidateVer - Returns the candidate version of the given package /*{{{*/ -pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, - pkgCache::PkgIterator const &Pkg, bool const &AllowError) { - pkgCache::VerIterator Cand; - if (Cache.IsDepCacheBuilt() == true) - Cand = Cache[Pkg].CandidateVerIter(Cache); - else { - if (unlikely(Cache.BuildPolicy() == false)) - return pkgCache::VerIterator(*Cache); - Cand = Cache.GetPolicy()->GetCandidateVer(Pkg); - } - if (AllowError == false && Cand.end() == true) - _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str()); - return Cand; -} - /*}}}*/ -// getInstalledVer - Returns the installed version of the given package /*{{{*/ -pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache, - pkgCache::PkgIterator const &Pkg, bool const &AllowError) { - if (AllowError == false && Pkg->CurrentVer == 0) - _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str()); - return Pkg.CurrentVer(); -} - /*}}}*/ -} diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h deleted file mode 100644 index 2bc268380..000000000 --- a/apt-pkg/cacheset.h +++ /dev/null @@ -1,274 +0,0 @@ -// -*- mode: cpp; mode: fold -*- -// Description /*{{{*/ -/** \file cacheset.h - Wrappers around std::set to have set::iterators which behave - similar to the Iterators of the cache structures. - - Provides also a few helper methods which work with these sets */ - /*}}}*/ -#ifndef APT_CACHESET_H -#define APT_CACHESET_H -// Include Files /*{{{*/ -#include -#include -#include -#include -#include -#include - -#include -#include - /*}}}*/ -namespace APT { -class PackageSet : public std::set { /*{{{*/ -/** \class APT::PackageSet - - Simple wrapper around a std::set to provide a similar interface to - a set of packages as to the complete set of all packages in the - pkgCache. */ -public: /*{{{*/ - /** \brief smell like a pkgCache::PkgIterator */ - class const_iterator : public std::set::const_iterator { - public: - const_iterator(std::set::const_iterator x) : - std::set::const_iterator(x) {} - - operator pkgCache::PkgIterator(void) { return **this; } - - inline const char *Name() const {return (**this).Name(); } - inline std::string FullName(bool const &Pretty) const { return (**this).FullName(Pretty); } - inline std::string FullName() const { return (**this).FullName(); } - inline const char *Section() const {return (**this).Section(); } - inline bool Purge() const {return (**this).Purge(); } - inline const char *Arch() const {return (**this).Arch(); } - inline pkgCache::GrpIterator Group() const { return (**this).Group(); } - inline pkgCache::VerIterator VersionList() const { return (**this).VersionList(); } - inline pkgCache::VerIterator CurrentVer() const { return (**this).CurrentVer(); } - inline pkgCache::DepIterator RevDependsList() const { return (**this).RevDependsList(); } - inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); } - inline pkgCache::PkgIterator::OkState State() const { return (**this).State(); } - inline const char *CandVersion() const { return (**this).CandVersion(); } - inline const char *CurVersion() const { return (**this).CurVersion(); } - inline pkgCache *Cache() const { return (**this).Cache(); }; - inline unsigned long Index() const {return (**this).Index();}; - // we have only valid iterators here - inline bool end() const { return false; }; - - friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, (*i)); } - - inline pkgCache::Package const * operator->() const { - return &***this; - }; - }; - // 103. set::iterator is required to be modifiable, but this allows modification of keys - typedef APT::PackageSet::const_iterator iterator; - - using std::set::insert; - inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set::insert(P); }; - - /** \brief returns all packages in the cache whose name matchs a given pattern - - A simple helper responsible for executing a regular expression on all - package names in the cache. Optional it prints a a notice about the - packages chosen cause of the given package. - \param Cache the packages are in - \param pattern regular expression for package names - \param out stream to print the notice to */ - static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out); - static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string const &pattern) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::FromRegEx(Cache, pattern, out); - } - - /** \brief returns all packages specified by a string - - \param Cache the packages are in - \param string String the package name(s) should be extracted from - \param out stream to print various notices to */ - static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, std::ostream &out); - static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::FromString(Cache, string, out); - } - - /** \brief returns all packages specified on the commandline - - Get all package names from the commandline and executes regex's if needed. - No special package command is supported, just plain names. - \param Cache the packages are in - \param cmdline Command line the package names should be extracted from - \param out stream to print various notices to */ - static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out); - static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::FromCommandLine(Cache, cmdline, out); - } - - struct Modifier { - enum Position { NONE, PREFIX, POSTFIX }; - unsigned short ID; - const char * const Alias; - Position Pos; - Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {}; - }; - - static std::map GroupedFromCommandLine( - pkgCacheFile &Cache, const char **cmdline, - std::list const &mods, - unsigned short const &fallback, std::ostream &out); - static std::map GroupedFromCommandLine( - pkgCacheFile &Cache, const char **cmdline, - std::list const &mods, - unsigned short const &fallback) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::GroupedFromCommandLine(Cache, cmdline, - mods, fallback, out); - } - /*}}}*/ -}; /*}}}*/ -class VersionSet : public std::set { /*{{{*/ -/** \class APT::VersionSet - - Simple wrapper around a std::set to provide a similar interface to - a set of versions as to the complete set of all versions in the - pkgCache. */ -public: /*{{{*/ - /** \brief smell like a pkgCache::VerIterator */ - class const_iterator : public std::set::const_iterator { - public: - const_iterator(std::set::const_iterator x) : - std::set::const_iterator(x) {} - - operator pkgCache::VerIterator(void) { return **this; } - - inline pkgCache *Cache() const { return (**this).Cache(); }; - inline unsigned long Index() const {return (**this).Index();}; - // we have only valid iterators here - inline bool end() const { return false; }; - - inline pkgCache::Version const * operator->() const { - return &***this; - }; - - inline int CompareVer(const pkgCache::VerIterator &B) const { return (**this).CompareVer(B); }; - inline const char *VerStr() const { return (**this).VerStr(); }; - inline const char *Section() const { return (**this).Section(); }; - inline const char *Arch() const { return (**this).Arch(); }; - inline const char *Arch(bool const pseudo) const { return (**this).Arch(pseudo); }; - inline pkgCache::PkgIterator ParentPkg() const { return (**this).ParentPkg(); }; - inline pkgCache::DescIterator DescriptionList() const { return (**this).DescriptionList(); }; - inline pkgCache::DescIterator TranslatedDescription() const { return (**this).TranslatedDescription(); }; - inline pkgCache::DepIterator DependsList() const { return (**this).DependsList(); }; - inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); }; - inline pkgCache::VerFileIterator FileList() const { return (**this).FileList(); }; - inline bool Downloadable() const { return (**this).Downloadable(); }; - inline const char *PriorityType() const { return (**this).PriorityType(); }; - inline string RelStr() const { return (**this).RelStr(); }; - inline bool Automatic() const { return (**this).Automatic(); }; - inline bool Pseudo() const { return (**this).Pseudo(); }; - inline pkgCache::VerFileIterator NewestFile() const { return (**this).NewestFile(); }; - }; - // 103. set::iterator is required to be modifiable, but this allows modification of keys - typedef APT::VersionSet::const_iterator iterator; - - using std::set::insert; - inline void insert(pkgCache::VerIterator const &V) { if (V.end() == false) std::set::insert(V); }; - - /** \brief specifies which version(s) will be returned if non is given */ - enum Version { - /** All versions */ - ALL, - /** Candidate and installed version */ - CANDANDINST, - /** Candidate version */ - CANDIDATE, - /** Installed version */ - INSTALLED, - /** Candidate or if non installed version */ - CANDINST, - /** Installed or if non candidate version */ - INSTCAND, - /** Newest version */ - NEWEST - }; - - /** \brief returns all versions specified on the commandline - - Get all versions from the commandline, uses given default version if - non specifically requested and executes regex's if needed on names. - \param Cache the packages and versions are in - \param cmdline Command line the versions should be extracted from - \param out stream to print various notices to */ - static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, - APT::VersionSet::Version const &fallback, std::ostream &out); - static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, - APT::VersionSet::Version const &fallback) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::VersionSet::FromCommandLine(Cache, cmdline, fallback, out); - } - static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { - return APT::VersionSet::FromCommandLine(Cache, cmdline, CANDINST); - } - - static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, - APT::VersionSet::Version const &fallback, std::ostream &out); - static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, - APT::VersionSet::Version const &fallback) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::VersionSet::FromString(Cache, pkg, fallback, out); - } - static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg) { - return APT::VersionSet::FromString(Cache, pkg, CANDINST); - } - - struct Modifier { - enum Position { NONE, PREFIX, POSTFIX }; - unsigned short ID; - const char * const Alias; - Position Pos; - VersionSet::Version SelectVersion; - Modifier (unsigned short const &id, const char * const alias, Position const &pos, - VersionSet::Version const &select) : ID(id), Alias(alias), Pos(pos), - SelectVersion(select) {}; - }; - - static std::map GroupedFromCommandLine( - pkgCacheFile &Cache, const char **cmdline, - std::list const &mods, - unsigned short const &fallback, std::ostream &out); - static std::map GroupedFromCommandLine( - pkgCacheFile &Cache, const char **cmdline, - std::list const &mods, - unsigned short const &fallback) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::VersionSet::GroupedFromCommandLine(Cache, cmdline, - mods, fallback, out); - } - /*}}}*/ -protected: /*{{{*/ - - /** \brief returns the candidate version of the package - - \param Cache to be used to query for information - \param Pkg we want the candidate version from this package - \param AllowError add an error to the stack if not */ - static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache, - pkgCache::PkgIterator const &Pkg, bool const &AllowError = false); - - /** \brief returns the installed version of the package - - \param Cache to be used to query for information - \param Pkg we want the installed version from this package - \param AllowError add an error to the stack if not */ - static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache, - pkgCache::PkgIterator const &Pkg, bool const &AllowError = false); - - - static bool AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, - pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, - bool const &AllowError = false); - - /*}}}*/ -}; /*}}}*/ -} -#endif diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 1a7078693..a5be462ce 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -35,15 +35,14 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \ srcrecords.cc cachefile.cc versionmatch.cc policy.cc \ pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \ indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \ - aptconfiguration.cc cacheset.cc + aptconfiguration.cc HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ orderlist.h sourcelist.h packagemanager.h tagfile.h \ init.h pkgcache.h version.h progress.h pkgrecords.h \ acquire.h acquire-worker.h acquire-item.h acquire-method.h \ clean.h srcrecords.h cachefile.h versionmatch.h policy.h \ pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \ - vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \ - cacheset.h + vendorlist.h cdrom.h indexcopy.h aptconfiguration.h # Source code for the debian specific components # In theory the deb headers do not need to be exported.. -- cgit v1.2.3 From 8ceeb9d695f7c8fc5d856aa4f8647e88c4a8659f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 16 Jun 2010 17:19:21 +0200 Subject: add a simple method to VerIterator to check if two Versions are similar --- apt-pkg/cacheiterators.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index f0b40dbb5..51bf6819e 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -30,6 +30,8 @@ #ifndef PKGLIB_CACHEITERATORS_H #define PKGLIB_CACHEITERATORS_H #include + +#include // abstract Iterator template /*{{{*/ /* This template provides the very basic iterator methods we need to have for doing some walk-over-the-cache magic */ @@ -183,6 +185,13 @@ class pkgCache::VerIterator : public Iterator { // Comparison int CompareVer(const VerIterator &B) const; + /** \brief compares two version and returns if they are similar + + This method should be used to identify if two pseudo versions are + refering to the same "real" version */ + inline bool SimilarVer(const VerIterator &B) const { + return (B.end() == false && S->Hash == B->Hash && strcmp(VerStr(), B.VerStr()) == 0); + }; // Accessors inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;}; -- cgit v1.2.3 From 1019948cea2e6adbd4b0df3f07b52c90187b1a05 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 16 Jun 2010 17:48:37 +0200 Subject: * apt-pkg/depcache.cc: - SetCandidateVer for all pseudo packages - SetReInstall for the "all" package of a pseudo package --- apt-pkg/depcache.cc | 32 +++++++++++++++++++++++++++++++- apt-pkg/depcache.h | 2 +- 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 3ae5f5953..d082b8404 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1453,6 +1453,9 @@ bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst, /* */ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To) { + if (unlikely(Pkg.end() == true)) + return; + ActionGroup group(*this); RemoveSizes(Pkg); @@ -1466,12 +1469,17 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To) AddStates(Pkg); AddSizes(Pkg); + + if (unlikely(Pkg.CurrentVer().end() == true) || Pkg.CurrentVer().Pseudo() == false) + return; + + SetReInstall(Pkg.Group().FindPkg("all"), To); } /*}}}*/ // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/ // --------------------------------------------------------------------- /* */ -void pkgDepCache::SetCandidateVersion(VerIterator TargetVer) +void pkgDepCache::SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo) { ActionGroup group(*this); @@ -1489,6 +1497,28 @@ void pkgDepCache::SetCandidateVersion(VerIterator TargetVer) AddStates(Pkg); Update(Pkg); AddSizes(Pkg); + + if (TargetVer.Pseudo() == false || Pseudo == false) + return; + + // the version was pseudo: set all other pseudos also + pkgCache::GrpIterator Grp = Pkg.Group(); + for (Pkg = Grp.FindPkg("any"); Pkg.end() == false; ++Pkg) + { + StateCache &P = PkgState[Pkg->ID]; + if (TargetVer.SimilarVer(P.CandidateVerIter(*this)) == true || + (P.CandidateVerIter(*this).Pseudo() == false && + strcmp(Pkg.Arch(), "all") != 0)) + continue; + + for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver) + { + if (TargetVer.SimilarVer(Ver) == false) + continue; + SetCandidateVersion(Ver, false); + break; + } + } } void pkgDepCache::MarkAuto(const PkgIterator &Pkg, bool Auto) diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index c6f245a80..72d7cce5d 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -405,7 +405,7 @@ class pkgDepCache : protected pkgCache::Namespace bool ForceImportantDeps = false); void SetReInstall(PkgIterator const &Pkg,bool To); - void SetCandidateVersion(VerIterator TargetVer); + void SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo = true); /** Set the "is automatically installed" flag of Pkg. */ void MarkAuto(const PkgIterator &Pkg, bool Auto); -- cgit v1.2.3 From 0b9032b180763ec974cdc918f93910540f05293a Mon Sep 17 00:00:00 2001 From: "martin@piware.de" <> Date: Thu, 17 Jun 2010 13:36:52 +0200 Subject: pkgAcqIndex::Done(): If we have an IMS-Hit, also rename the destination file in GzipIndexes mode, to avoid it being cleaned --- apt-pkg/acquire-item.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index bcfe6a98a..fe81ee791 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -739,16 +739,21 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash, ErrorText = "Method gave a blank filename"; } + string compExt = flExtension(flNotDir(URI(Desc.URI).Path)); + // The files timestamp matches - if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true) + if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true) { + if (_config->FindB("Acquire::GzipIndexes",false) && compExt == "gz") + // Update DestFile for .gz suffix so that the clean operation keeps it + DestFile += ".gz"; return; + } if (FileName == DestFile) Erase = true; else Local = true; - string compExt = flExtension(flNotDir(URI(Desc.URI).Path)); string decompProg; // If we enable compressed indexes and already have gzip, keep it -- cgit v1.2.3 From a5de4117b60617ace639fb1e09e8903279185c2e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 19 Jun 2010 09:13:33 +0200 Subject: fix the gcc warning about the initialisation order of variables caused by moving Policy to public again (and therefore after SrcList) --- apt-pkg/cachefile.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cachefile.cc b/apt-pkg/cachefile.cc index 01598386c..964c5bd8b 100644 --- a/apt-pkg/cachefile.cc +++ b/apt-pkg/cachefile.cc @@ -28,7 +28,7 @@ // --------------------------------------------------------------------- /* */ pkgCacheFile::pkgCacheFile() : Map(NULL), Cache(NULL), DCache(NULL), - Policy(NULL), SrcList(NULL) + SrcList(NULL), Policy(NULL) { } /*}}}*/ -- cgit v1.2.3 From c4fc2fd7fa0fc63fd8cd6bc9b73492e6baf0222a Mon Sep 17 00:00:00 2001 From: "martin@piware.de" <> Date: Thu, 24 Jun 2010 21:27:27 +0200 Subject: Switch FileFd to not transparently gunzip, since that breaks code which expects the compressed contents to stay (such as the copy backend, or when using file:// repositories. Instead, introduce a new ReadOnlyGzip mode and use that where needed --- apt-pkg/acquire-item.cc | 4 ++-- apt-pkg/contrib/fileutl.cc | 14 +++++++++----- apt-pkg/contrib/fileutl.h | 2 +- apt-pkg/deb/debindexfile.cc | 6 +++--- apt-pkg/deb/debrecords.cc | 2 +- apt-pkg/deb/debsrcrecords.h | 2 +- 6 files changed, 17 insertions(+), 13 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index fe81ee791..9abdb0ad0 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -228,7 +228,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ ss >> ServerSha1 >> size; unsigned long const ServerSize = atol(size.c_str()); - FileFd fd(CurrentPackagesFile, FileFd::ReadOnly); + FileFd fd(CurrentPackagesFile, FileFd::ReadOnlyGzip); SHA1Summation SHA1; SHA1.AddFD(fd.Fd(), fd.Size()); string const local_sha1 = SHA1.Result(); @@ -459,7 +459,7 @@ bool pkgAcqIndexDiffs::QueueNextDiff() /*{{{*/ string FinalFile = _config->FindDir("Dir::State::lists"); FinalFile += URItoFileName(RealURI); - FileFd fd(FinalFile, FileFd::ReadOnly); + FileFd fd(FinalFile, FileFd::ReadOnlyGzip); SHA1Summation SHA1; SHA1.AddFD(fd.Fd(), fd.Size()); string local_sha1 = string(SHA1.Result()); diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 11a9e7f7b..2b91a46f7 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -604,12 +604,16 @@ bool FileFd::Open(string FileName,OpenMode Mode, unsigned long Perms) { case ReadOnly: iFd = open(FileName.c_str(),O_RDONLY); + break; + + case ReadOnlyGzip: + iFd = open(FileName.c_str(),O_RDONLY); if (iFd > 0 && FileName.compare(FileName.size()-3, 3, ".gz") == 0) { - gz = gzdopen (iFd, "r"); - if (gz == NULL) { - close (iFd); - iFd = -1; - } + gz = gzdopen (iFd, "r"); + if (gz == NULL) { + close (iFd); + iFd = -1; + } } break; diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 9925bbed4..c4b282126 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -41,7 +41,7 @@ class FileFd gzFile gz; public: - enum OpenMode {ReadOnly,WriteEmpty,WriteExists,WriteAny,WriteTemp}; + enum OpenMode {ReadOnly,WriteEmpty,WriteExists,WriteAny,WriteTemp,ReadOnlyGzip}; inline bool Read(void *To,unsigned long Size,bool AllowEof) { diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index 9832329c0..7d7bd09fb 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -273,7 +273,7 @@ unsigned long debPackagesIndex::Size() const bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const { string PackageFile = IndexFile("Packages"); - FileFd Pkg(PackageFile,FileFd::ReadOnly); + FileFd Pkg(PackageFile,FileFd::ReadOnlyGzip); debListParser Parser(&Pkg); if (_error->PendingError() == true) return _error->Error("Problem opening %s",PackageFile.c_str()); @@ -464,7 +464,7 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const string TranslationFile = IndexFile(Language); if (TranslationsAvailable() && FileExists(TranslationFile)) { - FileFd Trans(TranslationFile,FileFd::ReadOnly); + FileFd Trans(TranslationFile,FileFd::ReadOnlyGzip); debListParser TransParser(&Trans); if (_error->PendingError() == true) return false; @@ -544,7 +544,7 @@ unsigned long debStatusIndex::Size() const /* */ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const { - FileFd Pkg(File,FileFd::ReadOnly); + FileFd Pkg(File,FileFd::ReadOnlyGzip); if (_error->PendingError() == true) return false; debListParser Parser(&Pkg); diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc index 34ef0d8f2..ec9e395ef 100644 --- a/apt-pkg/deb/debrecords.cc +++ b/apt-pkg/deb/debrecords.cc @@ -19,7 +19,7 @@ // --------------------------------------------------------------------- /* */ debRecordParser::debRecordParser(string FileName,pkgCache &Cache) : - File(FileName,FileFd::ReadOnly), + File(FileName,FileFd::ReadOnlyGzip), Tags(&File, std::max(Cache.Head().MaxVerFileSize, Cache.Head().MaxDescFileSize) + 200) { diff --git a/apt-pkg/deb/debsrcrecords.h b/apt-pkg/deb/debsrcrecords.h index c39d78bae..905264daa 100644 --- a/apt-pkg/deb/debsrcrecords.h +++ b/apt-pkg/deb/debsrcrecords.h @@ -48,7 +48,7 @@ class debSrcRecordParser : public pkgSrcRecords::Parser virtual bool Files(vector &F); debSrcRecordParser(string const &File,pkgIndexFile const *Index) - : Parser(Index), Fd(File,FileFd::ReadOnly), Tags(&Fd,102400), + : Parser(Index), Fd(File,FileFd::ReadOnlyGzip), Tags(&Fd,102400), Buffer(0), BufSize(0) {} ~debSrcRecordParser(); }; -- cgit v1.2.3 From 7aeee3653d7d0dc34769bb74a2bf4824b438834f Mon Sep 17 00:00:00 2001 From: "martin@piware.de" <> Date: Thu, 24 Jun 2010 22:43:07 +0200 Subject: apt-pkg/acquire-item.cc: Fix handling of local (file:/) sources --- apt-pkg/acquire-item.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 9abdb0ad0..a506aa9aa 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -757,7 +757,7 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash, string decompProg; // If we enable compressed indexes and already have gzip, keep it - if (_config->FindB("Acquire::GzipIndexes",false) && compExt == "gz") { + if (_config->FindB("Acquire::GzipIndexes",false) && compExt == "gz" && !Local) { string FinalFile = _config->FindDir("Dir::State::lists"); FinalFile += URItoFileName(RealURI) + ".gz"; //if(Debug) -- cgit v1.2.3 From 98ee7cd35cf205c52b3698ee91cec76d704a3937 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 25 Jun 2010 08:01:48 +0200 Subject: * apt-pkg/contrib/error.{cc,h}: - complete rewrite but use the same API - add NOTICE and DEBUG as new types of a message --- apt-pkg/contrib/error.cc | 333 ++++++++++++++++++++++------------------------- apt-pkg/contrib/error.h | 230 +++++++++++++++++++++++++++----- 2 files changed, 356 insertions(+), 207 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc index 927b7e05c..837d9e615 100644 --- a/apt-pkg/contrib/error.cc +++ b/apt-pkg/contrib/error.cc @@ -1,16 +1,15 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: error.cc,v 1.11 2002/03/26 07:38:58 jgg Exp $ /* ###################################################################### - - Global Erorr Class - Global error mechanism + + Global Error Class - Global error mechanism We use a simple STL vector to store each error record. A PendingFlag is kept which indicates when the vector contains a Sever error. - + This source is placed in the Public Domain, do with it what you will It was originally written by Jason Gunthorpe. - + ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ @@ -19,7 +18,6 @@ #include #include #include -#include #include #include @@ -28,209 +26,188 @@ #include "config.h" /*}}}*/ -using namespace std; - // Global Error Object /*{{{*/ /* If the implementation supports posix threads then the accessor function is compiled to be thread safe otherwise a non-safe version is used. A Per-Thread error object is maintained in much the same manner as libc manages errno */ #if defined(_POSIX_THREADS) && defined(HAVE_PTHREAD) - #include - - static pthread_key_t ErrorKey; - static void ErrorDestroy(void *Obj) {delete (GlobalError *)Obj;}; - static void KeyAlloc() {pthread_key_create(&ErrorKey,ErrorDestroy);}; - - GlobalError *_GetErrorObj() - { - static pthread_once_t Once = PTHREAD_ONCE_INIT; - pthread_once(&Once,KeyAlloc); - - void *Res = pthread_getspecific(ErrorKey); - if (Res == 0) - pthread_setspecific(ErrorKey,Res = new GlobalError); - return (GlobalError *)Res; - } + #include + + static pthread_key_t ErrorKey; + static void ErrorDestroy(void *Obj) {delete (GlobalError *)Obj;}; + static void KeyAlloc() {pthread_key_create(&ErrorKey,ErrorDestroy);}; + + GlobalError *_GetErrorObj() { + static pthread_once_t Once = PTHREAD_ONCE_INIT; + pthread_once(&Once,KeyAlloc); + + void *Res = pthread_getspecific(ErrorKey); + if (Res == 0) + pthread_setspecific(ErrorKey,Res = new GlobalError); + return (GlobalError *)Res; + } #else - GlobalError *_GetErrorObj() - { - static GlobalError *Obj = new GlobalError; - return Obj; - } + GlobalError *_GetErrorObj() { + static GlobalError *Obj = new GlobalError; + return Obj; + } #endif /*}}}*/ - // GlobalError::GlobalError - Constructor /*{{{*/ -// --------------------------------------------------------------------- -/* */ -GlobalError::GlobalError() : List(0), PendingFlag(false) -{ +GlobalError::GlobalError() : PendingFlag(false) {} + /*}}}*/ +// GlobalError::FatalE - Get part of the error string from errno /*{{{*/ +bool GlobalError::FatalE(const char *Function,const char *Description,...) { + va_list args; + va_start(args,Description); + return InsertErrno(FATAL, Function, Description, args); } /*}}}*/ // GlobalError::Errno - Get part of the error string from errno /*{{{*/ -// --------------------------------------------------------------------- -/* Function indicates the stdlib function that failed and Description is - a user string that leads the text. Form is: - Description - Function (errno: strerror) - Carefull of the buffer overrun, sprintf. - */ -bool GlobalError::Errno(const char *Function,const char *Description,...) -{ - va_list args; - va_start(args,Description); - - // sprintf the description - char S[400]; - vsnprintf(S,sizeof(S),Description,args); - snprintf(S + strlen(S),sizeof(S) - strlen(S), - " - %s (%i: %s)",Function,errno,strerror(errno)); - - // Put it on the list - Item *Itm = new Item; - Itm->Text = S; - Itm->Error = true; - Insert(Itm); - - PendingFlag = true; - - return false; +bool GlobalError::Errno(const char *Function,const char *Description,...) { + va_list args; + va_start(args,Description); + return InsertErrno(ERROR, Function, Description, args); } /*}}}*/ -// GlobalError::WarningE - Get part of the warn string from errno /*{{{*/ -// --------------------------------------------------------------------- -/* Function indicates the stdlib function that failed and Description is - a user string that leads the text. Form is: - Description - Function (errno: strerror) - Carefull of the buffer overrun, sprintf. - */ -bool GlobalError::WarningE(const char *Function,const char *Description,...) -{ - va_list args; - va_start(args,Description); - - // sprintf the description - char S[400]; - vsnprintf(S,sizeof(S),Description,args); - snprintf(S + strlen(S),sizeof(S) - strlen(S), - " - %s (%i: %s)",Function,errno,strerror(errno)); - - // Put it on the list - Item *Itm = new Item; - Itm->Text = S; - Itm->Error = false; - Insert(Itm); - - return false; +// GlobalError::WarningE - Get part of the warning string from errno /*{{{*/ +bool GlobalError::WarningE(const char *Function,const char *Description,...) { + va_list args; + va_start(args,Description); + return InsertErrno(WARNING, Function, Description, args); +} + /*}}}*/ +// GlobalError::NoticeE - Get part of the notice string from errno /*{{{*/ +bool GlobalError::NoticeE(const char *Function,const char *Description,...) { + va_list args; + va_start(args,Description); + return InsertErrno(NOTICE, Function, Description, args); +} + /*}}}*/ +// GlobalError::DebugE - Get part of the debug string from errno /*{{{*/ +bool GlobalError::DebugE(const char *Function,const char *Description,...) { + va_list args; + va_start(args,Description); + return InsertErrno(DEBUG, Function, Description, args); +} + /*}}}*/ +// GlobalError::InsertErrno - formats an error message with the errno /*{{{*/ +bool GlobalError::InsertErrno(MsgType type, const char* Function, + const char* Description, va_list const &args) { + char S[400]; + vsnprintf(S,sizeof(S),Description,args); + snprintf(S + strlen(S),sizeof(S) - strlen(S), + " - %s (%i: %s)", Function, errno, strerror(errno)); + return Insert(type, S, args); +} + /*}}}*/ +// GlobalError::Fatal - Add a fatal error to the list /*{{{*/ +bool GlobalError::Fatal(const char *Description,...) { + va_list args; + va_start(args,Description); + return Insert(FATAL, Description, args); } /*}}}*/ // GlobalError::Error - Add an error to the list /*{{{*/ -// --------------------------------------------------------------------- -/* Just vsprintfs and pushes */ -bool GlobalError::Error(const char *Description,...) -{ - va_list args; - va_start(args,Description); - - // sprintf the description - char S[400]; - vsnprintf(S,sizeof(S),Description,args); - - // Put it on the list - Item *Itm = new Item; - Itm->Text = S; - Itm->Error = true; - Insert(Itm); - - PendingFlag = true; - - return false; +bool GlobalError::Error(const char *Description,...) { + va_list args; + va_start(args,Description); + return Insert(ERROR, Description, args); } /*}}}*/ // GlobalError::Warning - Add a warning to the list /*{{{*/ -// --------------------------------------------------------------------- -/* This doesn't set the pending error flag */ -bool GlobalError::Warning(const char *Description,...) +bool GlobalError::Warning(const char *Description,...) { + va_list args; + va_start(args,Description); + return Insert(WARNING, Description, args); +} + /*}}}*/ +// GlobalError::Notice - Add a notice to the list /*{{{*/ +bool GlobalError::Notice(const char *Description,...) { - va_list args; - va_start(args,Description); - - // sprintf the description - char S[400]; - vsnprintf(S,sizeof(S),Description,args); - - // Put it on the list - Item *Itm = new Item; - Itm->Text = S; - Itm->Error = false; - Insert(Itm); - - return false; + va_list args; + va_start(args,Description); + return Insert(NOTICE, Description, args); } /*}}}*/ -// GlobalError::PopMessage - Pulls a single message out /*{{{*/ -// --------------------------------------------------------------------- -/* This should be used in a loop checking empty() each cycle. It returns - true if the message is an error. */ -bool GlobalError::PopMessage(string &Text) +// GlobalError::Debug - Add a debug to the list /*{{{*/ +bool GlobalError::Debug(const char *Description,...) { - if (List == 0) - return false; - - bool Ret = List->Error; - Text = List->Text; - Item *Old = List; - List = List->Next; - delete Old; - - // This really should check the list to see if only warnings are left.. - if (List == 0) - PendingFlag = false; - - return Ret; + va_list args; + va_start(args,Description); + return Insert(DEBUG, Description, args); +} + /*}}}*/ +// GlobalError::Insert - Insert a new item at the end /*{{{*/ +bool GlobalError::Insert(MsgType type, const char* Description, + va_list const &args) { + char S[400]; + vsnprintf(S,sizeof(S),Description,args); + + Item const m(S, type); + Messages.push_back(m); + + if (type == ERROR || type == FATAL) + PendingFlag = true; + + if (type == FATAL || type == DEBUG) + std::clog << m << std::endl; + + return false; +} + /*}}}*/ +// GlobalError::PopMessage - Pulls a single message out /*{{{*/ +bool GlobalError::PopMessage(std::string &Text) { + if (Messages.empty() == true) + return false; + + Item const msg = Messages.front(); + Messages.pop_front(); + + bool const Ret = (msg.Type == ERROR || msg.Type == FATAL); + Text = msg.Text; + if (PendingFlag == false || Ret == false) + return Ret; + + // check if another error message is pending + for (std::list::const_iterator m = Messages.begin(); + m != Messages.end(); m++) + if (m->Type == ERROR || m->Type == FATAL) + return Ret; + + PendingFlag = false; + return Ret; } /*}}}*/ // GlobalError::DumpErrors - Dump all of the errors/warns to cerr /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void GlobalError::DumpErrors() -{ - // Print any errors or warnings found - string Err; - while (empty() == false) - { - bool Type = PopMessage(Err); - if (Type == true) - cerr << "E: " << Err << endl; - else - cerr << "W: " << Err << endl; - } +void GlobalError::DumpErrors(std::ostream &out, MsgType const &trashhold) { + for (std::list::const_iterator m = Messages.begin(); + m != Messages.end(); m++) + if (m->Type >= trashhold) + out << (*m) << std::endl; + Discard(); } /*}}}*/ -// GlobalError::Discard - Discard /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void GlobalError::Discard() -{ - while (List != 0) - { - Item *Old = List; - List = List->Next; - delete Old; - } - - PendingFlag = false; +// GlobalError::Discard - Discard /*{{{*/ +void GlobalError::Discard() { + Messages.clear(); + PendingFlag = false; }; /*}}}*/ -// GlobalError::Insert - Insert a new item at the end /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void GlobalError::Insert(Item *Itm) -{ - Item **End = &List; - for (Item *I = List; I != 0; I = I->Next) - End = &I->Next; - Itm->Next = *End; - *End = Itm; +// GlobalError::empty - does our error list include anything? /*{{{*/ +bool GlobalError::empty(MsgType const &trashhold) const { + if (PendingFlag == true) + return false; + + if (Messages.empty() == true) + return true; + + for (std::list::const_iterator m = Messages.begin(); + m != Messages.end(); m++) + if (m->Type >= trashhold) + return false; + + return true; } /*}}}*/ diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h index 8d5ec05ea..fc7b38f1b 100644 --- a/apt-pkg/contrib/error.h +++ b/apt-pkg/contrib/error.h @@ -42,43 +42,215 @@ #include +#include +#include #include -class GlobalError +#include + +class GlobalError /*{{{*/ { - struct Item - { - std::string Text; - bool Error; - Item *Next; - }; - - Item *List; - bool PendingFlag; - void Insert(Item *I); - - public: +public: /*{{{*/ + /** \brief a message can have one of following severity */ + enum MsgType { + /** \brief Message will be printed instantly as it is likely that + this error will lead to a complete crash */ + FATAL = 40, + /** \brief An error does hinder the correct execution and should be corrected */ + ERROR = 30, + /** \brief indicates problem that can lead to errors later on */ + WARNING = 20, + /** \brief deprecation warnings, old fallback behavior, … */ + NOTICE = 10, + /** \brief for developers only in areas it is hard to print something directly */ + DEBUG = 0 + }; - // Call to generate an error from a library call. - bool Errno(const char *Function,const char *Description,...) __like_printf(3) __cold; - bool WarningE(const char *Function,const char *Description,...) __like_printf(3) __cold; + /** \brief add a fatal error message with errno to the list + * + * \param Function name of the function generating the error + * \param Description format string for the error message + * + * \return \b false + */ + bool FatalE(const char *Function,const char *Description,...) __like_printf(3) __cold; - /* A warning should be considered less severe than an error, and may be - ignored by the client. */ - bool Error(const char *Description,...) __like_printf(2) __cold; - bool Warning(const char *Description,...) __like_printf(2) __cold; + /** \brief add an Error message with errno to the list + * + * \param Function name of the function generating the error + * \param Description format string for the error message + * + * \return \b false + */ + bool Errno(const char *Function,const char *Description,...) __like_printf(3) __cold; - // Simple accessors - inline bool PendingError() {return PendingFlag;}; - inline bool empty() {return List == 0;}; - bool PopMessage(std::string &Text); - void Discard(); + /** \brief add a warning message with errno to the list + * + * A warning should be considered less severe than an error and + * may be ignored by the client. + * + * \param Function Name of the function generates the warning. + * \param Description Format string for the warning message. + * + * \return \b false + */ + bool WarningE(const char *Function,const char *Description,...) __like_printf(3) __cold; - // Usefull routine to dump to cerr - void DumpErrors(); - - GlobalError(); + /** \brief add a notice message with errno to the list + * + * \param Function name of the function generating the error + * \param Description format string for the error message + * + * \return \b false + */ + bool NoticeE(const char *Function,const char *Description,...) __like_printf(3) __cold; + + /** \brief add a debug message with errno to the list + * + * \param Function name of the function generating the error + * \param Description format string for the error message + * + * \return \b false + */ + bool DebugE(const char *Function,const char *Description,...) __like_printf(3) __cold; + + /** \brief add an fatal error message to the list + * + * Most of the stuff we consider as "error" is also "fatal" for + * the user as the application will not have the expected result, + * but a fatal message here means that it gets printed directly + * to stderr in addiction to adding it to the list as the error + * leads sometimes to crashes and a maybe duplicated message + * is better than "Segfault" as the only displayed text + * + * \param Description Format string for the fatal error message. + * + * \return \b false + */ + bool Fatal(const char *Description,...) __like_printf(2) __cold; + + /** \brief add an Error message to the list + * + * \param Description Format string for the error message. + * + * \return \b false + */ + bool Error(const char *Description,...) __like_printf(2) __cold; + + /** \brief add a warning message to the list + * + * A warning should be considered less severe than an error and + * may be ignored by the client. + * + * \param Description Format string for the message + * + * \return \b false + */ + bool Warning(const char *Description,...) __like_printf(2) __cold; + + /** \brief add a notice message to the list + * + * A notice should be considered less severe than an error or a + * warning and can be ignored by the client without further problems + * for some times, but he should consider fixing the problem. + * This error type can be used for e.g. deprecation warnings of options. + * + * \param Description Format string for the message + * + * \return \b false + */ + bool Notice(const char *Description,...) __like_printf(2) __cold; + + /** \brief add a debug message to the list + * + * \param Description Format string for the message + * + * \return \b false + */ + bool Debug(const char *Description,...) __like_printf(2) __cold; + + /** \brief is an error in the list? + * + * \return \b true if an error is included in the list, \b false otherwise + */ + inline bool PendingError() const {return PendingFlag;}; + + /** \brief is the list empty? + * + * The default checks if the list is empty or contains only notices, + * if you want to check if also no notices happend set the parameter + * flag to \b false. + * + * \param WithoutNotice does notices count, default is \b true, so no + * + * \return \b true if an the list is empty, \b false otherwise + */ + bool empty(MsgType const &trashhold = WARNING) const; + + /** \brief returns and removes the first (or last) message in the list + * + * \param[out] Text message of the first/last item + * + * \return \b true if the message was an error, \b false otherwise + */ + bool PopMessage(std::string &Text); + + /** \brief clears the list of messages */ + void Discard(); + + /** \brief outputs the list of messages to the given stream + * + * Note that all messages are discarded, also the notices + * displayed or not. + * + * \param[out] out output stream to write the messages in + * \param WithoutNotice output notices or not + */ + void DumpErrors(std::ostream &out, MsgType const &trashhold = WARNING); + + /** \brief dumps the list of messages to std::cerr + * + * Note that all messages are discarded, also the notices + * displayed or not. + * + * \param WithoutNotice print notices or not + */ + void inline DumpErrors(MsgType const &trashhold = WARNING) { + DumpErrors(std::cerr, trashhold); + } + + GlobalError(); + /*}}}*/ +private: /*{{{*/ + struct Item { + std::string Text; + MsgType Type; + + Item(char const *Text, MsgType const &Type) : + Text(Text), Type(Type) {}; + + friend std::ostream& operator<< (std::ostream &out, Item i) { + switch(i.Type) { + case FATAL: + case ERROR: out << "E"; break; + case WARNING: out << "W"; break; + case NOTICE: out << "N"; break; + case DEBUG: out << "D"; break; + } + return out << ": " << i.Text; + } + }; + + std::list Messages; + bool PendingFlag; + + bool InsertErrno(MsgType type, const char* Function, + const char* Description, va_list const &args); + bool Insert(MsgType type, const char* Description, + va_list const &args); + /*}}}*/ }; + /*}}}*/ // The 'extra-ansi' syntax is used to help with collisions. GlobalError *_GetErrorObj(); -- cgit v1.2.3 From c4ba7c44ff03d67ff982bbab26dc48d796041e02 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 25 Jun 2010 19:16:12 +0200 Subject: add a simple stack handling to be able to delay error handling --- apt-pkg/contrib/error.cc | 32 +++++++++++++++++++++++++++++++- apt-pkg/contrib/error.h | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc index 837d9e615..8cee21c9c 100644 --- a/apt-pkg/contrib/error.cc +++ b/apt-pkg/contrib/error.cc @@ -181,7 +181,13 @@ bool GlobalError::PopMessage(std::string &Text) { } /*}}}*/ // GlobalError::DumpErrors - Dump all of the errors/warns to cerr /*{{{*/ -void GlobalError::DumpErrors(std::ostream &out, MsgType const &trashhold) { +void GlobalError::DumpErrors(std::ostream &out, MsgType const &trashhold, + bool const &mergeStack) { + if (mergeStack == true) + for (std::list::const_reverse_iterator s = Stacks.rbegin(); + s != Stacks.rend(); ++s) + Messages.insert(Messages.begin(), s->Messages.begin(), s->Messages.end()); + for (std::list::const_iterator m = Messages.begin(); m != Messages.end(); m++) if (m->Type >= trashhold) @@ -211,3 +217,27 @@ bool GlobalError::empty(MsgType const &trashhold) const { return true; } /*}}}*/ +// GlobalError::PushToStack /*{{{*/ +void GlobalError::PushToStack() { + MsgStack pack(Messages, PendingFlag); + Stacks.push_back(pack); + Discard(); +} + /*}}}*/ +// GlobalError::RevertToStack /*{{{*/ +void GlobalError::RevertToStack() { + Discard(); + MsgStack pack = Stacks.back(); + Messages = pack.Messages; + PendingFlag = pack.PendingFlag; + Stacks.pop_back(); +} + /*}}}*/ +// GlobalError::MergeWithStack /*{{{*/ +void GlobalError::MergeWithStack() { + MsgStack pack = Stacks.back(); + Messages.insert(Messages.begin(), pack.Messages.begin(), pack.Messages.end()); + PendingFlag = PendingFlag || pack.PendingFlag; + Stacks.pop_back(); +} + /*}}}*/ diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h index fc7b38f1b..73735162d 100644 --- a/apt-pkg/contrib/error.h +++ b/apt-pkg/contrib/error.h @@ -206,7 +206,8 @@ public: /*{{{*/ * \param[out] out output stream to write the messages in * \param WithoutNotice output notices or not */ - void DumpErrors(std::ostream &out, MsgType const &trashhold = WARNING); + void DumpErrors(std::ostream &out, MsgType const &trashhold = WARNING, + bool const &mergeStack = true); /** \brief dumps the list of messages to std::cerr * @@ -219,6 +220,28 @@ public: /*{{{*/ DumpErrors(std::cerr, trashhold); } + /** \brief put the current Messages into the stack + * + * All "old" messages will be pushed into a stack to + * them later back, but for now the Message query will be + * empty and performs as no messages were present before. + * + * The stack can be as deep as you want - all stack operations + * will only operate on the last element in the stack. + */ + void PushToStack(); + + /** \brief throw away all current messages */ + void RevertToStack(); + + /** \brief merge current and stack together */ + void MergeWithStack(); + + /** \brief return the deep of the stack */ + size_t StackCount() const { + return Stacks.size(); + } + GlobalError(); /*}}}*/ private: /*{{{*/ @@ -244,6 +267,16 @@ private: /*{{{*/ std::list Messages; bool PendingFlag; + struct MsgStack { + std::list const Messages; + bool const PendingFlag; + + MsgStack(std::list const &Messages, bool const &Pending) : + Messages(Messages), PendingFlag(Pending) {}; + }; + + std::list Stacks; + bool InsertErrno(MsgType type, const char* Function, const char* Description, va_list const &args); bool Insert(MsgType type, const char* Description, -- cgit v1.2.3 From 9f9717fa6bca13817cf9cf84d513e59d258af154 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 26 Jun 2010 09:03:26 +0200 Subject: * apt-pkg/aptconfiguration.cc: - show a deprecation notice for APT::Acquire::Translation --- apt-pkg/aptconfiguration.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 0c050d9dc..44f1f318a 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -10,6 +10,7 @@ // Include Files /*{{{*/ #include #include +#include #include #include #include @@ -196,6 +197,9 @@ std::vector const Configuration::getLanguages(bool const &All, // 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") { + // TRANSLATORS: the two %s are APT configuration options + _error->Notice("Option '%s' is deprecated. Please use '%s' instead, see 'man 5 apt.conf' for details.", + "APT::Acquire::Translation", "Acquire::Languages"); if (oldAcquire != "none") codes.push_back(oldAcquire); codes.push_back("en"); -- cgit v1.2.3 From 1f2933a8de0f3a26f51b4a0a2112cbdfd4461e9b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 26 Jun 2010 13:29:24 +0200 Subject: - use the new MatchAgainstConfig for the DefaultRootSetFunc * apt-pkg/contrib/configuration.{cc,h}: - add a wrapper to match strings against configurable regex patterns --- apt-pkg/contrib/configuration.cc | 43 +++++++++++++++++++++++++++++++++++ apt-pkg/contrib/configuration.h | 19 +++++++++++++++- apt-pkg/depcache.cc | 48 ---------------------------------------- apt-pkg/depcache.h | 22 +++++------------- 4 files changed, 67 insertions(+), 65 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc index 9129d92f0..81cc87d15 100644 --- a/apt-pkg/contrib/configuration.cc +++ b/apt-pkg/contrib/configuration.cc @@ -843,3 +843,46 @@ bool ReadConfigDir(Configuration &Conf,const string &Dir, return true; } /*}}}*/ +// MatchAgainstConfig Constructor /*{{{*/ +Configuration::MatchAgainstConfig::MatchAgainstConfig(char const * Config) +{ + std::vector const strings = _config->FindVector(Config); + for (std::vector::const_iterator s = strings.begin(); + s != strings.end(); ++s) + { + regex_t *p = new regex_t; + if (regcomp(p, s->c_str(), REG_EXTENDED | REG_ICASE | REG_NOSUB) == 0) + patterns.push_back(p); + else + { + regfree(p); + delete p; + _error->Warning("Regex compilation error for '%s' in configuration option '%s'", + s->c_str(), Config); + } + } + +} + /*}}}*/ +// MatchAgainstConfig Destructor /*{{{*/ +Configuration::MatchAgainstConfig::~MatchAgainstConfig() +{ + for(std::vector::const_iterator p = patterns.begin(); + p != patterns.end(); ++p) + { + regfree(*p); + delete *p; + } +} + /*}}}*/ +// MatchAgainstConfig::Match - returns true if a pattern matches /*{{{*/ +bool Configuration::MatchAgainstConfig::Match(char const * str) const +{ + for(std::vector::const_iterator p = patterns.begin(); + p != patterns.end(); ++p) + if (regexec(*p, str, 0, 0, 0) == 0) + return true; + + return false; +} + /*}}}*/ diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h index 2494c1d7c..cbe18e4e5 100644 --- a/apt-pkg/contrib/configuration.h +++ b/apt-pkg/contrib/configuration.h @@ -28,7 +28,7 @@ #ifndef PKGLIB_CONFIGURATION_H #define PKGLIB_CONFIGURATION_H - +#include #include #include @@ -104,6 +104,23 @@ class Configuration Configuration(const Item *Root); Configuration(); ~Configuration(); + + /** \brief match a string against a configurable list of patterns */ + class MatchAgainstConfig + { + std::vector patterns; + + public: + MatchAgainstConfig(char const * Config); + virtual ~MatchAgainstConfig(); + + /** \brief Returns \b true for a string matching one of the patterns */ + bool Match(char const * str) const; + bool Match(std::string const &str) const { return Match(str.c_str()); }; + + /** \brief returns if the matcher setup was successful */ + bool wasConstructedSuccessfully() const { return patterns.empty() == false; } + }; }; extern Configuration *_config; diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index d082b8404..8bca3e36e 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1635,54 +1635,6 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep) else if(Dep->Type == pkgCache::Dep::Suggests) return _config->FindB("APT::Install-Suggests", false); - return false; -} - /*}}}*/ -pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc() /*{{{*/ - : constructedSuccessfully(false) -{ - Configuration::Item const *Opts; - Opts = _config->Tree("APT::NeverAutoRemove"); - if (Opts != 0 && Opts->Child != 0) - { - Opts = Opts->Child; - for (; Opts != 0; Opts = Opts->Next) - { - if (Opts->Value.empty() == true) - continue; - - regex_t *p = new regex_t; - if(regcomp(p,Opts->Value.c_str(), - REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0) - { - regfree(p); - delete p; - _error->Error("Regex compilation error for APT::NeverAutoRemove"); - return; - } - - rootSetRegexp.push_back(p); - } - } - - constructedSuccessfully = true; -} - /*}}}*/ -pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc() /*{{{*/ -{ - for(unsigned int i = 0; i < rootSetRegexp.size(); i++) - { - regfree(rootSetRegexp[i]); - delete rootSetRegexp[i]; - } -} - /*}}}*/ -bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg) /*{{{*/ -{ - for(unsigned int i = 0; i < rootSetRegexp.size(); i++) - if (regexec(rootSetRegexp[i], pkg.Name(), 0, 0, 0) == 0) - return true; - return false; } /*}}}*/ diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 72d7cce5d..66c099b80 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -38,11 +38,10 @@ #ifndef PKGLIB_DEPCACHE_H #define PKGLIB_DEPCACHE_H - +#include #include #include - -#include +#include #include #include @@ -184,22 +183,13 @@ class pkgDepCache : protected pkgCache::Namespace /** \brief Returns \b true for packages matching a regular * expression in APT::NeverAutoRemove. */ - class DefaultRootSetFunc : public InRootSetFunc + class DefaultRootSetFunc : public InRootSetFunc, public Configuration::MatchAgainstConfig { - std::vector rootSetRegexp; - bool constructedSuccessfully; - public: - DefaultRootSetFunc(); - ~DefaultRootSetFunc(); - - /** \return \b true if the class initialized successfully, \b - * false otherwise. Used to avoid throwing an exception, since - * APT classes generally don't. - */ - bool wasConstructedSuccessfully() const { return constructedSuccessfully; } + DefaultRootSetFunc() : Configuration::MatchAgainstConfig("APT::NeverRemove") {}; + virtual ~DefaultRootSetFunc() {}; - bool InRootSet(const pkgCache::PkgIterator &pkg); + bool InRootSet(const pkgCache::PkgIterator &pkg) { return pkg.end() == true && Match(pkg.Name()); }; }; struct StateCache -- cgit v1.2.3 From 1408e219e76e577fb84ef1c48e58337b6569feec Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 26 Jun 2010 18:40:15 +0200 Subject: * apt-pkg/contrib/fileutl.cc: - show notice about ignored file instead of being always silent - add a Dir::Ignore-Files-Silently list option to control the notice * --- apt-pkg/contrib/fileutl.cc | 4 ++++ apt-pkg/init.cc | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 16f7ce929..e95ddf562 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -281,6 +281,7 @@ std::vector GetListOfFilesInDir(string const &Dir, std::vector c } std::vector List; + Configuration::MatchAgainstConfig SilentIgnore("Dir::Ignore-Files-Silently"); DIR *D = opendir(Dir.c_str()); if (D == 0) { @@ -306,6 +307,7 @@ std::vector GetListOfFilesInDir(string const &Dir, std::vector c { if (Debug == true) std::clog << "Bad file: " << Ent->d_name << " → no extension" << std::endl; + _error->Notice("Ignoring file '%s' in directory '%s' as it has no filename extension", Ent->d_name, Dir.c_str()); continue; } } @@ -313,6 +315,8 @@ std::vector GetListOfFilesInDir(string const &Dir, std::vector c { if (Debug == true) std::clog << "Bad file: " << Ent->d_name << " → bad extension »" << flExtension(Ent->d_name) << "«" << std::endl; + if (SilentIgnore.Match(Ent->d_name) == false) + _error->Notice("Ignoring file '%s' in directory '%s' as it has an invalid filename extension", Ent->d_name, Dir.c_str()); continue; } } diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc index 21472eb3b..7a332c86e 100644 --- a/apt-pkg/init.cc +++ b/apt-pkg/init.cc @@ -78,6 +78,11 @@ bool pkgInitConfig(Configuration &Cnf) Cnf.Set("Dir::Log::Terminal","term.log"); Cnf.Set("Dir::Log::History","history.log"); + Cnf.Set("Dir::Ignore-Files-Silently::", "~$"); + Cnf.Set("Dir::Ignore-Files-Silently::", "\\.disabled$"); + Cnf.Set("Dir::Ignore-Files-Silently::", "\\.bak$"); + Cnf.Set("Dir::Ignore-Files-Silently::", "\\.dpkg-[a-z]+$"); + // Translation Cnf.Set("APT::Acquire::Translation", "environment"); -- cgit v1.2.3 From 5afa55c6703a71a198aac950db30ffc6ca49f269 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 26 Jun 2010 18:42:42 +0200 Subject: make the MMap Grow Error a fatal one as while in theory the code should never segfault it still tend to do it so better show it directly --- apt-pkg/contrib/mmap.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc index d233e51bc..d71066243 100644 --- a/apt-pkg/contrib/mmap.cc +++ b/apt-pkg/contrib/mmap.cc @@ -297,7 +297,7 @@ unsigned long DynamicMMap::RawAllocate(unsigned long Size,unsigned long Aln) { if(!Grow()) { - _error->Error(_("Dynamic MMap ran out of room. Please increase the size " + _error->Fatal(_("Dynamic MMap ran out of room. Please increase the size " "of APT::Cache-Limit. Current value: %lu. (man 5 apt.conf)"), WorkSpace); return 0; } -- cgit v1.2.3 From 5c640e864f8b5f1c175682a94f6c6d0dff42d4bc Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 26 Jun 2010 20:49:47 +0200 Subject: always mark the all package if a pseudo package is marked for install --- apt-pkg/depcache.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 8bca3e36e..c93993ab1 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1255,6 +1255,10 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, Update(Pkg); AddSizes(Pkg); + // always trigger the install of the all package for a pseudo package + if (P.CandidateVerIter(*Cache).Pseudo() == true) + MarkInstall(Pkg.Group().FindPkg("all"), AutoInst, Depth, FromUser, ForceImportantDeps); + if (AutoInst == false) return; -- cgit v1.2.3 From d4af23c2d81116b8f7557ee795059bca126ae9f4 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sat, 26 Jun 2010 20:56:44 +0200 Subject: * apt-pkg/deb/deblistparser.cc: - Handle architecture wildcards (Closes: #547724). --- apt-pkg/deb/deblistparser.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 83c5b8d2e..ddbd0d31a 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -19,6 +19,7 @@ #include #include +#include #include /*}}}*/ @@ -572,8 +573,15 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop, I++; } - if (stringcmp(arch,I,End) == 0) + if (stringcmp(arch,I,End) == 0) { Found = true; + } else { + std::string wildcard = SubstVar(string(I, End), "any", "*"); + if (fnmatch(wildcard.c_str(), arch.c_str(), 0) == 0) + Found = true; + else if (fnmatch(wildcard.c_str(), ("linux-" + arch).c_str(), 0) == 0) + Found = true; + } if (*End++ == ']') { I = End; -- cgit v1.2.3 From 3b20aef1a2b5fd2fcd6f62a819edbdb19631fb98 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sat, 26 Jun 2010 23:01:49 +0200 Subject: apt-pkg/deb/deblistparser.cc: Fix bug in architecture wildcard support. Previously, linux-any was always matched, because the code simply appended linux- to the APT::Architecture value. Now, it does this only if the APT::Architecture value does not contain "-". --- apt-pkg/deb/deblistparser.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index ddbd0d31a..00016679a 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -473,6 +473,14 @@ const char *debListParser::ConvertRelation(const char *I,unsigned int &Op) return I; } +/* + * CompleteArch: + * + * The complete architecture, consisting of -. + */ +static string CompleteArch(std::string& arch) { + return (arch.find("-") != string::npos) ? arch : "linux-" + arch; +} /*}}}*/ // ListParser::ParseDepends - Parse a dependency element /*{{{*/ // --------------------------------------------------------------------- @@ -546,6 +554,7 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop, if (ParseArchFlags == true) { string arch = _config->Find("APT::Architecture"); + string completeArch = CompleteArch(arch); // Parse an architecture if (I != Stop && *I == '[') @@ -577,9 +586,7 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop, Found = true; } else { std::string wildcard = SubstVar(string(I, End), "any", "*"); - if (fnmatch(wildcard.c_str(), arch.c_str(), 0) == 0) - Found = true; - else if (fnmatch(wildcard.c_str(), ("linux-" + arch).c_str(), 0) == 0) + if (fnmatch(wildcard.c_str(), completeArch.c_str(), 0) == 0) Found = true; } -- cgit v1.2.3 From 5143f361005775e3674f4f5871ad574cbe8ef705 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 27 Jun 2010 21:04:53 +0200 Subject: deblistparser: Special-case *-armel, lpia and powerpcspe architectures. --- apt-pkg/deb/deblistparser.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 00016679a..6ede14c4d 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -479,6 +479,12 @@ const char *debListParser::ConvertRelation(const char *I,unsigned int &Op) * The complete architecture, consisting of -. */ static string CompleteArch(std::string& arch) { + if (arch == "armel") return "linux-arm"; + if (arch == "lpia") return "linux-i386"; + if (arch == "powerpcspe") return "linux-powerpc"; + if (arch == "uclibc-linux-armel") return "linux-arm"; + if (arch == "uclinux-armel") return "uclinux-arm"; + return (arch.find("-") != string::npos) ? arch : "linux-" + arch; } /*}}}*/ -- cgit v1.2.3 From ae4a4f91e90fb09a8de1699f18f3b28d095c4d73 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 28 Jun 2010 17:21:14 +0200 Subject: * apt-pkg/versionmatch.cc: - Support matching pins by regular expressions or glob() like patterns, regular expressions have to be put between to slashes; for example, /.*/. --- apt-pkg/versionmatch.cc | 58 +++++++++++++++++++++++++++++++++++++++---------- apt-pkg/versionmatch.h | 2 ++ 2 files changed, 48 insertions(+), 12 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/versionmatch.cc b/apt-pkg/versionmatch.cc index e5f0fafd2..72c9bff2d 100644 --- a/apt-pkg/versionmatch.cc +++ b/apt-pkg/versionmatch.cc @@ -18,6 +18,10 @@ #include #include +#include +#include +#include + /*}}}*/ // VersionMatch::pkgVersionMatch - Constructor /*{{{*/ @@ -162,6 +166,36 @@ pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg) // This will be Ended by now. return Ver; } + +#ifndef FNM_CASEFOLD +#define FNM_CASEFOLD 0 +#endif + +bool pkgVersionMatch::ExpressionMatches(const char *pattern, const char *string) +{ + std::cerr << "MATCH " << pattern; + if (pattern[0] == '/') { + bool res = false; + size_t length = strlen(pattern); + if (pattern[length - 1] == '/') { + regex_t preg; + char *regex = strdup(pattern + 1); + regex[length - 2] = '\0'; + if (regcomp(&preg, regex, REG_EXTENDED | REG_ICASE) != 0) { + std::cerr << "E: Invalid regular expression: " << regex << "\n"; + } else if (regexec(&preg, string, 0, NULL, 0) == 0) { + res = true; + } + free(regex); + return res; + } + } + return fnmatch(pattern, string, FNM_CASEFOLD) == 0; +} +bool pkgVersionMatch::ExpressionMatches(const std::string& pattern, const char *string) +{ + return ExpressionMatches(pattern.c_str(), string); +} /*}}}*/ // VersionMatch::FileMatch - Match against an index file /*{{{*/ // --------------------------------------------------------------------- @@ -185,37 +219,37 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File) if (RelVerStr.empty() == false) if (File->Version == 0 || - MatchVer(File.Version(),RelVerStr,RelVerPrefixMatch) == false) + (MatchVer(File.Version(),RelVerStr,RelVerPrefixMatch) == false && + ExpressionMatches(RelVerStr, File.Version()) == false)) return false; if (RelOrigin.empty() == false) - if (File->Origin == 0 || - stringcasecmp(RelOrigin,File.Origin()) != 0) + if (File->Origin == 0 || !ExpressionMatches(RelOrigin,File.Origin())) return false; if (RelArchive.empty() == false) if (File->Archive == 0 || - stringcasecmp(RelArchive,File.Archive()) != 0) + !ExpressionMatches(RelArchive,File.Archive())) return false; if (RelCodename.empty() == false) if (File->Codename == 0 || - stringcasecmp(RelCodename,File.Codename()) != 0) + !ExpressionMatches(RelCodename,File.Codename())) return false; if (RelRelease.empty() == false) if ((File->Archive == 0 || - stringcasecmp(RelRelease,File.Archive()) != 0) && + !ExpressionMatches(RelRelease,File.Archive())) && (File->Codename == 0 || - stringcasecmp(RelRelease,File.Codename()) != 0)) + !ExpressionMatches(RelRelease,File.Codename()))) return false; if (RelLabel.empty() == false) if (File->Label == 0 || - stringcasecmp(RelLabel,File.Label()) != 0) + !ExpressionMatches(RelLabel,File.Label())) return false; if (RelComponent.empty() == false) if (File->Component == 0 || - stringcasecmp(RelComponent,File.Component()) != 0) + !ExpressionMatches(RelComponent,File.Component())) return false; if (RelArchitecture.empty() == false) if (File->Architecture == 0 || - stringcasecmp(RelArchitecture,File.Architecture()) != 0) + !ExpressionMatches(RelArchitecture,File.Architecture())) return false; return true; } @@ -223,12 +257,12 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File) if (Type == Origin) { if (OrSite.empty() == false) { - if (File->Site == 0 || OrSite != File.Site()) + if (File->Site == 0 || !ExpressionMatches(OrSite, File.Site())) return false; } else // so we are talking about file:// or status file if (strcmp(File.Site(),"") == 0 && File->Archive != 0) // skip the status file return false; - return (OrSite == File.Site()); /* both strings match */ + return (ExpressionMatches(OrSite, File.Site())); /* both strings match */ } return false; diff --git a/apt-pkg/versionmatch.h b/apt-pkg/versionmatch.h index a8da072ae..39639a23d 100644 --- a/apt-pkg/versionmatch.h +++ b/apt-pkg/versionmatch.h @@ -67,6 +67,8 @@ class pkgVersionMatch enum MatchType {None = 0,Version,Release,Origin} Type; bool MatchVer(const char *A,string B,bool Prefix); + bool ExpressionMatches(const char *pattern, const char *string); + bool ExpressionMatches(const std::string& pattern, const char *string); bool FileMatch(pkgCache::PkgFileIterator File); pkgCache::VerIterator Find(pkgCache::PkgIterator Pkg); -- cgit v1.2.3 From 05002864535069dbc35fd1c713ab072a5b6df65f Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 28 Jun 2010 17:29:11 +0200 Subject: Also support regular expressions and glob() patterns in "Pin: version". --- apt-pkg/versionmatch.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/versionmatch.cc b/apt-pkg/versionmatch.cc index 72c9bff2d..2abb73e8d 100644 --- a/apt-pkg/versionmatch.cc +++ b/apt-pkg/versionmatch.cc @@ -155,6 +155,8 @@ pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg) { if (MatchVer(Ver.VerStr(),VerStr,VerPrefixMatch) == true) return Ver; + if (ExpressionMatches(VerStr, Ver.VerStr()) == true) + return Ver; continue; } -- cgit v1.2.3 From 01934fb1fe79cddcc3cb4c79c99c3c30390fdef6 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 28 Jun 2010 17:30:40 +0200 Subject: Remove debugging stuff, this was not meant to be here. --- apt-pkg/versionmatch.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/versionmatch.cc b/apt-pkg/versionmatch.cc index 2abb73e8d..65908f733 100644 --- a/apt-pkg/versionmatch.cc +++ b/apt-pkg/versionmatch.cc @@ -175,7 +175,6 @@ pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg) bool pkgVersionMatch::ExpressionMatches(const char *pattern, const char *string) { - std::cerr << "MATCH " << pattern; if (pattern[0] == '/') { bool res = false; size_t length = strlen(pattern); -- cgit v1.2.3 From 4213f040ac8464d8826b64746c49c21c53a1ab12 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 28 Jun 2010 17:34:54 +0200 Subject: Use _error->Warning() instead of writing to std::cerr. --- apt-pkg/versionmatch.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/versionmatch.cc b/apt-pkg/versionmatch.cc index 65908f733..a269338d6 100644 --- a/apt-pkg/versionmatch.cc +++ b/apt-pkg/versionmatch.cc @@ -183,7 +183,7 @@ bool pkgVersionMatch::ExpressionMatches(const char *pattern, const char *string) char *regex = strdup(pattern + 1); regex[length - 2] = '\0'; if (regcomp(&preg, regex, REG_EXTENDED | REG_ICASE) != 0) { - std::cerr << "E: Invalid regular expression: " << regex << "\n"; + _error->Warning("Invalid regular expression: %s", regex); } else if (regexec(&preg, string, 0, NULL, 0) == 0) { res = true; } -- cgit v1.2.3 From cec9f4f4bb39cc075acded3478d59d0f17d3ed89 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 28 Jun 2010 17:38:08 +0200 Subject: Also free regular expressions. --- apt-pkg/versionmatch.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'apt-pkg') diff --git a/apt-pkg/versionmatch.cc b/apt-pkg/versionmatch.cc index a269338d6..093180f9b 100644 --- a/apt-pkg/versionmatch.cc +++ b/apt-pkg/versionmatch.cc @@ -188,6 +188,7 @@ bool pkgVersionMatch::ExpressionMatches(const char *pattern, const char *string) res = true; } free(regex); + regfree(&preg); return res; } } -- cgit v1.2.3 From 3010fb0e069d2fd4c7a6ade4559bfb659bf8f2fb Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 29 Jun 2010 17:23:24 +0200 Subject: * apt-pkg/contrib/fileutl.cc: - Make FileFd replace files atomically in WriteTemp mode (for cache, etc). --- apt-pkg/contrib/fileutl.cc | 20 +++++++++++++++----- apt-pkg/contrib/fileutl.h | 3 ++- 2 files changed, 17 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 16f7ce929..0b0739cda 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -654,10 +655,11 @@ bool FileFd::Open(string FileName,OpenMode Mode, unsigned long Perms) case WriteEmpty: { - struct stat Buf; - if (lstat(FileName.c_str(),&Buf) == 0 && S_ISLNK(Buf.st_mode)) - unlink(FileName.c_str()); - iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_TRUNC,Perms); + Flags |= Replace; + char *name = strdup((FileName + ".XXXXXX").c_str()); + TemporaryFileName = string(mktemp(name)); + iFd = open(TemporaryFileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms); + free(name); break; } @@ -839,11 +841,19 @@ bool FileFd::Close() if (iFd >= 0 && close(iFd) != 0) Res &= _error->Errno("close",_("Problem closing the file")); iFd = -1; - + + if ((Flags & Replace) == Replace) { + FileName = TemporaryFileName; // for the unlink() below. + if (rename(TemporaryFileName.c_str(), FileName.c_str()) != 0) + Res &= _error->Errno("rename",_("Problem renaming the file")); + } + if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail && FileName.empty() == false) if (unlink(FileName.c_str()) != 0) Res &= _error->WarningE("unlnk",_("Problem unlinking the file")); + + return Res; } /*}}}*/ diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 003bd9b83..528725f89 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -34,9 +34,10 @@ class FileFd int iFd; enum LocalFlags {AutoClose = (1<<0),Fail = (1<<1),DelOnFail = (1<<2), - HitEof = (1<<3)}; + HitEof = (1<<3), Replace = (1<<4) }; unsigned long Flags; string FileName; + string TemporaryFileName; public: enum OpenMode {ReadOnly,WriteEmpty,WriteExists,WriteAny,WriteTemp}; -- cgit v1.2.3 From fd3b761e8cba6ed626639b50b1221246098c7b3a Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 29 Jun 2010 17:28:33 +0200 Subject: Fix the atomic replace. --- apt-pkg/contrib/fileutl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 0b0739cda..0b62d1bd8 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -843,9 +843,9 @@ bool FileFd::Close() iFd = -1; if ((Flags & Replace) == Replace) { - FileName = TemporaryFileName; // for the unlink() below. if (rename(TemporaryFileName.c_str(), FileName.c_str()) != 0) Res &= _error->Errno("rename",_("Problem renaming the file")); + FileName = TemporaryFileName; // for the unlink() below. } if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail && -- cgit v1.2.3 From e841200b9389ffc90e290310207bcb47e8a52be2 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 4 Jul 2010 14:23:20 +0200 Subject: * apt-pkg/policy.h: - add another round of const& madness as the previous round accidently NOT override the virtual GetCandidateVer() method (Closes: #587725) --- apt-pkg/algorithms.h | 2 +- apt-pkg/cacheiterators.h | 32 ++++++++++++++++---------------- apt-pkg/depcache.cc | 4 ++-- apt-pkg/depcache.h | 6 +++--- apt-pkg/pkgcache.cc | 12 ++++++------ apt-pkg/policy.h | 2 +- 6 files changed, 29 insertions(+), 29 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index cee30b679..cf4a98c4f 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -48,7 +48,7 @@ class pkgSimulate : public pkgPackageManager /*{{{*/ pkgDepCache *Cache; public: - virtual VerIterator GetCandidateVer(PkgIterator Pkg) + virtual VerIterator GetCandidateVer(PkgIterator const &Pkg) { return (*Cache)[Pkg].CandidateVerIter(*Cache); } diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 51bf6819e..dfe5707e1 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -105,13 +105,13 @@ class pkgCache::GrpIterator: public Iterator { inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;}; inline PkgIterator PackageList() const; - PkgIterator FindPkg(string Arch = "any"); + PkgIterator FindPkg(string Arch = "any") const; /** \brief find the package with the "best" architecture The best architecture is either the "native" or the first in the list of Architectures which is not an end-Pointer */ - PkgIterator FindPreferredPkg(); - PkgIterator NextPkg(PkgIterator const &Pkg); + PkgIterator FindPreferredPkg() const; + PkgIterator NextPkg(PkgIterator const &Pkg) const; // Constructors inline GrpIterator(pkgCache &Owner, Group *Trg) : Iterator(Owner, Trg), HashIndex(0) { @@ -272,17 +272,17 @@ class pkgCache::DepIterator : public Iterator { // Accessors inline const char *TargetVer() const {return S->Version == 0?0:Owner->StrP + S->Version;}; - inline PkgIterator TargetPkg() {return PkgIterator(*Owner,Owner->PkgP + S->Package);}; - inline PkgIterator SmartTargetPkg() {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;}; - inline VerIterator ParentVer() {return VerIterator(*Owner,Owner->VerP + S->ParentVer);}; - inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->ParentVer].ParentPkg);}; - inline bool Reverse() {return Type == DepRev;}; - bool IsCritical(); + inline PkgIterator TargetPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->Package);}; + inline PkgIterator SmartTargetPkg() const {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;}; + inline VerIterator ParentVer() const {return VerIterator(*Owner,Owner->VerP + S->ParentVer);}; + inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->ParentVer].ParentPkg);}; + inline bool Reverse() const {return Type == DepRev;}; + bool IsCritical() const; void GlobOr(DepIterator &Start,DepIterator &End); - Version **AllTargets(); - bool SmartTargetPkg(PkgIterator &Result); - inline const char *CompType() {return Owner->CompType(S->CompareOp);}; - inline const char *DepType() {return Owner->DepType(S->Type);}; + Version **AllTargets() const; + bool SmartTargetPkg(PkgIterator &Result) const; + inline const char *CompType() const {return Owner->CompType(S->CompareOp);}; + inline const char *DepType() const {return Owner->DepType(S->Type);}; inline DepIterator(pkgCache &Owner, Dependency *Trg, Version* = 0) : Iterator(Owner, Trg), Type(DepVer) { @@ -315,9 +315,9 @@ class pkgCache::PrvIterator : public Iterator { // Accessors inline const char *Name() const {return Owner->StrP + Owner->PkgP[S->ParentPkg].Name;}; inline const char *ProvideVersion() const {return S->ProvideVersion == 0?0:Owner->StrP + S->ProvideVersion;}; - inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);}; - inline VerIterator OwnerVer() {return VerIterator(*Owner,Owner->VerP + S->Version);}; - inline PkgIterator OwnerPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->Version].ParentPkg);}; + inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);}; + inline VerIterator OwnerVer() const {return VerIterator(*Owner,Owner->VerP + S->Version);}; + inline PkgIterator OwnerPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->Version].ParentPkg);}; inline PrvIterator() : Iterator(), Type(PrvVer) {}; diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index c93993ab1..05127fe18 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1585,7 +1585,7 @@ const char *pkgDepCache::StateCache::StripEpoch(const char *Ver) // --------------------------------------------------------------------- /* The default just returns the highest available version that is not a source and automatic. */ -pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg) +pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator const &Pkg) { /* Not source/not automatic versions cannot be a candidate version unless they are already installed */ @@ -1620,7 +1620,7 @@ pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg) // Policy::IsImportantDep - True if the dependency is important /*{{{*/ // --------------------------------------------------------------------- /* */ -bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep) +bool pkgDepCache::Policy::IsImportantDep(DepIterator const &Dep) { if(Dep.IsCritical()) return true; diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 66c099b80..45276dc95 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -256,8 +256,8 @@ class pkgDepCache : protected pkgCache::Namespace { public: - virtual VerIterator GetCandidateVer(PkgIterator Pkg); - virtual bool IsImportantDep(DepIterator Dep); + virtual VerIterator GetCandidateVer(PkgIterator const &Pkg); + virtual bool IsImportantDep(DepIterator const &Dep); virtual ~Policy() {}; }; @@ -334,7 +334,7 @@ class pkgDepCache : protected pkgCache::Namespace inline pkgVersioningSystem &VS() {return *Cache->VS;}; // Policy implementation - inline VerIterator GetCandidateVer(PkgIterator Pkg) {return LocalPolicy->GetCandidateVer(Pkg);}; + inline VerIterator GetCandidateVer(PkgIterator const &Pkg) {return LocalPolicy->GetCandidateVer(Pkg);}; inline bool IsImportantDep(DepIterator Dep) {return LocalPolicy->IsImportantDep(Dep);}; inline Policy &GetPolicy() {return *LocalPolicy;}; diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 30bb41470..68aa83d0c 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -307,7 +307,7 @@ const char *pkgCache::Priority(unsigned char Prio) // GrpIterator::FindPkg - Locate a package by arch /*{{{*/ // --------------------------------------------------------------------- /* Returns an End-Pointer on error, pointer to the package otherwise */ -pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) { +pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) const { if (unlikely(IsGood() == false || S->FirstPackage == 0)) return PkgIterator(*Owner, 0); @@ -346,7 +346,7 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) { // GrpIterator::FindPreferredPkg - Locate the "best" package /*{{{*/ // --------------------------------------------------------------------- /* Returns an End-Pointer on error, pointer to the package otherwise */ -pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg() { +pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg() const { pkgCache::PkgIterator Pkg = FindPkg("native"); if (Pkg.end() == false) return Pkg; @@ -367,7 +367,7 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg() { /* Returns an End-Pointer on error, pointer to the package otherwise. We can't simply ++ to the next as the next package of the last will be from a different group (with the same hash value) */ -pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const &LastPkg) { +pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const &LastPkg) const { if (unlikely(IsGood() == false || S->FirstPackage == 0 || LastPkg.end() == true)) return PkgIterator(*Owner, 0); @@ -504,7 +504,7 @@ std::string pkgCache::PkgIterator::FullName(bool const &Pretty) const // --------------------------------------------------------------------- /* Currently critical deps are defined as depends, predepends and conflicts (including dpkg's Breaks fields). */ -bool pkgCache::DepIterator::IsCritical() +bool pkgCache::DepIterator::IsCritical() const { if (S->Type == pkgCache::Dep::Conflicts || S->Type == pkgCache::Dep::DpkgBreaks || @@ -528,7 +528,7 @@ bool pkgCache::DepIterator::IsCritical() In Conjunction with the DepCache the value of Result may not be super-good since the policy may have made it uninstallable. Using AllTargets is better in this case. */ -bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result) +bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result) const { Result = TargetPkg(); @@ -577,7 +577,7 @@ bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result) provides. It includes every possible package-version that could satisfy the dependency. The last item in the list has a 0. The resulting pointer must be delete [] 'd */ -pkgCache::Version **pkgCache::DepIterator::AllTargets() +pkgCache::Version **pkgCache::DepIterator::AllTargets() const { Version **Res = 0; unsigned long Size =0; diff --git a/apt-pkg/policy.h b/apt-pkg/policy.h index 28cb3ccbb..f8b2678de 100644 --- a/apt-pkg/policy.h +++ b/apt-pkg/policy.h @@ -76,7 +76,7 @@ class pkgPolicy : public pkgDepCache::Policy // Things for the cache interface. virtual pkgCache::VerIterator GetCandidateVer(pkgCache::PkgIterator const &Pkg); - virtual bool IsImportantDep(pkgCache::DepIterator Dep) {return pkgDepCache::Policy::IsImportantDep(Dep);}; + virtual bool IsImportantDep(pkgCache::DepIterator const &Dep) {return pkgDepCache::Policy::IsImportantDep(Dep);}; bool InitDefaults(); pkgPolicy(pkgCache *Owner); -- cgit v1.2.3 From dcfa253fa4b3c563b3ed085c40d3336933840d55 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 4 Jul 2010 17:04:07 +0200 Subject: clean deblistparser a bit by get the Architectures at one place instead of distributed in a few methods --- apt-pkg/deb/deblistparser.cc | 23 ++++++++++------------- apt-pkg/deb/deblistparser.h | 4 +++- 2 files changed, 13 insertions(+), 14 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 83c5b8d2e..d1931f909 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -38,6 +38,8 @@ debListParser::debListParser(FileFd *File, string const &Arch) : Tags(File), Arch(Arch) { if (Arch == "native") this->Arch = _config->Find("APT::Architecture"); + Architectures = APT::Configuration::getArchitectures(); + MultiArchEnabled = Architectures.size() > 1; } /*}}}*/ // ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/ @@ -155,10 +157,9 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) to a NOP in the download/install step - this package will ensure that it is downloaded only one time and installed only one time -- even if the architecture bound versions coming in and out on regular basis. */ - bool const static multiArch = APT::Configuration::getArchitectures().size() > 1; if (strcmp(Ver.Arch(true),"all") == 0) return true; - else if (multiArch == true) + else if (MultiArchEnabled == true) { // our pseudo packages have no size to not confuse the fetcher Ver->Size = 0; @@ -620,9 +621,6 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver, if (Section.Find(Tag,Start,Stop) == false) return true; - static std::vector const archs = APT::Configuration::getArchitectures(); - static bool const multiArch = archs.size() <= 1; - string Package; string const pkgArch = Ver.Arch(true); string Version; @@ -634,13 +632,13 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver, if (Start == 0) return _error->Error("Problem parsing dependency %s",Tag); - if (multiArch == true && + if (MultiArchEnabled == true && (Type == pkgCache::Dep::Conflicts || Type == pkgCache::Dep::DpkgBreaks || Type == pkgCache::Dep::Replaces)) { - for (std::vector::const_iterator a = archs.begin(); - a != archs.end(); ++a) + for (std::vector::const_iterator a = Architectures.begin(); + a != Architectures.end(); ++a) if (NewDepends(Ver,Package,*a,Version,Op,Type) == false) return false; } @@ -692,14 +690,13 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver) if (Ver->MultiArch != pkgCache::Version::Foreign) return true; - std::vector const archs = APT::Configuration::getArchitectures(); - if (archs.size() <= 1) + if (MultiArchEnabled == false) return true; string const Package = Ver.ParentPkg().Name(); string const Version = Ver.VerStr(); - for (std::vector::const_iterator a = archs.begin(); - a != archs.end(); ++a) + for (std::vector::const_iterator a = Architectures.begin(); + a != Architectures.end(); ++a) { if (NewProvides(Ver, Package, *a, Version) == false) return false; @@ -739,7 +736,7 @@ bool debListParser::Step() if (Architecture.empty() == true) return true; - if (Arch.empty() == true) + if (Arch.empty() == true || MultiArchEnabled == false) { if (APT::Configuration::checkArchitecture(Architecture) == true) return true; diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 8da051530..6c81d9fa0 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -32,7 +32,9 @@ class debListParser : public pkgCacheGenerator::ListParser pkgTagSection Section; unsigned long iOffset; string Arch; - + std::vector Architectures; + bool MultiArchEnabled; + unsigned long UniqFindTagWrite(const char *Tag); bool ParseStatus(pkgCache::PkgIterator Pkg,pkgCache::VerIterator Ver); bool ParseDepends(pkgCache::VerIterator Ver,const char *Tag, -- cgit v1.2.3 From 3b5272950a1ac62178f7b8a0144c4c52e194be40 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 5 Jul 2010 11:42:57 +0200 Subject: Try to use NotEquals for the MultiArch Breaks dependencies instead of Less and Greater -> half the dependencies :) --- apt-pkg/pkgcachegen.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 5649cd6f8..05c01494b 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -572,10 +572,7 @@ bool pkgCacheGenerator::FinishCache(OpProgress *Progress) OldDepLast); // Breaks: ${self}:other (!= ${binary:Version}) NewDepends(D, V, V.VerStr(), - pkgCache::Dep::Less, pkgCache::Dep::DpkgBreaks, - OldDepLast); - NewDepends(D, V, V.VerStr(), - pkgCache::Dep::Greater, pkgCache::Dep::DpkgBreaks, + pkgCache::Dep::NotEquals, pkgCache::Dep::DpkgBreaks, OldDepLast); if (V->MultiArch == pkgCache::Version::All) { -- cgit v1.2.3 From 7e58ab0c0db9e5f27ae91251bf692bf79a046534 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 6 Jul 2010 10:21:45 +0200 Subject: wrap the mmap actions in the CacheGenerator in their own methods to be able to react on condition changes later then we can move mmap --- apt-pkg/pkgcachegen.cc | 53 ++++++++++++++++++++++++++++++++------------------ apt-pkg/pkgcachegen.h | 12 ++++++++---- 2 files changed, 42 insertions(+), 23 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 05c01494b..6a9da4a92 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -61,8 +61,8 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) : // Starting header *Cache.HeaderP = pkgCache::Header(); - Cache.HeaderP->VerSysName = Map.WriteString(_system->VS->Label); - Cache.HeaderP->Architecture = Map.WriteString(_config->Find("APT::Architecture")); + Cache.HeaderP->VerSysName = WriteStringInMap(_system->VS->Label); + Cache.HeaderP->Architecture = WriteStringInMap(_config->Find("APT::Architecture")); Cache.ReMap(); } else @@ -96,6 +96,21 @@ pkgCacheGenerator::~pkgCacheGenerator() Map.Sync(0,sizeof(pkgCache::Header)); } /*}}}*/ +// CacheGenerator::WriteStringInMap /*{{{*/ +unsigned long pkgCacheGenerator::WriteStringInMap(const char *String, + const unsigned long &Len) { + return Map.WriteString(String, Len); +} + /*}}}*/ +// CacheGenerator::WriteStringInMap /*{{{*/ +unsigned long pkgCacheGenerator::WriteStringInMap(const char *String) { + return Map.WriteString(String); +} + /*}}}*/ +unsigned long pkgCacheGenerator::AllocateInMap(const unsigned long &size) {/*{{{*/ + return Map.Allocate(size); +} + /*}}}*/ // CacheGenerator::MergeList - Merge the package list /*{{{*/ // --------------------------------------------------------------------- /* This provides the generation of the entries in the cache. Each loop @@ -342,12 +357,12 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name) return true; // Get a structure - unsigned long const Group = Map.Allocate(sizeof(pkgCache::Group)); + unsigned long const Group = AllocateInMap(sizeof(pkgCache::Group)); if (unlikely(Group == 0)) return false; Grp = pkgCache::GrpIterator(Cache, Cache.GrpP + Group); - Grp->Name = Map.WriteString(Name); + Grp->Name = WriteStringInMap(Name); if (unlikely(Grp->Name == 0)) return false; @@ -374,7 +389,7 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name return true; // Get a structure - unsigned long const Package = Map.Allocate(sizeof(pkgCache::Package)); + unsigned long const Package = AllocateInMap(sizeof(pkgCache::Package)); if (unlikely(Package == 0)) return false; Pkg = pkgCache::PkgIterator(Cache,Cache.PkgP + Package); @@ -418,7 +433,7 @@ bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator &Ver, return true; // Get a structure - unsigned long VerFile = Map.Allocate(sizeof(pkgCache::VerFile)); + unsigned long VerFile = AllocateInMap(sizeof(pkgCache::VerFile)); if (VerFile == 0) return 0; @@ -449,7 +464,7 @@ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver, unsigned long Next) { // Get a structure - unsigned long Version = Map.Allocate(sizeof(pkgCache::Version)); + unsigned long Version = AllocateInMap(sizeof(pkgCache::Version)); if (Version == 0) return 0; @@ -457,7 +472,7 @@ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver, Ver = pkgCache::VerIterator(Cache,Cache.VerP + Version); Ver->NextVer = Next; Ver->ID = Cache.HeaderP->VersionCount++; - Ver->VerStr = Map.WriteString(VerStr); + Ver->VerStr = WriteStringInMap(VerStr); if (Ver->VerStr == 0) return 0; @@ -474,7 +489,7 @@ bool pkgCacheGenerator::NewFileDesc(pkgCache::DescIterator &Desc, return true; // Get a structure - unsigned long DescFile = Map.Allocate(sizeof(pkgCache::DescFile)); + unsigned long DescFile = AllocateInMap(sizeof(pkgCache::DescFile)); if (DescFile == 0) return false; @@ -507,7 +522,7 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, map_ptrloc Next) { // Get a structure - map_ptrloc Description = Map.Allocate(sizeof(pkgCache::Description)); + map_ptrloc Description = AllocateInMap(sizeof(pkgCache::Description)); if (Description == 0) return 0; @@ -515,8 +530,8 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, Desc = pkgCache::DescIterator(Cache,Cache.DescP + Description); Desc->NextDesc = Next; Desc->ID = Cache.HeaderP->DescriptionCount++; - Desc->language_code = Map.WriteString(Lang); - Desc->md5sum = Map.WriteString(md5sum.Value()); + Desc->language_code = WriteStringInMap(Lang); + Desc->md5sum = WriteStringInMap(md5sum.Value()); if (Desc->language_code == 0 || Desc->md5sum == 0) return 0; @@ -607,7 +622,7 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, map_ptrloc *OldDepLast) { // Get a structure - unsigned long const Dependency = Map.Allocate(sizeof(pkgCache::Dependency)); + unsigned long const Dependency = AllocateInMap(sizeof(pkgCache::Dependency)); if (unlikely(Dependency == 0)) return false; @@ -625,7 +640,7 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, if (I->Version != 0 && I.TargetVer() == Version) Dep->Version = I->Version;*/ if (Dep->Version == 0) - if (unlikely((Dep->Version = Map.WriteString(Version)) == 0)) + if (unlikely((Dep->Version = WriteStringInMap(Version)) == 0)) return false; } @@ -699,7 +714,7 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver, return true; // Get a structure - unsigned long const Provides = Owner->Map.Allocate(sizeof(pkgCache::Provides)); + unsigned long const Provides = Owner->AllocateInMap(sizeof(pkgCache::Provides)); if (unlikely(Provides == 0)) return false; Cache.HeaderP->ProvidesCount++; @@ -734,12 +749,12 @@ bool pkgCacheGenerator::SelectFile(const string &File,const string &Site, unsigned long Flags) { // Get some space for the structure - CurrentFile = Cache.PkgFileP + Map.Allocate(sizeof(*CurrentFile)); + CurrentFile = Cache.PkgFileP + AllocateInMap(sizeof(*CurrentFile)); if (CurrentFile == Cache.PkgFileP) return false; // Fill it in - CurrentFile->FileName = Map.WriteString(File); + CurrentFile->FileName = WriteStringInMap(File); CurrentFile->Site = WriteUniqString(Site); CurrentFile->NextFile = Cache.HeaderP->FileList; CurrentFile->Flags = Flags; @@ -791,7 +806,7 @@ unsigned long pkgCacheGenerator::WriteUniqString(const char *S, } // Get a structure - unsigned long Item = Map.Allocate(sizeof(pkgCache::StringItem)); + unsigned long Item = AllocateInMap(sizeof(pkgCache::StringItem)); if (Item == 0) return 0; @@ -799,7 +814,7 @@ unsigned long pkgCacheGenerator::WriteUniqString(const char *S, pkgCache::StringItem *ItemP = Cache.StringItemP + Item; ItemP->NextItem = I - Cache.StringItemP; *Last = Item; - ItemP->String = Map.WriteString(S,Size); + ItemP->String = WriteStringInMap(S,Size); if (ItemP->String == 0) return 0; diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index ff0941e0c..a88c49451 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -31,9 +31,13 @@ class pkgIndexFile; class pkgCacheGenerator /*{{{*/ { private: - + pkgCache::StringItem *UniqHash[26]; - + unsigned long WriteStringInMap(std::string const &String) { return WriteStringInMap(String.c_str()); }; + unsigned long WriteStringInMap(const char *String); + unsigned long WriteStringInMap(const char *String, const unsigned long &Len); + unsigned long AllocateInMap(const unsigned long &size); + public: class ListParser; @@ -103,8 +107,8 @@ class pkgCacheGenerator::ListParser inline unsigned long WriteUniqString(string S) {return Owner->WriteUniqString(S);}; inline unsigned long WriteUniqString(const char *S,unsigned int Size) {return Owner->WriteUniqString(S,Size);}; - inline unsigned long WriteString(const string &S) {return Owner->Map.WriteString(S);}; - inline unsigned long WriteString(const char *S,unsigned int Size) {return Owner->Map.WriteString(S,Size);}; + inline unsigned long WriteString(const string &S) {return Owner->WriteStringInMap(S);}; + inline unsigned long WriteString(const char *S,unsigned int Size) {return Owner->WriteStringInMap(S,Size);}; bool NewDepends(pkgCache::VerIterator Ver,const string &Package, const string &Arch, const string &Version,unsigned int Op, unsigned int Type); -- cgit v1.2.3 From d13c2d3f7b10e558301a05948e91ac4a60160793 Mon Sep 17 00:00:00 2001 From: "martin@piware.de" <> Date: Tue, 6 Jul 2010 12:48:06 +0200 Subject: FileFd(): Drop file name extension check in ReadOnlyGzip mode Drop the ".gz" extension check in FileFd::Open() in ReadOnlyGzip mode, to not depend on a particular file extension. This allows rewriting the gzip method using internal decompression (on ".decomp" files). This requires a zlib bug workaround in FileFd::Close(): When opening an empty file with gzdopen(), gzclose() fails with Z_BUF_ERROR. Do not count this as a failure. --- apt-pkg/contrib/fileutl.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 2b91a46f7..0d2d3f356 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -608,7 +608,7 @@ bool FileFd::Open(string FileName,OpenMode Mode, unsigned long Perms) case ReadOnlyGzip: iFd = open(FileName.c_str(),O_RDONLY); - if (iFd > 0 && FileName.compare(FileName.size()-3, 3, ".gz") == 0) { + if (iFd > 0) { gz = gzdopen (iFd, "r"); if (gz == NULL) { close (iFd); @@ -827,8 +827,16 @@ bool FileFd::Close() { bool Res = true; if ((Flags & AutoClose) == AutoClose) - if ((gz != NULL && gzclose(gz) != 0) || (gz == NULL && iFd > 0 && close(iFd) != 0)) - Res &= _error->Errno("close",_("Problem closing the file")); + { + if (gz != NULL) { + int e = gzclose(gz); + // gzdopen() on empty files always fails with "buffer error" here, ignore that + if (e != 0 && e != Z_BUF_ERROR) + Res &= _error->Errno("close",_("Problem closing the gzip file")); + } else + if (iFd > 0 && close(iFd) != 0) + Res &= _error->Errno("close",_("Problem closing the file")); + } iFd = -1; gz = NULL; -- cgit v1.2.3 From 24baab5c477bf1e57a0b169a7bac1d2e9ab0c974 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 7 Jul 2010 16:47:09 +0200 Subject: * apt-pkg/deb/dpkgpm.cc: - make the apt/term.log output unbuffered (thanks to Matt Zimmerman) --- apt-pkg/deb/dpkgpm.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 8abe3f5c6..2bbc7a4ba 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -582,7 +583,7 @@ bool pkgDPkgPM::OpenLog() term_out = fopen(logfile_name.c_str(),"a"); if (term_out == NULL) return _error->WarningE(_("Could not open file '%s'"), logfile_name.c_str()); - + setvbuf(term_out, NULL, _IONBF, 0); chmod(logfile_name.c_str(), 0600); fprintf(term_out, "\nLog started: %s\n", timestr); } -- cgit v1.2.3 From 32b9a14cb4c6bdcddfe84c4451c225ced1a34bb7 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 8 Jul 2010 11:10:46 +0200 Subject: use references instead of copies in the Cache generation methods --- apt-pkg/deb/deblistparser.cc | 16 ++++++++-------- apt-pkg/deb/deblistparser.h | 14 +++++++------- apt-pkg/pkgcachegen.cc | 9 +++++---- apt-pkg/pkgcachegen.h | 12 ++++++------ 4 files changed, 26 insertions(+), 25 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 24df57a5c..2cfeb23e9 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -106,7 +106,7 @@ string debListParser::Version() // ListParser::NewVersion - Fill in the version structure /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debListParser::NewVersion(pkgCache::VerIterator Ver) +bool debListParser::NewVersion(pkgCache::VerIterator &Ver) { // Parse the section Ver->Section = UniqFindTagWrite("Section"); @@ -251,8 +251,8 @@ MD5SumValue debListParser::Description_md5() // --------------------------------------------------------------------- /* This is called to update the package with any new information that might be found in the section */ -bool debListParser::UsePackage(pkgCache::PkgIterator Pkg, - pkgCache::VerIterator Ver) +bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg, + pkgCache::VerIterator &Ver) { if (Pkg->Section == 0) Pkg->Section = UniqFindTagWrite("Section"); @@ -332,8 +332,8 @@ unsigned short debListParser::VersionHash() Some of the above are obsolete (I think?) flag = hold-* and status = post-inst-failed, removal-failed at least. */ -bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg, - pkgCache::VerIterator Ver) +bool debListParser::ParseStatus(pkgCache::PkgIterator &Pkg, + pkgCache::VerIterator &Ver) { const char *Start; const char *Stop; @@ -634,7 +634,7 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop, // --------------------------------------------------------------------- /* This is the higher level depends parser. It takes a tag and generates a complete depends tree for the given version. */ -bool debListParser::ParseDepends(pkgCache::VerIterator Ver, +bool debListParser::ParseDepends(pkgCache::VerIterator &Ver, const char *Tag,unsigned int Type) { const char *Start; @@ -674,7 +674,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver, // ListParser::ParseProvides - Parse the provides list /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debListParser::ParseProvides(pkgCache::VerIterator Ver) +bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) { const char *Start; const char *Stop; @@ -779,7 +779,7 @@ bool debListParser::Step() // ListParser::LoadReleaseInfo - Load the release information /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI, +bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, FileFd &File, string component) { pkgTagFile Tags(&File, File.Size() + 256); // XXX diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 6c81d9fa0..4bc1bd93c 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -36,10 +36,10 @@ class debListParser : public pkgCacheGenerator::ListParser bool MultiArchEnabled; unsigned long UniqFindTagWrite(const char *Tag); - bool ParseStatus(pkgCache::PkgIterator Pkg,pkgCache::VerIterator Ver); - bool ParseDepends(pkgCache::VerIterator Ver,const char *Tag, + bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver); + bool ParseDepends(pkgCache::VerIterator &Ver,const char *Tag, unsigned int Type); - bool ParseProvides(pkgCache::VerIterator Ver); + bool ParseProvides(pkgCache::VerIterator &Ver); static bool GrabWord(string Word,WordList *List,unsigned char &Out); public: @@ -51,19 +51,19 @@ class debListParser : public pkgCacheGenerator::ListParser virtual string Architecture(); virtual bool ArchitectureAll(); virtual string Version(); - virtual bool NewVersion(pkgCache::VerIterator Ver); + virtual bool NewVersion(pkgCache::VerIterator &Ver); virtual string Description(); virtual string DescriptionLanguage(); virtual MD5SumValue Description_md5(); virtual unsigned short VersionHash(); - virtual bool UsePackage(pkgCache::PkgIterator Pkg, - pkgCache::VerIterator Ver); + virtual bool UsePackage(pkgCache::PkgIterator &Pkg, + pkgCache::VerIterator &Ver); virtual unsigned long Offset() {return iOffset;}; virtual unsigned long Size() {return Section.size();}; virtual bool Step(); - bool LoadReleaseInfo(pkgCache::PkgFileIterator FileI,FileFd &File, + bool LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,FileFd &File, string section); static const char *ParseDepends(const char *Start,const char *Stop, diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 6a9da4a92..62e457734 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -157,13 +157,14 @@ bool pkgCacheGenerator::MergeList(ListParser &List, // we first process the package, then the descriptions // (this has the bonus that we get MMap error when we run out // of MMap space) - if (List.UsePackage(Pkg,pkgCache::VerIterator(Cache)) == false) + pkgCache::VerIterator Ver(Cache); + if (List.UsePackage(Pkg, Ver) == false) return _error->Error(_("Error occurred while processing %s (UsePackage1)"), PackageName.c_str()); // Find the right version to write the description MD5SumValue CurMd5 = List.Description_md5(); - pkgCache::VerIterator Ver = Pkg.VersionList(); + Ver = Pkg.VersionList(); map_ptrloc *LastVer = &Pkg->VersionList; for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++) @@ -668,7 +669,7 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, // --------------------------------------------------------------------- /* This creates a Group and the Package to link this dependency to if needed and handles also the caching of the old endpoint */ -bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, +bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator &Ver, const string &PackageName, const string &Arch, const string &Version, @@ -702,7 +703,7 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, // ListParser::NewProvides - Create a Provides element /*{{{*/ // --------------------------------------------------------------------- /* */ -bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver, +bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator &Ver, const string &PkgName, const string &PkgArch, const string &Version) diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index a88c49451..8f7739165 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -109,10 +109,10 @@ class pkgCacheGenerator::ListParser inline unsigned long WriteUniqString(const char *S,unsigned int Size) {return Owner->WriteUniqString(S,Size);}; inline unsigned long WriteString(const string &S) {return Owner->WriteStringInMap(S);}; inline unsigned long WriteString(const char *S,unsigned int Size) {return Owner->WriteStringInMap(S,Size);}; - bool NewDepends(pkgCache::VerIterator Ver,const string &Package, const string &Arch, + bool NewDepends(pkgCache::VerIterator &Ver,const string &Package, const string &Arch, const string &Version,unsigned int Op, unsigned int Type); - bool NewProvides(pkgCache::VerIterator Ver,const string &PkgName, + bool NewProvides(pkgCache::VerIterator &Ver,const string &PkgName, const string &PkgArch, const string &Version); public: @@ -122,13 +122,13 @@ class pkgCacheGenerator::ListParser virtual string Architecture() = 0; virtual bool ArchitectureAll() = 0; virtual string Version() = 0; - virtual bool NewVersion(pkgCache::VerIterator Ver) = 0; + virtual bool NewVersion(pkgCache::VerIterator &Ver) = 0; virtual string Description() = 0; virtual string DescriptionLanguage() = 0; virtual MD5SumValue Description_md5() = 0; virtual unsigned short VersionHash() = 0; - virtual bool UsePackage(pkgCache::PkgIterator Pkg, - pkgCache::VerIterator Ver) = 0; + virtual bool UsePackage(pkgCache::PkgIterator &Pkg, + pkgCache::VerIterator &Ver) = 0; virtual unsigned long Offset() = 0; virtual unsigned long Size() = 0; @@ -136,7 +136,7 @@ class pkgCacheGenerator::ListParser inline bool HasFileDeps() {return FoundFileDeps;}; virtual bool CollectFileProvides(pkgCache &Cache, - pkgCache::VerIterator Ver) {return true;}; + pkgCache::VerIterator &Ver) {return true;}; ListParser() : FoundFileDeps(false) {}; virtual ~ListParser() {}; -- cgit v1.2.3 From a9fe592842bfa17d91f4904d7fb0e3af3adebb17 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 8 Jul 2010 15:28:53 +0200 Subject: * apt-pkg/pkgcachegen.{cc,h}: - make the used MMap moveable (and therefore dynamic resizeable) by applying (some) mad pointer magic (Closes: #195018) --- apt-pkg/cacheiterators.h | 6 ++ apt-pkg/contrib/mmap.cc | 27 ++++-- apt-pkg/deb/debindexfile.cc | 1 + apt-pkg/pkgcache.cc | 5 +- apt-pkg/pkgcache.h | 2 +- apt-pkg/pkgcachegen.cc | 229 ++++++++++++++++++++++++++++++++------------ apt-pkg/pkgcachegen.h | 30 ++++-- 7 files changed, 223 insertions(+), 77 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index dfe5707e1..eb8dee5e3 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -75,6 +75,12 @@ template class pkgCache::Iterator : inline bool IsGood() const { return S && Owner && ! end();}; inline unsigned long Index() const {return S - OwnerPointer();}; + void ReOwn(pkgCache &newOwner, void const * const oldMap, void const * const newMap) { + if (S == 0) + return; + S += (Str*)(newMap) - (Str*)(oldMap); + } + // Constructors - look out for the variable assigning inline Iterator() : S(0), Owner(0) {}; inline Iterator(pkgCache &Owner,Str *T = 0) : S(T), Owner(&Owner) {}; diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc index d71066243..aa184b130 100644 --- a/apt-pkg/contrib/mmap.cc +++ b/apt-pkg/contrib/mmap.cc @@ -225,22 +225,22 @@ DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long const &WorkSpace, // disable Moveable if we don't grow if (Grow == 0) - Flags &= ~Moveable; + this->Flags &= ~Moveable; #ifndef __linux__ // kfreebsd doesn't have mremap, so we use the fallback - if ((Flags & Moveable) == Moveable) - Flags |= Fallback; + if ((this->Flags & Moveable) == Moveable) + this->Flags |= Fallback; #endif #ifdef _POSIX_MAPPED_FILES - if ((Flags & Fallback) != Fallback) { + if ((this->Flags & Fallback) != Fallback) { // Set the permissions. int Prot = PROT_READ; int Map = MAP_PRIVATE | MAP_ANONYMOUS; - if ((Flags & ReadOnly) != ReadOnly) + if ((this->Flags & ReadOnly) != ReadOnly) Prot |= PROT_WRITE; - if ((Flags & Public) == Public) + if ((this->Flags & Public) == Public) Map = MAP_SHARED | MAP_ANONYMOUS; // use anonymous mmap() to get the memory @@ -314,7 +314,7 @@ unsigned long DynamicMMap::Allocate(unsigned long ItemSize) // Look for a matching pool entry Pool *I; Pool *Empty = 0; - for (I = Pools; I != Pools + PoolCount; I++) + for (I = Pools; I != Pools + PoolCount; ++I) { if (I->ItemSize == 0) Empty = I; @@ -342,7 +342,11 @@ unsigned long DynamicMMap::Allocate(unsigned long ItemSize) { const unsigned long size = 20*1024; I->Count = size/ItemSize; + Pool* oldPools = Pools; Result = RawAllocate(size,ItemSize); + if (Pools != oldPools) + I += Pools - oldPools; + // Does the allocation failed ? if (Result == 0 && _error->PendingError()) return 0; @@ -365,7 +369,7 @@ unsigned long DynamicMMap::WriteString(const char *String, if (Len == (unsigned long)-1) Len = strlen(String); - unsigned long Result = RawAllocate(Len+1,0); + unsigned long const Result = RawAllocate(Len+1,0); if (Result == 0 && _error->PendingError()) return 0; @@ -395,16 +399,20 @@ bool DynamicMMap::Grow() { return _error->Error(_("Unable to increase the size of the MMap as the " "limit of %lu bytes is already reached."), Limit); - unsigned long const newSize = WorkSpace + 1024*1024; + unsigned long const newSize = WorkSpace + GrowFactor; if(Fd != 0) { Fd->Seek(newSize - 1); char C = 0; Fd->Write(&C,sizeof(C)); } + + unsigned long const poolOffset = Pools - ((Pool*) Base); + 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 @@ -425,6 +433,7 @@ bool DynamicMMap::Grow() { return false; } + Pools =(Pool*) Base + poolOffset; WorkSpace = newSize; return true; } diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index 6d9e99497..5e6db3f38 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -277,6 +277,7 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const // Store the IMS information pkgCache::PkgFileIterator File = Gen.GetCurFile(); + pkgCacheGenerator::Dynamic DynFile(File); struct stat St; if (fstat(Pkg.Fd(),&St) != 0) return _error->Errno("fstat","Failed to stat"); diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 68aa83d0c..8af8ef7de 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -119,7 +119,7 @@ pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map) // Cache::ReMap - Reopen the cache file /*{{{*/ // --------------------------------------------------------------------- /* If the file is already closed then this will open it open it. */ -bool pkgCache::ReMap() +bool pkgCache::ReMap(bool const &Errorchecks) { // Apply the typecasts. HeaderP = (Header *)Map.Data(); @@ -135,6 +135,9 @@ bool pkgCache::ReMap() StringItemP = (StringItem *)Map.Data(); StrP = (char *)Map.Data(); + if (Errorchecks == false) + return true; + if (Map.Size() == 0 || HeaderP == 0) return _error->Error(_("Empty package cache")); diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 426bb9f13..799521784 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -174,7 +174,7 @@ class pkgCache /*{{{*/ StringItem *StringItemP; char *StrP; - virtual bool ReMap(); + virtual bool ReMap(bool const &Errorchecks = true); inline bool Sync() {return Map.Sync();}; inline MMap &GetMap() {return Map;}; inline void *DataEnd() {return ((unsigned char *)Map.Data()) + Map.Size();}; diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 62e457734..18bad6727 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -36,6 +36,7 @@ #include /*}}}*/ typedef vector::iterator FileIterator; +template std::set pkgCacheGenerator::Dynamic::toReMap; // CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/ // --------------------------------------------------------------------- @@ -61,8 +62,12 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) : // Starting header *Cache.HeaderP = pkgCache::Header(); - Cache.HeaderP->VerSysName = WriteStringInMap(_system->VS->Label); - Cache.HeaderP->Architecture = WriteStringInMap(_config->Find("APT::Architecture")); + map_ptrloc const idxVerSysName = WriteStringInMap(_system->VS->Label); + Cache.HeaderP->VerSysName = idxVerSysName; + map_ptrloc const idxArchitecture = WriteStringInMap(_config->Find("APT::Architecture")); + Cache.HeaderP->Architecture = idxArchitecture; + if (unlikely(idxVerSysName == 0 || idxArchitecture == 0)) + return; Cache.ReMap(); } else @@ -96,19 +101,65 @@ pkgCacheGenerator::~pkgCacheGenerator() Map.Sync(0,sizeof(pkgCache::Header)); } /*}}}*/ +void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newMap) {/*{{{*/ + if (oldMap == newMap) + return; + + Cache.ReMap(false); + + CurrentFile += (pkgCache::PackageFile*) newMap - (pkgCache::PackageFile*) oldMap; + + for (size_t i = 0; i < _count(UniqHash); ++i) + if (UniqHash[i] != 0) + UniqHash[i] += (pkgCache::StringItem*) newMap - (pkgCache::StringItem*) oldMap; + + for (std::set::const_iterator i = Dynamic::toReMap.begin(); + i != Dynamic::toReMap.end(); ++i) + (*i)->ReOwn(Cache, oldMap, newMap); + for (std::set::const_iterator i = Dynamic::toReMap.begin(); + i != Dynamic::toReMap.end(); ++i) + (*i)->ReOwn(Cache, oldMap, newMap); + for (std::set::const_iterator i = Dynamic::toReMap.begin(); + i != Dynamic::toReMap.end(); ++i) + (*i)->ReOwn(Cache, oldMap, newMap); + for (std::set::const_iterator i = Dynamic::toReMap.begin(); + i != Dynamic::toReMap.end(); ++i) + (*i)->ReOwn(Cache, oldMap, newMap); + for (std::set::const_iterator i = Dynamic::toReMap.begin(); + i != Dynamic::toReMap.end(); ++i) + (*i)->ReOwn(Cache, oldMap, newMap); + for (std::set::const_iterator i = Dynamic::toReMap.begin(); + i != Dynamic::toReMap.end(); ++i) + (*i)->ReOwn(Cache, oldMap, newMap); + for (std::set::const_iterator i = Dynamic::toReMap.begin(); + i != Dynamic::toReMap.end(); ++i) + (*i)->ReOwn(Cache, oldMap, newMap); +} /*}}}*/ // CacheGenerator::WriteStringInMap /*{{{*/ -unsigned long pkgCacheGenerator::WriteStringInMap(const char *String, +map_ptrloc pkgCacheGenerator::WriteStringInMap(const char *String, const unsigned long &Len) { - return Map.WriteString(String, Len); + void const * const oldMap = Map.Data(); + map_ptrloc const index = Map.WriteString(String, Len); + if (index != 0) + ReMap(oldMap, Map.Data()); + return index; } /*}}}*/ // CacheGenerator::WriteStringInMap /*{{{*/ -unsigned long pkgCacheGenerator::WriteStringInMap(const char *String) { - return Map.WriteString(String); +map_ptrloc pkgCacheGenerator::WriteStringInMap(const char *String) { + void const * const oldMap = Map.Data(); + map_ptrloc const index = Map.WriteString(String); + if (index != 0) + ReMap(oldMap, Map.Data()); + return index; } /*}}}*/ -unsigned long pkgCacheGenerator::AllocateInMap(const unsigned long &size) {/*{{{*/ - return Map.Allocate(size); +map_ptrloc pkgCacheGenerator::AllocateInMap(const unsigned long &size) {/*{{{*/ + void const * const oldMap = Map.Data(); + map_ptrloc const index = Map.Allocate(size); + if (index != 0) + ReMap(oldMap, Map.Data()); + return index; } /*}}}*/ // CacheGenerator::MergeList - Merge the package list /*{{{*/ @@ -142,6 +193,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List, { // Get a pointer to the package structure pkgCache::PkgIterator Pkg; + Dynamic DynPkg(Pkg); if (NewPackage(Pkg, PackageName, *arch) == false) return _error->Error(_("Error occurred while processing %s (NewPackage)"),PackageName.c_str()); Counter++; @@ -158,6 +210,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List, // (this has the bonus that we get MMap error when we run out // of MMap space) pkgCache::VerIterator Ver(Cache); + Dynamic DynVer(Ver); if (List.UsePackage(Pkg, Ver) == false) return _error->Error(_("Error occurred while processing %s (UsePackage1)"), PackageName.c_str()); @@ -165,11 +218,11 @@ bool pkgCacheGenerator::MergeList(ListParser &List, // Find the right version to write the description MD5SumValue CurMd5 = List.Description_md5(); Ver = Pkg.VersionList(); - map_ptrloc *LastVer = &Pkg->VersionList; - for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++) + for (; Ver.end() == false; ++Ver) { pkgCache::DescIterator Desc = Ver.DescriptionList(); + Dynamic DynDesc(Desc); map_ptrloc *LastDesc = &Ver->DescriptionList; bool duplicate=false; @@ -189,7 +242,11 @@ bool pkgCacheGenerator::MergeList(ListParser &List, if (MD5SumValue(Desc.md5()) == CurMd5) { // Add new description - *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), CurMd5, *LastDesc); + void const * const oldMap = Map.Data(); + map_ptrloc const descindex = NewDescription(Desc, List.DescriptionLanguage(), CurMd5, *LastDesc); + if (oldMap != Map.Data()) + LastDesc += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap; + *LastDesc = descindex; Desc->ParentPkg = Pkg.Index(); if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false) @@ -203,7 +260,9 @@ bool pkgCacheGenerator::MergeList(ListParser &List, } pkgCache::VerIterator Ver = Pkg.VersionList(); + Dynamic DynVer(Ver); map_ptrloc *LastVer = &Pkg->VersionList; + void const * oldMap = Map.Data(); int Res = 1; unsigned long const Hash = List.VersionHash(); for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++) @@ -242,21 +301,28 @@ bool pkgCacheGenerator::MergeList(ListParser &List, } // Add a new version - *LastVer = NewVersion(Ver,Version,*LastVer); + map_ptrloc const verindex = NewVersion(Ver,Version,*LastVer); + if (verindex == 0 && _error->PendingError()) + return _error->Error(_("Error occurred while processing %s (NewVersion%d)"), + PackageName.c_str(), 1); + + if (oldMap != Map.Data()) + LastVer += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap; + *LastVer = verindex; Ver->ParentPkg = Pkg.Index(); Ver->Hash = Hash; - if ((*LastVer == 0 && _error->PendingError()) || List.NewVersion(Ver) == false) - return _error->Error(_("Error occurred while processing %s (NewVersion1)"), - PackageName.c_str()); + if (List.NewVersion(Ver) == false) + return _error->Error(_("Error occurred while processing %s (NewVersion%d)"), + PackageName.c_str(), 2); if (List.UsePackage(Pkg,Ver) == false) return _error->Error(_("Error occurred while processing %s (UsePackage3)"), PackageName.c_str()); if (NewFileVer(Ver,List) == false) - return _error->Error(_("Error occurred while processing %s (NewVersion2)"), - PackageName.c_str()); + return _error->Error(_("Error occurred while processing %s (NewVersion%d)"), + PackageName.c_str(), 3); // Read only a single record and return if (OutVer != 0) @@ -269,13 +335,18 @@ bool pkgCacheGenerator::MergeList(ListParser &List, /* Record the Description data. Description data always exist in Packages and Translation-* files. */ pkgCache::DescIterator Desc = Ver.DescriptionList(); + Dynamic DynDesc(Desc); map_ptrloc *LastDesc = &Ver->DescriptionList; - + // Skip to the end of description set for (; Desc.end() == false; LastDesc = &Desc->NextDesc, Desc++); // Add new description - *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), List.Description_md5(), *LastDesc); + oldMap = Map.Data(); + map_ptrloc const descindex = NewDescription(Desc, List.DescriptionLanguage(), List.Description_md5(), *LastDesc); + if (oldMap != Map.Data()) + LastDesc += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap; + *LastDesc = descindex; Desc->ParentPkg = Pkg.Index(); if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false) @@ -322,6 +393,7 @@ bool pkgCacheGenerator::MergeFileProvides(ListParser &List) continue; pkgCache::PkgIterator Pkg = Cache.FindPkg(PackageName); + Dynamic DynPkg(Pkg); if (Pkg.end() == true) return _error->Error(_("Error occurred while processing %s (FindPkg)"), PackageName.c_str()); @@ -331,6 +403,7 @@ bool pkgCacheGenerator::MergeFileProvides(ListParser &List) unsigned long Hash = List.VersionHash(); pkgCache::VerIterator Ver = Pkg.VersionList(); + Dynamic DynVer(Ver); for (; Ver.end() == false; Ver++) { if (Ver->Hash == Hash && Version.c_str() == Ver.VerStr()) @@ -358,14 +431,15 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name) return true; // Get a structure - unsigned long const Group = AllocateInMap(sizeof(pkgCache::Group)); + map_ptrloc const Group = AllocateInMap(sizeof(pkgCache::Group)); if (unlikely(Group == 0)) return false; Grp = pkgCache::GrpIterator(Cache, Cache.GrpP + Group); - Grp->Name = WriteStringInMap(Name); - if (unlikely(Grp->Name == 0)) + map_ptrloc const idxName = WriteStringInMap(Name); + if (unlikely(idxName == 0)) return false; + Grp->Name = idxName; // Insert it into the hash table unsigned long const Hash = Cache.Hash(Name); @@ -382,6 +456,7 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name) bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name, const string &Arch) { pkgCache::GrpIterator Grp; + Dynamic DynGrp(Grp); if (unlikely(NewGroup(Grp, Name) == false)) return false; @@ -390,7 +465,7 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name return true; // Get a structure - unsigned long const Package = AllocateInMap(sizeof(pkgCache::Package)); + map_ptrloc const Package = AllocateInMap(sizeof(pkgCache::Package)); if (unlikely(Package == 0)) return false; Pkg = pkgCache::PkgIterator(Cache,Cache.PkgP + Package); @@ -416,9 +491,10 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name // Set the name, arch and the ID Pkg->Name = Grp->Name; Pkg->Group = Grp.Index(); - Pkg->Arch = WriteUniqString(Arch.c_str()); - if (unlikely(Pkg->Arch == 0)) + map_ptrloc const idxArch = WriteUniqString(Arch.c_str()); + if (unlikely(idxArch == 0)) return false; + Pkg->Arch = idxArch; Pkg->ID = Cache.HeaderP->PackageCount++; return true; @@ -434,7 +510,7 @@ bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator &Ver, return true; // Get a structure - unsigned long VerFile = AllocateInMap(sizeof(pkgCache::VerFile)); + map_ptrloc const VerFile = AllocateInMap(sizeof(pkgCache::VerFile)); if (VerFile == 0) return 0; @@ -465,7 +541,7 @@ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver, unsigned long Next) { // Get a structure - unsigned long Version = AllocateInMap(sizeof(pkgCache::Version)); + map_ptrloc const Version = AllocateInMap(sizeof(pkgCache::Version)); if (Version == 0) return 0; @@ -473,9 +549,10 @@ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver, Ver = pkgCache::VerIterator(Cache,Cache.VerP + Version); Ver->NextVer = Next; Ver->ID = Cache.HeaderP->VersionCount++; - Ver->VerStr = WriteStringInMap(VerStr); - if (Ver->VerStr == 0) + map_ptrloc const idxVerStr = WriteStringInMap(VerStr); + if (unlikely(idxVerStr == 0)) return 0; + Ver->VerStr = idxVerStr; return Version; } @@ -490,7 +567,7 @@ bool pkgCacheGenerator::NewFileDesc(pkgCache::DescIterator &Desc, return true; // Get a structure - unsigned long DescFile = AllocateInMap(sizeof(pkgCache::DescFile)); + map_ptrloc const DescFile = AllocateInMap(sizeof(pkgCache::DescFile)); if (DescFile == 0) return false; @@ -523,7 +600,7 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, map_ptrloc Next) { // Get a structure - map_ptrloc Description = AllocateInMap(sizeof(pkgCache::Description)); + map_ptrloc const Description = AllocateInMap(sizeof(pkgCache::Description)); if (Description == 0) return 0; @@ -531,10 +608,12 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, Desc = pkgCache::DescIterator(Cache,Cache.DescP + Description); Desc->NextDesc = Next; Desc->ID = Cache.HeaderP->DescriptionCount++; - Desc->language_code = WriteStringInMap(Lang); - Desc->md5sum = WriteStringInMap(md5sum.Value()); - if (Desc->language_code == 0 || Desc->md5sum == 0) + map_ptrloc const idxlanguage_code = WriteStringInMap(Lang); + map_ptrloc const idxmd5sum = WriteStringInMap(md5sum.Value()); + if (unlikely(idxlanguage_code == 0 || idxmd5sum == 0)) return 0; + Desc->language_code = idxlanguage_code; + Desc->md5sum = idxmd5sum; return Description; } @@ -550,15 +629,22 @@ bool pkgCacheGenerator::FinishCache(OpProgress *Progress) if (archs.size() > 1) { // Create Conflicts in between the group - for (pkgCache::GrpIterator G = GetCache().GrpBegin(); G.end() != true; G++) + pkgCache::GrpIterator G = GetCache().GrpBegin(); + Dynamic DynG(G); + for (; G.end() != true; G++) { string const PkgName = G.Name(); - for (pkgCache::PkgIterator P = G.PackageList(); P.end() != true; P = G.NextPkg(P)) + pkgCache::PkgIterator P = G.PackageList(); + Dynamic DynP(P); + for (; P.end() != true; P = G.NextPkg(P)) { if (strcmp(P.Arch(),"all") == 0) continue; pkgCache::PkgIterator allPkg; - for (pkgCache::VerIterator V = P.VersionList(); V.end() != true; V++) + Dynamic DynallPkg(allPkg); + pkgCache::VerIterator V = P.VersionList(); + Dynamic DynV(V); + for (; V.end() != true; V++) { string const Arch = V.Arch(true); map_ptrloc *OldDepLast = NULL; @@ -578,6 +664,7 @@ bool pkgCacheGenerator::FinishCache(OpProgress *Progress) per group, therefore each group member conflicts with all other group members */ pkgCache::PkgIterator D = G.FindPkg(*A); + Dynamic DynD(D); if (D.end() == true) continue; if (coInstall == true) @@ -622,13 +709,15 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, unsigned int const &Type, map_ptrloc *OldDepLast) { + void const * const oldMap = Map.Data(); // Get a structure - unsigned long const Dependency = AllocateInMap(sizeof(pkgCache::Dependency)); + map_ptrloc const Dependency = AllocateInMap(sizeof(pkgCache::Dependency)); if (unlikely(Dependency == 0)) return false; // Fill it in pkgCache::DepIterator Dep(Cache,Cache.DepP + Dependency); + Dynamic DynDep(Dep); Dep->ParentVer = Ver.Index(); Dep->Type = Type; Dep->CompareOp = Op; @@ -640,9 +729,12 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, /* for (pkgCache::DepIterator I = Pkg.RevDependsList(); I.end() == false; I++) if (I->Version != 0 && I.TargetVer() == Version) Dep->Version = I->Version;*/ - if (Dep->Version == 0) - if (unlikely((Dep->Version = WriteStringInMap(Version)) == 0)) + if (Dep->Version == 0) { + map_ptrloc const index = WriteStringInMap(Version); + if (unlikely(index == 0)) return false; + Dep->Version = index; + } } // Link it to the package @@ -656,7 +748,8 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, OldDepLast = &Ver->DependsList; for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++) OldDepLast = &D->NextDepends; - } + } else if (oldMap != Map.Data()) + OldDepLast += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap; Dep->NextDepends = *OldDepLast; *OldDepLast = Dep.Index(); @@ -677,11 +770,13 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator &Ver, unsigned int Type) { pkgCache::GrpIterator Grp; + Dynamic DynGrp(Grp); if (unlikely(Owner->NewGroup(Grp, PackageName) == false)) return false; // Locate the target package pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch); + Dynamic DynPkg(Pkg); if (Pkg.end() == true) { if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false)) return false; @@ -715,13 +810,14 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator &Ver, return true; // Get a structure - unsigned long const Provides = Owner->AllocateInMap(sizeof(pkgCache::Provides)); + map_ptrloc const Provides = Owner->AllocateInMap(sizeof(pkgCache::Provides)); if (unlikely(Provides == 0)) return false; Cache.HeaderP->ProvidesCount++; // Fill it in pkgCache::PrvIterator Prv(Cache,Cache.ProvideP + Provides,Cache.PkgP); + Dynamic DynPrv(Prv); Prv->Version = Ver.Index(); Prv->NextPkgProv = Ver->ProvidesList; Ver->ProvidesList = Prv.Index(); @@ -730,6 +826,7 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator &Ver, // Locate the target package pkgCache::PkgIterator Pkg; + Dynamic DynPkg(Pkg); if (unlikely(Owner->NewPackage(Pkg,PkgName, PkgArch) == false)) return false; @@ -750,24 +847,29 @@ bool pkgCacheGenerator::SelectFile(const string &File,const string &Site, unsigned long Flags) { // Get some space for the structure - CurrentFile = Cache.PkgFileP + AllocateInMap(sizeof(*CurrentFile)); - if (CurrentFile == Cache.PkgFileP) + map_ptrloc const idxFile = AllocateInMap(sizeof(*CurrentFile)); + if (unlikely(idxFile == 0)) return false; - + CurrentFile = Cache.PkgFileP + idxFile; + // Fill it in - CurrentFile->FileName = WriteStringInMap(File); - CurrentFile->Site = WriteUniqString(Site); + map_ptrloc const idxFileName = WriteStringInMap(File); + map_ptrloc const idxSite = WriteUniqString(Site); + if (unlikely(idxFileName == 0 || idxSite == 0)) + return false; + CurrentFile->FileName = idxFileName; + CurrentFile->Site = idxSite; CurrentFile->NextFile = Cache.HeaderP->FileList; CurrentFile->Flags = Flags; CurrentFile->ID = Cache.HeaderP->PackageFileCount; - CurrentFile->IndexType = WriteUniqString(Index.GetType()->Label); + map_ptrloc const idxIndexType = WriteUniqString(Index.GetType()->Label); + if (unlikely(idxIndexType == 0)) + return false; + CurrentFile->IndexType = idxIndexType; PkgFileName = File; Cache.HeaderP->FileList = CurrentFile - Cache.PkgFileP; Cache.HeaderP->PackageFileCount++; - if (CurrentFile->FileName == 0) - return false; - if (Progress != 0) Progress->SubProgress(Index.Size()); return true; @@ -807,18 +909,25 @@ unsigned long pkgCacheGenerator::WriteUniqString(const char *S, } // Get a structure - unsigned long Item = AllocateInMap(sizeof(pkgCache::StringItem)); + void const * const oldMap = Map.Data(); + map_ptrloc const Item = AllocateInMap(sizeof(pkgCache::StringItem)); if (Item == 0) return 0; + map_ptrloc const idxString = WriteStringInMap(S,Size); + if (unlikely(idxString == 0)) + return 0; + if (oldMap != Map.Data()) { + Last += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap; + I += (pkgCache::StringItem*) Map.Data() - (pkgCache::StringItem*) oldMap; + } + *Last = Item; + // Fill in the structure pkgCache::StringItem *ItemP = Cache.StringItemP + Item; ItemP->NextItem = I - Cache.StringItemP; - *Last = Item; - ItemP->String = WriteStringInMap(S,Size); - if (ItemP->String == 0) - return 0; - + ItemP->String = idxString; + Bucket = ItemP; return ItemP->String; } @@ -1072,7 +1181,7 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress unlink(CacheFile.c_str()); CacheF = new FileFd(CacheFile,FileFd::WriteEmpty); fchmod(CacheF->Fd(),0644); - Map = new DynamicMMap(*CacheF,MMap::Public,MapSize); + Map = new DynamicMMap(*CacheF,MMap::Public | MMap::Moveable, MapSize); if (_error->PendingError() == true) return false; if (Debug == true) @@ -1081,7 +1190,7 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress else { // Just build it in memory.. - Map = new DynamicMMap(0,MapSize); + Map = new DynamicMMap(MMap::Moveable, MapSize); if (Debug == true) std::clog << "Open memory Map (not filebased)" << std::endl; } @@ -1194,7 +1303,7 @@ bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **O if (_system->AddStatusFiles(Files) == false) return false; - SPtr Map = new DynamicMMap(0,MapSize); + SPtr Map = new DynamicMMap(MMap::Moveable, MapSize); unsigned long CurrentSize = 0; unsigned long TotalSize = 0; diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index 8f7739165..3bee1f958 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -23,6 +23,8 @@ #include #include +#include + class pkgSourceList; class OpProgress; class MMap; @@ -33,18 +35,32 @@ class pkgCacheGenerator /*{{{*/ private: pkgCache::StringItem *UniqHash[26]; - unsigned long WriteStringInMap(std::string const &String) { return WriteStringInMap(String.c_str()); }; - unsigned long WriteStringInMap(const char *String); - unsigned long WriteStringInMap(const char *String, const unsigned long &Len); - unsigned long AllocateInMap(const unsigned long &size); + map_ptrloc WriteStringInMap(std::string const &String) { return WriteStringInMap(String.c_str()); }; + map_ptrloc WriteStringInMap(const char *String); + map_ptrloc WriteStringInMap(const char *String, const unsigned long &Len); + map_ptrloc AllocateInMap(const unsigned long &size); public: class ListParser; friend class ListParser; - + + template class Dynamic { + Iter *I; + + public: + static std::set toReMap; + Dynamic(Iter &It) : I(&It) { + toReMap.insert(I); + } + + ~Dynamic() { + toReMap.erase(I); + } + }; + protected: - + DynamicMMap ⤅ pkgCache Cache; OpProgress *Progress; @@ -86,6 +102,8 @@ class pkgCacheGenerator /*{{{*/ MMap **OutMap = 0,bool AllowMem = false); static bool MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap); + void ReMap(void const * const oldMap, void const * const newMap); + pkgCacheGenerator(DynamicMMap *Map,OpProgress *Progress); ~pkgCacheGenerator(); }; -- cgit v1.2.3 From dcdf1ef18b37c243fc707869149f7761d964915c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 9 Jul 2010 17:00:28 +0200 Subject: * doc/apt.conf.5.xml: - add and document APT::Cache-{Start,Grow,Limit} options for mmap control --- apt-pkg/contrib/mmap.cc | 2 ++ apt-pkg/pkgcachegen.cc | 22 ++++++++++++++++------ apt-pkg/pkgcachegen.h | 1 + 3 files changed, 19 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc index aa184b130..69fb61fca 100644 --- a/apt-pkg/contrib/mmap.cc +++ b/apt-pkg/contrib/mmap.cc @@ -398,6 +398,8 @@ bool DynamicMMap::Grow() { if (Limit != 0 && WorkSpace >= Limit) return _error->Error(_("Unable to increase the size of the MMap as the " "limit of %lu bytes is already reached."), Limit); + if (GrowFactor <= 0) + return _error->Error(_("Unable to increase size of the MMap as automatic growing is disabled by user.")); unsigned long const newSize = WorkSpace + GrowFactor; diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 18bad6727..7ca8fbfda 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -1094,6 +1094,18 @@ static bool BuildCache(pkgCacheGenerator &Gen, return true; } /*}}}*/ +DynamicMMap* pkgCacheGenerator::CreateDynamicMMap(FileFd *CacheF, unsigned long Flags) { + unsigned long const MapStart = _config->FindI("APT::Cache-Start", 24*1024*1024); + unsigned long const MapGrow = _config->FindI("APT::Cache-Grow", 1*1024*1024); + unsigned long const MapLimit = _config->FindI("APT::Cache-Limit", 0); + Flags |= MMap::Moveable; + if (_config->FindB("APT::Cache-Fallback", false) == true) + Flags |= MMap::Fallback; + if (CacheF != NULL) + return new DynamicMMap(*CacheF, Flags, MapStart, MapGrow, MapLimit); + else + return new DynamicMMap(Flags, MapStart, MapGrow, MapLimit); +} // CacheGenerator::MakeStatusCache - Construct the status cache /*{{{*/ // --------------------------------------------------------------------- /* This makes sure that the status cache (the cache that has all @@ -1109,7 +1121,6 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress MMap **OutMap,bool AllowMem) { bool const Debug = _config->FindB("Debug::pkgCacheGen", false); - unsigned long const MapSize = _config->FindI("APT::Cache-Limit",24*1024*1024); vector Files; for (vector::const_iterator i = List.begin(); @@ -1181,7 +1192,7 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress unlink(CacheFile.c_str()); CacheF = new FileFd(CacheFile,FileFd::WriteEmpty); fchmod(CacheF->Fd(),0644); - Map = new DynamicMMap(*CacheF,MMap::Public | MMap::Moveable, MapSize); + Map = CreateDynamicMMap(CacheF, MMap::Public); if (_error->PendingError() == true) return false; if (Debug == true) @@ -1190,7 +1201,7 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress else { // Just build it in memory.. - Map = new DynamicMMap(MMap::Moveable, MapSize); + Map = CreateDynamicMMap(NULL); if (Debug == true) std::clog << "Open memory Map (not filebased)" << std::endl; } @@ -1297,13 +1308,12 @@ __deprecated bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutM { return pkgCacheGenerator::MakeOnlyStatusCache(&Progress, OutMap); } bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap) { - unsigned long MapSize = _config->FindI("APT::Cache-Limit",20*1024*1024); vector Files; unsigned long EndOfSource = Files.size(); if (_system->AddStatusFiles(Files) == false) return false; - - SPtr Map = new DynamicMMap(MMap::Moveable, MapSize); + + SPtr Map = CreateDynamicMMap(NULL); unsigned long CurrentSize = 0; unsigned long TotalSize = 0; diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index 3bee1f958..20dd28030 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -101,6 +101,7 @@ class pkgCacheGenerator /*{{{*/ static bool MakeStatusCache(pkgSourceList &List,OpProgress *Progress, MMap **OutMap = 0,bool AllowMem = false); static bool MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap); + static DynamicMMap* CreateDynamicMMap(FileFd *CacheF, unsigned long Flags = 0); void ReMap(void const * const oldMap, void const * const newMap); -- cgit v1.2.3 From 7635093c1c015e385a9e72bdd8a089fd9d48ab57 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 9 Jul 2010 19:51:19 +0200 Subject: switch from std::set to std::vector as it is way more simple, a bit faster and still provides everything we need for the Cache generator --- apt-pkg/pkgcachegen.cc | 16 ++++++++-------- apt-pkg/pkgcachegen.h | 12 +++++------- 2 files changed, 13 insertions(+), 15 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 7ca8fbfda..1175d5129 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -36,7 +36,7 @@ #include /*}}}*/ typedef vector::iterator FileIterator; -template std::set pkgCacheGenerator::Dynamic::toReMap; +template std::vector pkgCacheGenerator::Dynamic::toReMap(6); // CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/ // --------------------------------------------------------------------- @@ -113,25 +113,25 @@ void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newM if (UniqHash[i] != 0) UniqHash[i] += (pkgCache::StringItem*) newMap - (pkgCache::StringItem*) oldMap; - for (std::set::const_iterator i = Dynamic::toReMap.begin(); + for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) (*i)->ReOwn(Cache, oldMap, newMap); - for (std::set::const_iterator i = Dynamic::toReMap.begin(); + for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) (*i)->ReOwn(Cache, oldMap, newMap); - for (std::set::const_iterator i = Dynamic::toReMap.begin(); + for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) (*i)->ReOwn(Cache, oldMap, newMap); - for (std::set::const_iterator i = Dynamic::toReMap.begin(); + for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) (*i)->ReOwn(Cache, oldMap, newMap); - for (std::set::const_iterator i = Dynamic::toReMap.begin(); + for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) (*i)->ReOwn(Cache, oldMap, newMap); - for (std::set::const_iterator i = Dynamic::toReMap.begin(); + for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) (*i)->ReOwn(Cache, oldMap, newMap); - for (std::set::const_iterator i = Dynamic::toReMap.begin(); + for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) (*i)->ReOwn(Cache, oldMap, newMap); } /*}}}*/ diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index 20dd28030..ff198833a 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -23,7 +23,7 @@ #include #include -#include +#include class pkgSourceList; class OpProgress; @@ -46,16 +46,14 @@ class pkgCacheGenerator /*{{{*/ friend class ListParser; template class Dynamic { - Iter *I; - public: - static std::set toReMap; - Dynamic(Iter &It) : I(&It) { - toReMap.insert(I); + static std::vector toReMap; + Dynamic(Iter &I) { + toReMap.push_back(&I); } ~Dynamic() { - toReMap.erase(I); + toReMap.pop_back(); } }; -- cgit v1.2.3 From 62d073d937742baf8621a11c3094e0320aa846cd Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 9 Jul 2010 21:46:42 +0200 Subject: check the state of the FileFd before renaming as otherwise the rename will be tried twice e.g. in an "apt-get update" run and every other piece of code closing the FileFd manual before the destructor will do it again. --- apt-pkg/contrib/fileutl.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 62d42e4da..8f7791a8a 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -843,19 +843,21 @@ bool FileFd::Close() bool Res = true; if ((Flags & AutoClose) == AutoClose) if (iFd >= 0 && close(iFd) != 0) - Res &= _error->Errno("close",_("Problem closing the file")); - iFd = -1; + Res &= _error->Errno("close",_("Problem closing the file %s"), FileName.c_str()); - if ((Flags & Replace) == Replace) { + if ((Flags & Replace) == Replace && iFd >= 0) { if (rename(TemporaryFileName.c_str(), FileName.c_str()) != 0) - Res &= _error->Errno("rename",_("Problem renaming the file")); + Res &= _error->Errno("rename",_("Problem renaming the file %s to %s"), TemporaryFileName.c_str(), FileName.c_str()); + FileName = TemporaryFileName; // for the unlink() below. } - + + iFd = -1; + if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail && FileName.empty() == false) if (unlink(FileName.c_str()) != 0) - Res &= _error->WarningE("unlnk",_("Problem unlinking the file")); + Res &= _error->WarningE("unlnk",_("Problem unlinking the file %s"), FileName.c_str()); return Res; -- cgit v1.2.3 From 3c0929ecbeab50de9d38edc2eaebe92aeee65baf Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 10 Jul 2010 13:51:47 +0200 Subject: * apt-pkg/contrib/error.{cc,h}: - remove constness of va_list parameter to fix build on amd64 and co Thanks Eric Valette! (Closes: #588610) --- apt-pkg/contrib/error.cc | 9 ++++----- apt-pkg/contrib/error.h | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc index 8cee21c9c..fbb6e4636 100644 --- a/apt-pkg/contrib/error.cc +++ b/apt-pkg/contrib/error.cc @@ -94,11 +94,10 @@ bool GlobalError::DebugE(const char *Function,const char *Description,...) { /*}}}*/ // GlobalError::InsertErrno - formats an error message with the errno /*{{{*/ bool GlobalError::InsertErrno(MsgType type, const char* Function, - const char* Description, va_list const &args) { + const char* Description, va_list &args) { char S[400]; - vsnprintf(S,sizeof(S),Description,args); - snprintf(S + strlen(S),sizeof(S) - strlen(S), - " - %s (%i: %s)", Function, errno, strerror(errno)); + snprintf(S, sizeof(S), "%s - %s (%i: %s)", Description, + Function, errno, strerror(errno)); return Insert(type, S, args); } /*}}}*/ @@ -141,7 +140,7 @@ bool GlobalError::Debug(const char *Description,...) /*}}}*/ // GlobalError::Insert - Insert a new item at the end /*{{{*/ bool GlobalError::Insert(MsgType type, const char* Description, - va_list const &args) { + va_list &args) { char S[400]; vsnprintf(S,sizeof(S),Description,args); diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h index 73735162d..e5517c2da 100644 --- a/apt-pkg/contrib/error.h +++ b/apt-pkg/contrib/error.h @@ -278,9 +278,9 @@ private: /*{{{*/ std::list Stacks; bool InsertErrno(MsgType type, const char* Function, - const char* Description, va_list const &args); + const char* Description, va_list &args); bool Insert(MsgType type, const char* Description, - va_list const &args); + va_list &args); /*}}}*/ }; /*}}}*/ -- cgit v1.2.3 From dd13742ef11a6a601a2e85afd9d80be92ed7513a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 11 Jul 2010 18:50:41 +0200 Subject: * apt-pkg/deb/debmetaindex.cc: - do not query each architecture for flat file archives --- apt-pkg/deb/debindexfile.cc | 8 ++++---- apt-pkg/deb/deblistparser.cc | 2 +- apt-pkg/deb/debmetaindex.cc | 14 ++++++++++++-- apt-pkg/pkgcachegen.cc | 2 ++ 4 files changed, 19 insertions(+), 7 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index 7e9a973a4..ba5b3f266 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -184,8 +184,8 @@ string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const Res += " "; Res += Ver.ParentPkg().Name(); Res += " "; - Res += Ver.Arch(); - Res += " "; + if (Dist[Dist.size() - 1] != '/') + Res.append(Ver.Arch()).append(" "); Res += Ver.VerStr(); return Res; } @@ -219,8 +219,8 @@ string debPackagesIndex::Info(const char *Type) const else Info += Dist + '/' + Section; Info += " "; - Info += Architecture; - Info += " "; + if (Dist[Dist.size() - 1] != '/') + Info += Architecture + " "; Info += Type; return Info; } diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 2cfeb23e9..5fb737970 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -757,7 +757,7 @@ bool debListParser::Step() if (Architecture.empty() == true) return true; - if (Arch.empty() == true || MultiArchEnabled == false) + if (Arch.empty() == true || Arch == "any" || MultiArchEnabled == false) { if (APT::Configuration::checkArchitecture(Architecture) == true) return true; diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 8df3ed18d..7366bd624 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -332,7 +332,12 @@ class debSLTypeDebian : public pkgSourceList::Type if (IsSrc == true) Deb->PushSectionEntry("source", new debReleaseIndex::debSectionEntry(Section, IsSrc)); else - Deb->PushSectionEntry(Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc)); + { + if (Dist[Dist.size() - 1] == '/') + Deb->PushSectionEntry("any", new debReleaseIndex::debSectionEntry(Section, IsSrc)); + else + Deb->PushSectionEntry(Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc)); + } return true; } } @@ -342,7 +347,12 @@ class debSLTypeDebian : public pkgSourceList::Type if (IsSrc == true) Deb->PushSectionEntry ("source", new debReleaseIndex::debSectionEntry(Section, IsSrc)); else - Deb->PushSectionEntry (Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc)); + { + if (Dist[Dist.size() - 1] == '/') + Deb->PushSectionEntry ("any", new debReleaseIndex::debSectionEntry(Section, IsSrc)); + else + Deb->PushSectionEntry (Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc)); + } List.push_back(Deb); return true; } diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 1175d5129..38f2d6a2a 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -1094,6 +1094,7 @@ static bool BuildCache(pkgCacheGenerator &Gen, return true; } /*}}}*/ +// CacheGenerator::CreateDynamicMMap - load an mmap with configuration options /*{{{*/ DynamicMMap* pkgCacheGenerator::CreateDynamicMMap(FileFd *CacheF, unsigned long Flags) { unsigned long const MapStart = _config->FindI("APT::Cache-Start", 24*1024*1024); unsigned long const MapGrow = _config->FindI("APT::Cache-Grow", 1*1024*1024); @@ -1106,6 +1107,7 @@ DynamicMMap* pkgCacheGenerator::CreateDynamicMMap(FileFd *CacheF, unsigned long else return new DynamicMMap(Flags, MapStart, MapGrow, MapLimit); } + /*}}}*/ // CacheGenerator::MakeStatusCache - Construct the status cache /*{{{*/ // --------------------------------------------------------------------- /* This makes sure that the status cache (the cache that has all -- cgit v1.2.3 From ff1ad6fdb01ad8d477ab711e4f6fe006d622f3bc Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 11 Jul 2010 18:58:54 +0200 Subject: fix typo preventing display of architecture in Info() --- apt-pkg/deb/debmetaindex.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 7366bd624..717d0bcde 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -23,7 +23,7 @@ string debReleaseIndex::Info(const char *Type, string const &Section, string con else { Info += Dist + '/' + Section; - if (Arch.empty() == true) + if (Arch.empty() != true) Info += " " + Arch; } Info += " "; -- cgit v1.2.3 From f7a35f2e813cff49470b4c4cb5b79cf6277f97d9 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 11 Jul 2010 19:19:35 +0200 Subject: rename ReOwn to ReMap in the cacheiterators --- apt-pkg/cacheiterators.h | 4 ++-- apt-pkg/pkgcachegen.cc | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index eb8dee5e3..1dcc34532 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -75,8 +75,8 @@ template class pkgCache::Iterator : inline bool IsGood() const { return S && Owner && ! end();}; inline unsigned long Index() const {return S - OwnerPointer();}; - void ReOwn(pkgCache &newOwner, void const * const oldMap, void const * const newMap) { - if (S == 0) + void ReMap(void const * const oldMap, void const * const newMap) { + if (Owner == 0 || S == 0) return; S += (Str*)(newMap) - (Str*)(oldMap); } diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 38f2d6a2a..75f2ffe45 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -115,25 +115,25 @@ void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newM for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReOwn(Cache, oldMap, newMap); + (*i)->ReMap(oldMap, newMap); for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReOwn(Cache, oldMap, newMap); + (*i)->ReMap(oldMap, newMap); for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReOwn(Cache, oldMap, newMap); + (*i)->ReMap(oldMap, newMap); for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReOwn(Cache, oldMap, newMap); + (*i)->ReMap(oldMap, newMap); for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReOwn(Cache, oldMap, newMap); + (*i)->ReMap(oldMap, newMap); for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReOwn(Cache, oldMap, newMap); + (*i)->ReMap(oldMap, newMap); for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) - (*i)->ReOwn(Cache, oldMap, newMap); + (*i)->ReMap(oldMap, newMap); } /*}}}*/ // CacheGenerator::WriteStringInMap /*{{{*/ map_ptrloc pkgCacheGenerator::WriteStringInMap(const char *String, -- cgit v1.2.3 From f5eb830c02cb0724cb1d2e70f56cd508583aaf9a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 11 Jul 2010 19:44:14 +0200 Subject: mark all "Hash Sum mismatch" strings as translateable --- apt-pkg/acquire-item.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 020efdfaa..a289fb7ba 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -1710,7 +1710,7 @@ void pkgAcqFile::Done(string Message,unsigned long Size,string CalcHash, if(!ExpectedHash.empty() && ExpectedHash.toStr() != CalcHash) { Status = StatError; - ErrorText = "Hash Sum mismatch"; + ErrorText = _("Hash Sum mismatch"); Rename(DestFile,DestFile + ".FAILED"); return; } -- cgit v1.2.3 From d10cef824604012516f26efaae8bab1f29a7820a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 11 Jul 2010 23:07:58 +0200 Subject: accidently prefilling the vectors results in segfaults --- apt-pkg/pkgcachegen.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 75f2ffe45..c9a9a753c 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -36,7 +36,7 @@ #include /*}}}*/ typedef vector::iterator FileIterator; -template std::vector pkgCacheGenerator::Dynamic::toReMap(6); +template std::vector pkgCacheGenerator::Dynamic::toReMap; // CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/ // --------------------------------------------------------------------- -- cgit v1.2.3 From d3814b27a7ba26236835180c37de72e6afbdffb2 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 14 Jul 2010 22:59:43 +0200 Subject: * apt-pkg/depcache.cc: - handle "circular" conflicts for "all" packages correctly --- apt-pkg/depcache.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 05127fe18..bc663a8e9 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -338,7 +338,7 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res) /* Check simple depends. A depends -should- never self match but we allow it anyhow because dpkg does. Technically it is a packaging bug. Conflicts may never self match */ - if (Dep.TargetPkg() != Dep.ParentPkg() || + if (Dep.TargetPkg()->Group != Dep.ParentPkg()->Group || (Dep->Type != Dep::Conflicts && Dep->Type != Dep::DpkgBreaks && Dep->Type != Dep::Obsoletes)) { PkgIterator Pkg = Dep.TargetPkg(); @@ -367,9 +367,9 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res) PkgIterator Pkg = Dep.ParentPkg(); for (; P.end() != true; P++) { - /* Provides may never be applied against the same package if it is - a conflicts. See the comment above. */ - if (P.OwnerPkg() == Pkg && + /* Provides may never be applied against the same package (or group) + if it is a conflicts. See the comment above. */ + if (P.OwnerPkg()->Group == Pkg->Group && (Dep->Type == Dep::Conflicts || Dep->Type == Dep::DpkgBreaks)) continue; -- cgit v1.2.3 From 9ba5aa3b01f1f7c08c74f5d0a21971db221d30f1 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 17 Jul 2010 19:07:00 +0200 Subject: factor regex package name matches into newly created cachefilter classes --- apt-pkg/cachefilter.cc | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ apt-pkg/cachefilter.h | 29 +++++++++++++++++++++++++++ apt-pkg/makefile | 5 +++-- 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 apt-pkg/cachefilter.cc create mode 100644 apt-pkg/cachefilter.h (limited to 'apt-pkg') diff --git a/apt-pkg/cachefilter.cc b/apt-pkg/cachefilter.cc new file mode 100644 index 000000000..8f0725ea3 --- /dev/null +++ b/apt-pkg/cachefilter.cc @@ -0,0 +1,54 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/** \file cachefilter.h + Collection of functor classes */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include + +#include + +#include + +#include + /*}}}*/ +namespace APT { +namespace CacheFilter { +PackageNameMatchesRegEx::PackageNameMatchesRegEx(std::string const &Pattern) {/*{{{*/ + pattern = new regex_t; + int const Res = regcomp(pattern, Pattern.c_str(), REG_EXTENDED | REG_ICASE | REG_NOSUB); + if (Res == 0) + return; + + delete pattern; + pattern = NULL; + char Error[300]; + regerror(Res, pattern, Error, sizeof(Error)); + _error->Error(_("Regex compilation error - %s"), Error); +} + /*}}}*/ +bool PackageNameMatchesRegEx::operator() (pkgCache::PkgIterator const &Pkg) {/*{{{*/ + if (unlikely(pattern == NULL)) + return false; + else + return regexec(pattern, Pkg.Name(), 0, 0, 0) == 0; +} + /*}}}*/ +bool PackageNameMatchesRegEx::operator() (pkgCache::GrpIterator const &Grp) {/*{{{*/ + if (unlikely(pattern == NULL)) + return false; + else + return regexec(pattern, Grp.Name(), 0, 0, 0) == 0; +} + /*}}}*/ +PackageNameMatchesRegEx::~PackageNameMatchesRegEx() { /*{{{*/ + if (pattern == NULL) + return; + regfree(pattern); + delete pattern; +} + /*}}}*/ +} +} diff --git a/apt-pkg/cachefilter.h b/apt-pkg/cachefilter.h new file mode 100644 index 000000000..e7ab1723f --- /dev/null +++ b/apt-pkg/cachefilter.h @@ -0,0 +1,29 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/** \file cachefilter.h + Collection of functor classes */ + /*}}}*/ +#ifndef APT_CACHEFILTER_H +#define APT_CACHEFILTER_H +// Include Files /*{{{*/ +#include + +#include + +#include + /*}}}*/ +namespace APT { +namespace CacheFilter { +// PackageNameMatchesRegEx /*{{{*/ +class PackageNameMatchesRegEx { + regex_t* pattern; +public: + PackageNameMatchesRegEx(std::string const &Pattern); + bool operator() (pkgCache::PkgIterator const &Pkg); + bool operator() (pkgCache::GrpIterator const &Grp); + ~PackageNameMatchesRegEx(); +}; + /*}}}*/ +} +} +#endif diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 2a7958536..e9e5651b0 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -35,14 +35,15 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \ srcrecords.cc cachefile.cc versionmatch.cc policy.cc \ pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \ indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \ - aptconfiguration.cc + aptconfiguration.cc cachefilter.cc HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ orderlist.h sourcelist.h packagemanager.h tagfile.h \ init.h pkgcache.h version.h progress.h pkgrecords.h \ acquire.h acquire-worker.h acquire-item.h acquire-method.h \ clean.h srcrecords.h cachefile.h versionmatch.h policy.h \ pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \ - vendorlist.h cdrom.h indexcopy.h aptconfiguration.h + vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \ + cachefilter.h # Source code for the debian specific components # In theory the deb headers do not need to be exported.. -- cgit v1.2.3 From 8fde723961709118837153cdf94f150c680e10e9 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 17 Jul 2010 20:04:44 +0200 Subject: * apt-pkg/cacheset.cc: - move them back to the library as they look stable now --- apt-pkg/cacheset.cc | 506 ++++++++++++++++++++++++++++++++++++++++++++++++++++ apt-pkg/cacheset.h | 375 ++++++++++++++++++++++++++++++++++++++ apt-pkg/makefile | 4 +- 3 files changed, 883 insertions(+), 2 deletions(-) create mode 100644 apt-pkg/cacheset.cc create mode 100644 apt-pkg/cacheset.h (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc new file mode 100644 index 000000000..df7e99fd0 --- /dev/null +++ b/apt-pkg/cacheset.cc @@ -0,0 +1,506 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + Simple wrapper around a std::set to provide a similar interface to + a set of cache structures as to the complete set of all structures + in the pkgCache. Currently only Package is supported. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + /*}}}*/ +namespace APT { +// FromTask - Return all packages in the cache from a specific task /*{{{*/ +PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { + size_t const archfound = pattern.find_last_of(':'); + std::string arch = "native"; + if (archfound != std::string::npos) { + arch = pattern.substr(archfound+1); + pattern.erase(archfound); + } + + if (pattern[pattern.length() -1] != '^') + return APT::PackageSet(TASK); + pattern.erase(pattern.length()-1); + + if (unlikely(Cache.GetPkgCache() == 0 || Cache.GetDepCache() == 0)) + return APT::PackageSet(TASK); + + PackageSet pkgset(TASK); + // get the records + pkgRecords Recs(Cache); + + // build regexp for the task + regex_t Pattern; + char S[300]; + snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", pattern.c_str()); + if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0) { + _error->Error("Failed to compile task regexp"); + return pkgset; + } + + for (pkgCache::GrpIterator Grp = Cache->GrpBegin(); Grp.end() == false; ++Grp) { + pkgCache::PkgIterator Pkg = Grp.FindPkg(arch); + if (Pkg.end() == true) + continue; + pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache); + if(ver.end() == true) + continue; + + pkgRecords::Parser &parser = Recs.Lookup(ver.FileList()); + const char *start, *end; + parser.GetRec(start,end); + unsigned int const length = end - start; + char buf[length]; + strncpy(buf, start, length); + buf[length-1] = '\0'; + if (regexec(&Pattern, buf, 0, 0, 0) != 0) + continue; + + pkgset.insert(Pkg); + } + regfree(&Pattern); + + if (pkgset.empty() == true) + return helper.canNotFindTask(Cache, pattern); + + helper.showTaskSelection(pkgset, pattern); + return pkgset; +} + /*}}}*/ +// FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ +PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { + static const char * const isregex = ".?+*|[^$"; + if (pattern.find_first_of(isregex) == std::string::npos) + return PackageSet(REGEX); + + size_t archfound = pattern.find_last_of(':'); + std::string arch = "native"; + if (archfound != std::string::npos) { + arch = pattern.substr(archfound+1); + if (arch.find_first_of(isregex) == std::string::npos) + pattern.erase(archfound); + else + arch = "native"; + } + + if (unlikely(Cache.GetPkgCache() == 0)) + return PackageSet(REGEX); + + APT::CacheFilter::PackageNameMatchesRegEx regexfilter(pattern); + + PackageSet pkgset(REGEX); + for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) { + if (regexfilter(Grp) == false) + continue; + pkgCache::PkgIterator Pkg = Grp.FindPkg(arch); + if (Pkg.end() == true) { + if (archfound == std::string::npos) { + std::vector archs = APT::Configuration::getArchitectures(); + for (std::vector::const_iterator a = archs.begin(); + a != archs.end() && Pkg.end() != true; ++a) + Pkg = Grp.FindPkg(*a); + } + if (Pkg.end() == true) + continue; + } + + pkgset.insert(Pkg); + } + + if (pkgset.empty() == true) + return helper.canNotFindRegEx(Cache, pattern); + + helper.showRegExSelection(pkgset, pattern); + return pkgset; +} + /*}}}*/ +// FromName - Returns the package defined by this string /*{{{*/ +pkgCache::PkgIterator PackageSet::FromName(pkgCacheFile &Cache, + std::string const &str, CacheSetHelper &helper) { + std::string pkg = str; + size_t archfound = pkg.find_last_of(':'); + std::string arch; + if (archfound != std::string::npos) { + arch = pkg.substr(archfound+1); + pkg.erase(archfound); + } + + if (Cache.GetPkgCache() == 0) + return pkgCache::PkgIterator(Cache, 0); + + pkgCache::PkgIterator Pkg(Cache, 0); + if (arch.empty() == true) { + pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(pkg); + if (Grp.end() == false) + Pkg = Grp.FindPreferredPkg(); + } else + Pkg = Cache.GetPkgCache()->FindPkg(pkg, arch); + + if (Pkg.end() == true) + return helper.canNotFindPkgName(Cache, str); + return Pkg; +} + /*}}}*/ +// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ +std::map PackageSet::GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, CacheSetHelper &helper) { + std::map pkgsets; + for (const char **I = cmdline; *I != 0; ++I) { + unsigned short modID = fallback; + std::string str = *I; + bool modifierPresent = false; + for (std::list::const_iterator mod = mods.begin(); + mod != mods.end(); ++mod) { + size_t const alength = strlen(mod->Alias); + switch(mod->Pos) { + case PackageSet::Modifier::POSTFIX: + if (str.compare(str.length() - alength, alength, + mod->Alias, 0, alength) != 0) + continue; + str.erase(str.length() - alength); + modID = mod->ID; + break; + case PackageSet::Modifier::PREFIX: + continue; + case PackageSet::Modifier::NONE: + continue; + } + modifierPresent = true; + break; + } + if (modifierPresent == true) { + bool const errors = helper.showErrors(false); + pkgCache::PkgIterator Pkg = FromName(Cache, *I, helper); + helper.showErrors(errors); + if (Pkg.end() == false) { + pkgsets[fallback].insert(Pkg); + continue; + } + } + pkgsets[modID].insert(PackageSet::FromString(Cache, str, helper)); + } + return pkgsets; +} + /*}}}*/ +// FromCommandLine - Return all packages specified on commandline /*{{{*/ +PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) { + PackageSet pkgset; + for (const char **I = cmdline; *I != 0; ++I) { + PackageSet pset = FromString(Cache, *I, helper); + pkgset.insert(pset.begin(), pset.end()); + } + return pkgset; +} + /*}}}*/ +// FromString - Return all packages matching a specific string /*{{{*/ +PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, CacheSetHelper &helper) { + _error->PushToStack(); + + PackageSet pkgset; + pkgCache::PkgIterator Pkg = FromName(Cache, str, helper); + if (Pkg.end() == false) + pkgset.insert(Pkg); + else { + pkgset = FromTask(Cache, str, helper); + if (pkgset.empty() == true) { + pkgset = FromRegEx(Cache, str, helper); + if (pkgset.empty() == true) + pkgset = helper.canNotFindPackage(Cache, str); + } + } + + if (pkgset.empty() == false) + _error->RevertToStack(); + else + _error->MergeWithStack(); + return pkgset; +} + /*}}}*/ +// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ +std::map VersionSet::GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, CacheSetHelper &helper) { + std::map versets; + for (const char **I = cmdline; *I != 0; ++I) { + unsigned short modID = fallback; + VersionSet::Version select = VersionSet::NEWEST; + std::string str = *I; + bool modifierPresent = false; + for (std::list::const_iterator mod = mods.begin(); + mod != mods.end(); ++mod) { + if (modID == fallback && mod->ID == fallback) + select = mod->SelectVersion; + size_t const alength = strlen(mod->Alias); + switch(mod->Pos) { + case VersionSet::Modifier::POSTFIX: + if (str.compare(str.length() - alength, alength, + mod->Alias, 0, alength) != 0) + continue; + str.erase(str.length() - alength); + modID = mod->ID; + select = mod->SelectVersion; + break; + case VersionSet::Modifier::PREFIX: + continue; + case VersionSet::Modifier::NONE: + continue; + } + modifierPresent = true; + break; + } + + if (modifierPresent == true) { + bool const errors = helper.showErrors(false); + VersionSet const vset = VersionSet::FromString(Cache, std::string(*I), select, helper, true); + helper.showErrors(errors); + if (vset.empty() == false) { + versets[fallback].insert(vset); + continue; + } + } + versets[modID].insert(VersionSet::FromString(Cache, str, select , helper)); + } + return versets; +} + /*}}}*/ +// FromCommandLine - Return all versions specified on commandline /*{{{*/ +APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, + APT::VersionSet::Version const &fallback, CacheSetHelper &helper) { + VersionSet verset; + for (const char **I = cmdline; *I != 0; ++I) + verset.insert(VersionSet::FromString(Cache, *I, fallback, helper)); + return verset; +} + /*}}}*/ +// FromString - Returns all versions spedcified by a string /*{{{*/ +APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, + APT::VersionSet::Version const &fallback, CacheSetHelper &helper, + bool const &onlyFromName) { + std::string ver; + bool verIsRel = false; + size_t const vertag = pkg.find_last_of("/="); + if (vertag != string::npos) { + ver = pkg.substr(vertag+1); + verIsRel = (pkg[vertag] == '/'); + pkg.erase(vertag); + } + PackageSet pkgset; + if (onlyFromName == false) + pkgset = PackageSet::FromString(Cache, pkg, helper); + else { + pkgset.insert(PackageSet::FromName(Cache, pkg, helper)); + } + + VersionSet verset; + bool errors = true; + if (pkgset.getConstructor() != PackageSet::UNKNOWN) + errors = helper.showErrors(false); + for (PackageSet::const_iterator P = pkgset.begin(); + P != pkgset.end(); ++P) { + if (vertag == string::npos) { + verset.insert(VersionSet::FromPackage(Cache, P, fallback, helper)); + continue; + } + pkgCache::VerIterator V; + if (ver == "installed") + V = getInstalledVer(Cache, P, helper); + else if (ver == "candidate") + V = getCandidateVer(Cache, P, helper); + else { + pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release : + pkgVersionMatch::Version)); + V = Match.Find(P); + if (V.end() == true) { + if (verIsRel == true) + _error->Error(_("Release '%s' for '%s' was not found"), + ver.c_str(), P.FullName(true).c_str()); + else + _error->Error(_("Version '%s' for '%s' was not found"), + ver.c_str(), P.FullName(true).c_str()); + continue; + } + } + if (V.end() == true) + continue; + helper.showSelectedVersion(P, V, ver, verIsRel); + verset.insert(V); + } + if (pkgset.getConstructor() != PackageSet::UNKNOWN) + helper.showErrors(errors); + return verset; +} + /*}}}*/ +// FromPackage - versions from package based on fallback /*{{{*/ +VersionSet VersionSet::FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, + VersionSet::Version const &fallback, CacheSetHelper &helper) { + VersionSet verset; + pkgCache::VerIterator V; + bool showErrors; + switch(fallback) { + case VersionSet::ALL: + if (P->VersionList != 0) + for (V = P.VersionList(); V.end() != true; ++V) + verset.insert(V); + else + verset.insert(helper.canNotFindAllVer(Cache, P)); + break; + case VersionSet::CANDANDINST: + verset.insert(getInstalledVer(Cache, P, helper)); + verset.insert(getCandidateVer(Cache, P, helper)); + break; + case VersionSet::CANDIDATE: + verset.insert(getCandidateVer(Cache, P, helper)); + break; + case VersionSet::INSTALLED: + verset.insert(getInstalledVer(Cache, P, helper)); + break; + case VersionSet::CANDINST: + showErrors = helper.showErrors(false); + V = getCandidateVer(Cache, P, helper); + if (V.end() == true) + V = getInstalledVer(Cache, P, helper); + helper.showErrors(showErrors); + if (V.end() == false) + verset.insert(V); + else + verset.insert(helper.canNotFindInstCandVer(Cache, P)); + break; + case VersionSet::INSTCAND: + showErrors = helper.showErrors(false); + V = getInstalledVer(Cache, P, helper); + if (V.end() == true) + V = getCandidateVer(Cache, P, helper); + helper.showErrors(showErrors); + if (V.end() == false) + verset.insert(V); + else + verset.insert(helper.canNotFindInstCandVer(Cache, P)); + break; + case VersionSet::NEWEST: + if (P->VersionList != 0) + verset.insert(P.VersionList()); + else + verset.insert(helper.canNotFindNewestVer(Cache, P)); + break; + } + return verset; +} + /*}}}*/ +// getCandidateVer - Returns the candidate version of the given package /*{{{*/ +pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) { + pkgCache::VerIterator Cand; + if (Cache.IsPolicyBuilt() == true || Cache.IsDepCacheBuilt() == false) + { + if (unlikely(Cache.GetPolicy() == 0)) + return pkgCache::VerIterator(Cache); + Cand = Cache.GetPolicy()->GetCandidateVer(Pkg); + } else { + Cand = Cache[Pkg].CandidateVerIter(Cache); + } + if (Cand.end() == true) + return helper.canNotFindCandidateVer(Cache, Pkg); + return Cand; +} + /*}}}*/ +// getInstalledVer - Returns the installed version of the given package /*{{{*/ +pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) { + if (Pkg->CurrentVer == 0) + return helper.canNotFindInstalledVer(Cache, Pkg); + return Pkg.CurrentVer(); +} + /*}}}*/ +// canNotFindPkgName - handle the case no package has this name /*{{{*/ +pkgCache::PkgIterator CacheSetHelper::canNotFindPkgName(pkgCacheFile &Cache, + std::string const &str) { + if (ShowError == true) + _error->Error(_("Unable to locate package %s"), str.c_str()); + return pkgCache::PkgIterator(Cache, 0); +} + /*}}}*/ +// canNotFindTask - handle the case no package is found for a task /*{{{*/ +PackageSet CacheSetHelper::canNotFindTask(pkgCacheFile &Cache, std::string pattern) { + if (ShowError == true) + _error->Error(_("Couldn't find task '%s'"), pattern.c_str()); + return PackageSet(); +} + /*}}}*/ +// canNotFindRegEx - handle the case no package is found by a regex /*{{{*/ +PackageSet CacheSetHelper::canNotFindRegEx(pkgCacheFile &Cache, std::string pattern) { + if (ShowError == true) + _error->Error(_("Couldn't find any package by regex '%s'"), pattern.c_str()); + return PackageSet(); +} + /*}}}*/ +// canNotFindPackage - handle the case no package is found from a string/*{{{*/ +PackageSet CacheSetHelper::canNotFindPackage(pkgCacheFile &Cache, std::string const &str) { + return PackageSet(); +} + /*}}}*/ +// canNotFindAllVer /*{{{*/ +VersionSet CacheSetHelper::canNotFindAllVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg) { + if (ShowError == true) + _error->Error(_("Can't select versions from package '%s' as it purely virtual"), Pkg.FullName(true).c_str()); + return VersionSet(); +} + /*}}}*/ +// canNotFindInstCandVer /*{{{*/ +VersionSet CacheSetHelper::canNotFindInstCandVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg) { + if (ShowError == true) + _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str()); + return VersionSet(); +} + /*}}}*/ +// canNotFindInstCandVer /*{{{*/ +VersionSet CacheSetHelper::canNotFindCandInstVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg) { + if (ShowError == true) + _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str()); + return VersionSet(); +} + /*}}}*/ +// canNotFindNewestVer /*{{{*/ +pkgCache::VerIterator CacheSetHelper::canNotFindNewestVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg) { + if (ShowError == true) + _error->Error(_("Can't select newest version from package '%s' as it is purely virtual"), Pkg.FullName(true).c_str()); + return pkgCache::VerIterator(Cache, 0); +} + /*}}}*/ +// canNotFindCandidateVer /*{{{*/ +pkgCache::VerIterator CacheSetHelper::canNotFindCandidateVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg) { + if (ShowError == true) + _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str()); + return pkgCache::VerIterator(Cache, 0); +} + /*}}}*/ +// canNotFindInstalledVer /*{{{*/ +pkgCache::VerIterator CacheSetHelper::canNotFindInstalledVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg) { + if (ShowError == true) + _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str()); + return pkgCache::VerIterator(Cache, 0); +} + /*}}}*/ +} diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h new file mode 100644 index 000000000..c8c3dd096 --- /dev/null +++ b/apt-pkg/cacheset.h @@ -0,0 +1,375 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/** \file cacheset.h + Wrappers around std::set to have set::iterators which behave + similar to the Iterators of the cache structures. + + Provides also a few helper methods which work with these sets */ + /*}}}*/ +#ifndef APT_CACHESET_H +#define APT_CACHESET_H +// Include Files /*{{{*/ +#include +#include +#include +#include +#include +#include + +#include +#include + /*}}}*/ +namespace APT { +class PackageSet; +class VersionSet; +class CacheSetHelper { /*{{{*/ +/** \class APT::CacheSetHelper + Simple base class with a lot of virtual methods which can be overridden + to alter the behavior or the output of the CacheSets. + + This helper is passed around by the static methods in the CacheSets and + used every time they hit an error condition or something could be + printed out. +*/ +public: /*{{{*/ + CacheSetHelper(bool const &ShowError = true) : ShowError(ShowError) {}; + virtual ~CacheSetHelper() {}; + + virtual void showTaskSelection(PackageSet const &pkgset, string const &pattern) {}; + virtual void showRegExSelection(PackageSet const &pkgset, string const &pattern) {}; + virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver, + string const &ver, bool const &verIsRel) {}; + + virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str); + virtual PackageSet canNotFindTask(pkgCacheFile &Cache, std::string pattern); + virtual PackageSet canNotFindRegEx(pkgCacheFile &Cache, std::string pattern); + virtual PackageSet canNotFindPackage(pkgCacheFile &Cache, std::string const &str); + virtual VersionSet canNotFindAllVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); + virtual VersionSet canNotFindInstCandVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg); + virtual VersionSet canNotFindCandInstVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg); + virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg); + virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg); + virtual pkgCache::VerIterator canNotFindInstalledVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg); + + bool showErrors() const { return ShowError; }; + bool showErrors(bool const &newValue) { if (ShowError == newValue) return ShowError; else return ((ShowError = newValue) == false); }; + /*}}}*/ +protected: + bool ShowError; +}; /*}}}*/ +class PackageSet : public std::set { /*{{{*/ +/** \class APT::PackageSet + + Simple wrapper around a std::set to provide a similar interface to + a set of packages as to the complete set of all packages in the + pkgCache. */ +public: /*{{{*/ + /** \brief smell like a pkgCache::PkgIterator */ + class const_iterator : public std::set::const_iterator {/*{{{*/ + public: + const_iterator(std::set::const_iterator x) : + std::set::const_iterator(x) {} + + operator pkgCache::PkgIterator(void) { return **this; } + + inline const char *Name() const {return (**this).Name(); } + inline std::string FullName(bool const &Pretty) const { return (**this).FullName(Pretty); } + inline std::string FullName() const { return (**this).FullName(); } + inline const char *Section() const {return (**this).Section(); } + inline bool Purge() const {return (**this).Purge(); } + inline const char *Arch() const {return (**this).Arch(); } + inline pkgCache::GrpIterator Group() const { return (**this).Group(); } + inline pkgCache::VerIterator VersionList() const { return (**this).VersionList(); } + inline pkgCache::VerIterator CurrentVer() const { return (**this).CurrentVer(); } + inline pkgCache::DepIterator RevDependsList() const { return (**this).RevDependsList(); } + inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); } + inline pkgCache::PkgIterator::OkState State() const { return (**this).State(); } + inline const char *CandVersion() const { return (**this).CandVersion(); } + inline const char *CurVersion() const { return (**this).CurVersion(); } + inline pkgCache *Cache() const { return (**this).Cache(); }; + inline unsigned long Index() const {return (**this).Index();}; + // we have only valid iterators here + inline bool end() const { return false; }; + + friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, (*i)); } + + inline pkgCache::Package const * operator->() const { + return &***this; + }; + }; + // 103. set::iterator is required to be modifiable, but this allows modification of keys + typedef APT::PackageSet::const_iterator iterator; + /*}}}*/ + + using std::set::insert; + inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set::insert(P); }; + inline void insert(PackageSet const &pkgset) { insert(pkgset.begin(), pkgset.end()); }; + + /** \brief returns all packages in the cache who belong to the given task + + A simple helper responsible for search for all members of a task + in the cache. Optional it prints a a notice about the + packages chosen cause of the given task. + \param Cache the packages are in + \param pattern name of the task + \param helper responsible for error and message handling */ + static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper); + static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string const &pattern) { + CacheSetHelper helper; + return APT::PackageSet::FromTask(Cache, pattern, helper); + } + + /** \brief returns all packages in the cache whose name matchs a given pattern + + A simple helper responsible for executing a regular expression on all + package names in the cache. Optional it prints a a notice about the + packages chosen cause of the given package. + \param Cache the packages are in + \param pattern regular expression for package names + \param helper responsible for error and message handling */ + static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper); + static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string const &pattern) { + CacheSetHelper helper; + return APT::PackageSet::FromRegEx(Cache, pattern, helper); + } + + /** \brief returns all packages specified by a string + + \param Cache the packages are in + \param string String the package name(s) should be extracted from + \param helper responsible for error and message handling */ + static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper); + static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string) { + CacheSetHelper helper; + return APT::PackageSet::FromString(Cache, string, helper); + } + + /** \brief returns a package specified by a string + + \param Cache the package is in + \param string String the package name should be extracted from + \param helper responsible for error and message handling */ + static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper); + static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string) { + CacheSetHelper helper; + return APT::PackageSet::FromName(Cache, string, helper); + } + + /** \brief returns all packages specified on the commandline + + Get all package names from the commandline and executes regex's if needed. + No special package command is supported, just plain names. + \param Cache the packages are in + \param cmdline Command line the package names should be extracted from + \param helper responsible for error and message handling */ + static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper); + static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { + CacheSetHelper helper; + return APT::PackageSet::FromCommandLine(Cache, cmdline, helper); + } + + struct Modifier { + enum Position { NONE, PREFIX, POSTFIX }; + unsigned short ID; + const char * const Alias; + Position Pos; + Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {}; + }; + + /** \brief group packages by a action modifiers + + At some point it is needed to get from the same commandline + different package sets grouped by a modifier. Take + apt-get install apt awesome- + as an example. + \param Cache the packages are in + \param cmdline Command line the package names should be extracted from + \param mods list of modifiers the method should accept + \param fallback the default modifier group for a package + \param helper responsible for error and message handling */ + static std::map GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, CacheSetHelper &helper); + static std::map GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback) { + CacheSetHelper helper; + return APT::PackageSet::GroupedFromCommandLine(Cache, cmdline, + mods, fallback, helper); + } + + enum Constructor { UNKNOWN, REGEX, TASK }; + Constructor getConstructor() const { return ConstructedBy; }; + + PackageSet() : ConstructedBy(UNKNOWN) {}; + PackageSet(Constructor const &by) : ConstructedBy(by) {}; + /*}}}*/ +private: /*{{{*/ + Constructor ConstructedBy; + /*}}}*/ +}; /*}}}*/ +class VersionSet : public std::set { /*{{{*/ +/** \class APT::VersionSet + + Simple wrapper around a std::set to provide a similar interface to + a set of versions as to the complete set of all versions in the + pkgCache. */ +public: /*{{{*/ + /** \brief smell like a pkgCache::VerIterator */ + class const_iterator : public std::set::const_iterator {/*{{{*/ + public: + const_iterator(std::set::const_iterator x) : + std::set::const_iterator(x) {} + + operator pkgCache::VerIterator(void) { return **this; } + + inline pkgCache *Cache() const { return (**this).Cache(); }; + inline unsigned long Index() const {return (**this).Index();}; + // we have only valid iterators here + inline bool end() const { return false; }; + + inline pkgCache::Version const * operator->() const { + return &***this; + }; + + inline int CompareVer(const pkgCache::VerIterator &B) const { return (**this).CompareVer(B); }; + inline const char *VerStr() const { return (**this).VerStr(); }; + inline const char *Section() const { return (**this).Section(); }; + inline const char *Arch() const { return (**this).Arch(); }; + inline const char *Arch(bool const pseudo) const { return (**this).Arch(pseudo); }; + inline pkgCache::PkgIterator ParentPkg() const { return (**this).ParentPkg(); }; + inline pkgCache::DescIterator DescriptionList() const { return (**this).DescriptionList(); }; + inline pkgCache::DescIterator TranslatedDescription() const { return (**this).TranslatedDescription(); }; + inline pkgCache::DepIterator DependsList() const { return (**this).DependsList(); }; + inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); }; + inline pkgCache::VerFileIterator FileList() const { return (**this).FileList(); }; + inline bool Downloadable() const { return (**this).Downloadable(); }; + inline const char *PriorityType() const { return (**this).PriorityType(); }; + inline string RelStr() const { return (**this).RelStr(); }; + inline bool Automatic() const { return (**this).Automatic(); }; + inline bool Pseudo() const { return (**this).Pseudo(); }; + inline pkgCache::VerFileIterator NewestFile() const { return (**this).NewestFile(); }; + }; + /*}}}*/ + // 103. set::iterator is required to be modifiable, but this allows modification of keys + typedef APT::VersionSet::const_iterator iterator; + + using std::set::insert; + inline void insert(pkgCache::VerIterator const &V) { if (V.end() == false) std::set::insert(V); }; + inline void insert(VersionSet const &verset) { insert(verset.begin(), verset.end()); }; + + /** \brief specifies which version(s) will be returned if non is given */ + enum Version { + /** All versions */ + ALL, + /** Candidate and installed version */ + CANDANDINST, + /** Candidate version */ + CANDIDATE, + /** Installed version */ + INSTALLED, + /** Candidate or if non installed version */ + CANDINST, + /** Installed or if non candidate version */ + INSTCAND, + /** Newest version */ + NEWEST + }; + + /** \brief returns all versions specified on the commandline + + Get all versions from the commandline, uses given default version if + non specifically requested and executes regex's if needed on names. + \param Cache the packages and versions are in + \param cmdline Command line the versions should be extracted from + \param helper responsible for error and message handling */ + static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, + APT::VersionSet::Version const &fallback, CacheSetHelper &helper); + static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, + APT::VersionSet::Version const &fallback) { + CacheSetHelper helper; + return APT::VersionSet::FromCommandLine(Cache, cmdline, fallback, helper); + } + static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { + return APT::VersionSet::FromCommandLine(Cache, cmdline, CANDINST); + } + + static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, + APT::VersionSet::Version const &fallback, CacheSetHelper &helper, + bool const &onlyFromName = false); + static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, + APT::VersionSet::Version const &fallback) { + CacheSetHelper helper; + return APT::VersionSet::FromString(Cache, pkg, fallback, helper); + } + static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg) { + return APT::VersionSet::FromString(Cache, pkg, CANDINST); + } + + /** \brief returns all versions specified for the package + + \param Cache the package and versions are in + \param P the package in question + \param fallback the version(s) you want to get + \param helper the helper used for display and error handling */ + static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, + VersionSet::Version const &fallback, CacheSetHelper &helper); + static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, + APT::VersionSet::Version const &fallback) { + CacheSetHelper helper; + return APT::VersionSet::FromPackage(Cache, P, fallback, helper); + } + static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) { + return APT::VersionSet::FromPackage(Cache, P, CANDINST); + } + + struct Modifier { + enum Position { NONE, PREFIX, POSTFIX }; + unsigned short ID; + const char * const Alias; + Position Pos; + VersionSet::Version SelectVersion; + Modifier (unsigned short const &id, const char * const alias, Position const &pos, + VersionSet::Version const &select) : ID(id), Alias(alias), Pos(pos), + SelectVersion(select) {}; + }; + + static std::map GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, CacheSetHelper &helper); + static std::map GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback) { + CacheSetHelper helper; + return APT::VersionSet::GroupedFromCommandLine(Cache, cmdline, + mods, fallback, helper); + } + /*}}}*/ +protected: /*{{{*/ + + /** \brief returns the candidate version of the package + + \param Cache to be used to query for information + \param Pkg we want the candidate version from this package */ + static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper); + + /** \brief returns the installed version of the package + + \param Cache to be used to query for information + \param Pkg we want the installed version from this package */ + static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper); + /*}}}*/ +}; /*}}}*/ +} +#endif diff --git a/apt-pkg/makefile b/apt-pkg/makefile index e9e5651b0..4e5ec107f 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -35,7 +35,7 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \ srcrecords.cc cachefile.cc versionmatch.cc policy.cc \ pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \ indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \ - aptconfiguration.cc cachefilter.cc + aptconfiguration.cc cachefilter.cc cacheset.cc HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ orderlist.h sourcelist.h packagemanager.h tagfile.h \ init.h pkgcache.h version.h progress.h pkgrecords.h \ @@ -43,7 +43,7 @@ HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ clean.h srcrecords.h cachefile.h versionmatch.h policy.h \ pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \ vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \ - cachefilter.h + cachefilter.h cacheset.h # Source code for the debian specific components # In theory the deb headers do not need to be exported.. -- cgit v1.2.3 From 621e918e5e57675580ee5cb9bb4775d106814be4 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 21 Jul 2010 17:14:53 +0200 Subject: * apt-pkg/deb/dpkgpm.cc: - Write architecture information to history file. --- apt-pkg/deb/dpkgpm.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 67291063c..2945e9750 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -675,17 +675,17 @@ bool pkgDPkgPM::OpenLog() for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { if (Cache[I].NewInstall()) - install += I.Name() + string(" (") + Cache[I].CandVersion + string("), "); + install += I.FullName(false) + string(" (") + Cache[I].CandVersion + string("), "); else if (Cache[I].Upgrade()) - upgrade += I.Name() + string(" (") + Cache[I].CurVersion + string(", ") + Cache[I].CandVersion + string("), "); + upgrade += I.FullName(false) + string(" (") + Cache[I].CurVersion + string(", ") + Cache[I].CandVersion + string("), "); else if (Cache[I].Downgrade()) - downgrade += I.Name() + string(" (") + Cache[I].CurVersion + string(", ") + Cache[I].CandVersion + string("), "); + downgrade += I.FullName(false) + string(" (") + Cache[I].CurVersion + string(", ") + Cache[I].CandVersion + string("), "); else if (Cache[I].Delete()) { if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge) - purge += I.Name() + string(" (") + Cache[I].CurVersion + string("), "); + purge += I.FullName(false) + string(" (") + Cache[I].CurVersion + string("), "); else - remove += I.Name() + string(" (") + Cache[I].CurVersion + string("), "); + remove += I.FullName(false) + string(" (") + Cache[I].CurVersion + string("), "); } } if (_config->Exists("Commandline::AsString") == true) -- cgit v1.2.3 From 6bf8f0d198f00dcbb46dba97840681fa2227177a Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 21 Jul 2010 17:19:16 +0200 Subject: Add to history whether a change was automatic or not. --- apt-pkg/deb/dpkgpm.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 2945e9750..aa0b04bd5 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -675,7 +675,12 @@ bool pkgDPkgPM::OpenLog() for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { if (Cache[I].NewInstall()) - install += I.FullName(false) + string(" (") + Cache[I].CandVersion + string("), "); + { + install += I.FullName(false) + string(" (") + Cache[I].CandVersion; + if (Cache[I].Flags & pkgCache::Flag::Auto) + install+= ", automatic"; + install += string("), "); + } else if (Cache[I].Upgrade()) upgrade += I.FullName(false) + string(" (") + Cache[I].CurVersion + string(", ") + Cache[I].CandVersion + string("), "); else if (Cache[I].Downgrade()) -- cgit v1.2.3 From 144c096976b2ce05fe64e5761c0df5854f6c0c09 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 23 Jul 2010 16:13:15 +0200 Subject: * apt-pkg/contrib/fileutl.cc: - Add FileFd::OpenDescriptor() (needed for python-apt's #383617). --- apt-pkg/contrib/fileutl.cc | 18 ++++++++++++++++++ apt-pkg/contrib/fileutl.h | 4 ++++ 2 files changed, 22 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 49b2f3828..2a3b8a87d 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -700,6 +700,24 @@ bool FileFd::Open(string FileName,OpenMode Mode, unsigned long Perms) SetCloseExec(iFd,true); return true; } + +bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, bool AutoClose) +{ + Close(); + Flags = (AutoClose) ? FileFd::AutoClose : 0; + iFd = Fd; + if (Mode == ReadOnlyGzip) { + gz = gzdopen (iFd, "r"); + if (gz == NULL) { + if (AutoClose) + close (iFd); + return _error->Errno("gzdopen",_("Could not open file descriptor %d"), + Fd); + } + } + this->FileName = ""; + return true; +} /*}}}*/ // FileFd::~File - Closes the file /*{{{*/ // --------------------------------------------------------------------- diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 0f70ab722..62705478d 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -28,6 +28,9 @@ #include +/* Define this for python-apt */ +#define APT_HAS_GZIP 1 + using std::string; class FileFd @@ -60,6 +63,7 @@ class FileFd unsigned long Tell(); unsigned long Size(); bool Open(string FileName,OpenMode Mode,unsigned long Perms = 0666); + bool OpenDescriptor(int Fd, OpenMode Mode, bool AutoClose=false); bool Close(); bool Sync(); -- cgit v1.2.3 From 3db58cf41785f1e0b7046bbe7f3ef5e545c9a658 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 25 Jul 2010 08:24:03 +0200 Subject: * apt-pkg/pkgcache.cc: - prefer non-virtual packages in FindPreferredPkg --- apt-pkg/cacheiterators.h | 7 +++++-- apt-pkg/pkgcache.cc | 8 +++++--- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 1dcc34532..0be9368bd 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -115,8 +115,11 @@ class pkgCache::GrpIterator: public Iterator { /** \brief find the package with the "best" architecture The best architecture is either the "native" or the first - in the list of Architectures which is not an end-Pointer */ - PkgIterator FindPreferredPkg() const; + in the list of Architectures which is not an end-Pointer + + \param PreferNonVirtual tries to respond with a non-virtual package + and only if this fails returns the best virtual package */ + PkgIterator FindPreferredPkg(bool const &PreferNonVirtual = true) const; PkgIterator NextPkg(PkgIterator const &Pkg) const; // Constructors diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 8af8ef7de..9e1f8b633 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -349,19 +349,21 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) const { // GrpIterator::FindPreferredPkg - Locate the "best" package /*{{{*/ // --------------------------------------------------------------------- /* Returns an End-Pointer on error, pointer to the package otherwise */ -pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg() const { +pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg(bool const &PreferNonVirtual) const { pkgCache::PkgIterator Pkg = FindPkg("native"); - if (Pkg.end() == false) + if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0)) return Pkg; std::vector const archs = APT::Configuration::getArchitectures(); for (std::vector::const_iterator a = archs.begin(); a != archs.end(); ++a) { Pkg = FindPkg(*a); - if (Pkg.end() == false) + if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0)) return Pkg; } + if (PreferNonVirtual == true) + return FindPreferredPkg(false); return PkgIterator(*Owner, 0); } /*}}}*/ -- cgit v1.2.3 From f1a58ff8b6cb4086ae59a2c6b02a29baf97ac116 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 26 Jul 2010 10:53:32 +0200 Subject: - add a 'newest' pseudo target release as in pkg/newest * --- apt-pkg/cacheset.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index df7e99fd0..f17a9e0d5 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -323,7 +323,12 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, V = getInstalledVer(Cache, P, helper); else if (ver == "candidate") V = getCandidateVer(Cache, P, helper); - else { + else if (ver == "newest") { + if (P->VersionList != 0) + V = P.VersionList(); + else + V = helper.canNotFindNewestVer(Cache, P); + } else { pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release : pkgVersionMatch::Version)); V = Match.Find(P); -- cgit v1.2.3 From 15032eec2d508df3c63b532be22f488d240159a2 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 27 Jul 2010 13:57:42 +0200 Subject: * apt-pkg/cdrom.cc: - Use link() instead of rename() for creating the CD database backup; otherwise there would be a short time without any database. --- apt-pkg/cdrom.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc index 93deb49c4..e3e0027fc 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -383,7 +383,7 @@ bool pkgCdrom::WriteDatabase(Configuration &Cnf) Out.close(); - rename(DFile.c_str(),string(DFile + '~').c_str()); + link(DFile.c_str(),string(DFile + '~').c_str()); if (rename(NewFile.c_str(),DFile.c_str()) != 0) return _error->Errno("rename","Failed to rename %s.new to %s", DFile.c_str(),DFile.c_str()); -- cgit v1.2.3