diff options
Diffstat (limited to 'apt-pkg')
30 files changed, 420 insertions, 108 deletions
diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index bafba337e..c1f6581e2 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -266,7 +266,7 @@ pkgAcquire::MethodConfig *pkgAcquire::GetConfig(string Access) return 0; /* if a method uses DownloadLimit, we switch to SingleInstance mode */ - if(_config->FindI("Acquire::"+Access+"::DlLimit",0) > 0) + if(_config->FindI("Acquire::"+Access+"::Dl-Limit",0) > 0) Conf->SingleInstance = true; return Conf; diff --git a/apt-pkg/acquire.h b/apt-pkg/acquire.h index 1de6f5e44..eaadded55 100644 --- a/apt-pkg/acquire.h +++ b/apt-pkg/acquire.h @@ -539,7 +539,7 @@ class pkgAcquire::UriIterator public: - inline void operator ++() {operator ++();}; + inline void operator ++() {operator ++(0);}; void operator ++(int) { diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index b6f4705f3..1fd3d39a4 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -489,6 +489,36 @@ void pkgProblemResolver::MakeScores() unsigned long Size = Cache.Head().PackageCount; memset(Scores,0,sizeof(*Scores)*Size); + // 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 PrioEssentials = _config->FindI("pkgProblemResolver::Scores::Essentials",100); + signed short PrioInstalledAndNotObsolete = _config->FindI("pkgProblemResolver::Scores::NotObsolete",1); + signed short PrioDepends = _config->FindI("pkgProblemResolver::Scores::Depends",1); + signed short PrioRecommends = _config->FindI("pkgProblemResolver::Scores::Recommends",1); + signed short AddProtected = _config->FindI("pkgProblemResolver::Scores::AddProtected",10000); + signed short AddEssential = _config->FindI("pkgProblemResolver::Scores::AddEssential",5000); + + if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true) + clog << "Settings used to calculate pkgProblemResolver::Scores::" << endl + << " Important => " << PrioMap[1] << endl + << " Required => " << PrioMap[2] << endl + << " Standard => " << PrioMap[3] << endl + << " Optional => " << PrioMap[4] << endl + << " Extra => " << PrioMap[5] << endl + << " Essentials => " << PrioEssentials << endl + << " InstalledAndNotObsolete => " << PrioInstalledAndNotObsolete << endl + << " Depends => " << PrioDepends << endl + << " Recommends => " << PrioRecommends << endl + << " AddProtected => " << AddProtected << endl + << " AddEssential => " << AddEssential << endl; + // Generate the base scores for a package based on its properties for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { @@ -502,11 +532,9 @@ void pkgProblemResolver::MakeScores() to allow an obsolete essential packages to be removed by a conflicts on a powerfull normal package (ie libc6) */ if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) - Score += 100; + Score += PrioEssentials; // We transform the priority - // Important Required Standard Optional Extra - signed short PrioMap[] = {0,3,2,1,-1,-2}; if (Cache[I].InstVerIter(Cache)->Priority <= 5) Score += PrioMap[Cache[I].InstVerIter(Cache)->Priority]; @@ -515,7 +543,7 @@ void pkgProblemResolver::MakeScores() if those are not obsolete */ if (I->CurrentVer != 0 && Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable()) - Score += 1; + Score += PrioInstalledAndNotObsolete; } // Now that we have the base scores we go and propogate dependencies @@ -527,9 +555,10 @@ void pkgProblemResolver::MakeScores() for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false; D++) { if (D->Type == pkgCache::Dep::Depends || - D->Type == pkgCache::Dep::PreDepends || - D->Type == pkgCache::Dep::Recommends) - Scores[D.TargetPkg()->ID]++; + D->Type == pkgCache::Dep::PreDepends) + Scores[D.TargetPkg()->ID] += PrioDepends; + else if (D->Type == pkgCache::Dep::Recommends) + Scores[D.TargetPkg()->ID] += PrioRecommends; } } @@ -576,10 +605,10 @@ void pkgProblemResolver::MakeScores() for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { if ((Flags[I->ID] & Protected) != 0) - Scores[I->ID] += 10000; + Scores[I->ID] += AddProtected; if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) - Scores[I->ID] += 5000; - } + Scores[I->ID] += AddEssential; + } } /*}}}*/ // ProblemResolver::DoUpgrade - Attempt to upgrade this package /*{{{*/ @@ -755,19 +784,21 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) *PEnd++ = I; This = this; qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort); - -/* for (pkgCache::Package **K = PList; K != PEnd; K++) - if (Scores[(*K)->ID] != 0) - { - pkgCache::PkgIterator Pkg(Cache,*K); - clog << Scores[(*K)->ID] << ' ' << Pkg.Name() << - ' ' << (pkgCache::Version *)Pkg.CurrentVer() << ' ' << - Cache[Pkg].InstallVer << ' ' << Cache[Pkg].CandidateVer << endl; - } */ + + if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true) + { + clog << "Show Scores" << endl; + for (pkgCache::Package **K = PList; K != PEnd; K++) + if (Scores[(*K)->ID] != 0) + { + pkgCache::PkgIterator Pkg(Cache,*K); + clog << Scores[(*K)->ID] << ' ' << Pkg << std::endl; + } + } if (Debug == true) clog << "Starting 2" << endl; - + /* Now consider all broken packages. For each broken package we either remove the package or fix it's problem. We do this once, it should not be possible for a loop to form (that is a < b < c and fixing b by @@ -882,7 +913,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) } if (Debug == true) - clog << "Package " << I.Name() << " has broken dep on " << Start.TargetPkg().Name() << endl; + clog << "Package " << I.Name() << " has broken " << Start.DepType() << " on " << Start.TargetPkg().Name() << endl; /* Look across the version list. If there are no possible targets then we keep the package and bail. This is necessary @@ -961,15 +992,27 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) // Consider other options if (InOr == false) { - if (Debug == true) - clog << " Removing " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl; - Cache.MarkDelete(I); - if (Counter > 1) + if (Cache.AutoInstOk(I, Cache[I].CandidateVerIter(Cache),Start) == true) { - if (Scores[Pkg->ID] > Scores[I->ID]) - Scores[I->ID] = Scores[Pkg->ID]; - } - } + if (Debug == true) + clog << " Removing " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl; + Cache.MarkDelete(I); + if (Counter > 1) + { + if (Scores[Pkg->ID] > Scores[I->ID]) + Scores[I->ID] = Scores[Pkg->ID]; + } + } else { + /* The dependency of the TargetPkg would be satisfiable with I but it is + forbidden to install I automatical, so anything we can do is hold + back the TargetPkg. + */ + if (Debug == true) + clog << " Hold back " << Start.TargetPkg().Name() << + " rather than change denied AutoInstall " << I.Name() << endl; + Cache.MarkKeep(Start.TargetPkg()); + } + } } } @@ -1141,9 +1184,6 @@ bool pkgProblemResolver::ResolveByKeep() unsigned long Size = Cache.Head().PackageCount; - if (Debug == true) - clog << "Entering ResolveByKeep" << endl; - MakeScores(); /* We have to order the packages so that the broken fixing pass @@ -1156,7 +1196,21 @@ bool pkgProblemResolver::ResolveByKeep() *PEnd++ = I; This = this; qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort); - + + if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true) + { + clog << "Show Scores" << endl; + for (pkgCache::Package **K = PList; K != PEnd; K++) + if (Scores[(*K)->ID] != 0) + { + pkgCache::PkgIterator Pkg(Cache,*K); + clog << Scores[(*K)->ID] << ' ' << Pkg << std::endl; + } + } + + if (Debug == true) + clog << "Entering ResolveByKeep" << endl; + // Consider each broken package pkgCache::Package **LastStop = 0; for (pkgCache::Package **K = PList; K != PEnd; K++) @@ -1202,8 +1256,8 @@ bool pkgProblemResolver::ResolveByKeep() while (true) { if (Debug == true) - clog << "Package " << I.Name() << " has broken dep on " << Start.TargetPkg().Name() << endl; - + clog << "Package " << I.Name() << " has broken " << Start.DepType() << " on " << Start.TargetPkg().Name() << endl; + // Look at all the possible provides on this package SPtrArray<pkgCache::Version *> VList = Start.AllTargets(); for (pkgCache::Version **V = VList; *V != 0; V++) @@ -1219,7 +1273,7 @@ bool pkgProblemResolver::ResolveByKeep() if ((Flags[I->ID] & Protected) == 0) { if (Debug == true) - clog << " Keeping Package " << Pkg.Name() << " due to dep" << endl; + clog << " Keeping Package " << Pkg.Name() << " due to " << Start.DepType() << endl; Cache.MarkKeep(Pkg, false, false); } diff --git a/apt-pkg/cachefile.cc b/apt-pkg/cachefile.cc index 1a84aea54..5b5e26497 100644 --- a/apt-pkg/cachefile.cc +++ b/apt-pkg/cachefile.cc @@ -92,7 +92,7 @@ bool pkgCacheFile::Open(OpProgress &Progress,bool WithLock) Policy = new pkgPolicy(Cache); if (_error->PendingError() == true) return false; - if (ReadPinFile(*Policy) == false) + if (ReadPinFile(*Policy) == false || ReadPinDir(*Policy) == false) return false; // Create the dependency cache diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index bbbcb7753..af21681ed 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -80,7 +80,13 @@ class pkgCache::PkgIterator 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) @@ -111,7 +117,10 @@ class pkgCache::VerIterator 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;}; @@ -333,6 +342,7 @@ class pkgCache::PkgFileIterator 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;}; diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc index 7326b84ea..48a5f0bff 100644 --- a/apt-pkg/contrib/configuration.cc +++ b/apt-pkg/contrib/configuration.cc @@ -182,9 +182,9 @@ string Configuration::FindFile(const char *Name,const char *Default) const if (Itm == 0 || Itm->Value.empty() == true) { if (Default == 0) - return ""; + return rootDir; else - return Default; + return rootDir + Default; } string val = Itm->Value; @@ -521,6 +521,7 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool AsSectional, F.getline(Buffer,sizeof(Buffer) / 2); Input += Buffer; + delete[] Buffer; } while (F.fail() && !F.eof()); @@ -582,7 +583,7 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool AsSectional, if (InQuote == true) continue; - if (*I == '/' && I + 1 != End && I[1] == '/') + if ((*I == '/' && I + 1 != End && I[1] == '/') || *I == '#') { End = I; break; diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index fcc2f887c..70f2db06d 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -108,11 +108,16 @@ bool Hashes::AddFD(int Fd,unsigned long Size) { unsigned char Buf[64*64]; int Res = 0; - while (Size != 0) + int ToEOF = (Size == 0); + while (Size != 0 || ToEOF) { - Res = read(Fd,Buf,min(Size,(unsigned long)sizeof(Buf))); - if (Res < 0 || (unsigned)Res != min(Size,(unsigned long)sizeof(Buf))) - return false; + unsigned n = sizeof(Buf); + if (!ToEOF) n = min(Size,(unsigned long)n); + Res = read(Fd,Buf,n); + if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read + return false; + if (ToEOF && Res == 0) // EOF + break; Size -= Res; MD5.Add(Buf,Res); SHA1.Add(Buf,Res); diff --git a/apt-pkg/contrib/md5.cc b/apt-pkg/contrib/md5.cc index a095f8f0f..2bfd70f1b 100644 --- a/apt-pkg/contrib/md5.cc +++ b/apt-pkg/contrib/md5.cc @@ -294,11 +294,16 @@ bool MD5Summation::AddFD(int Fd,unsigned long Size) { unsigned char Buf[64*64]; int Res = 0; - while (Size != 0) + int ToEOF = (Size == 0); + while (Size != 0 || ToEOF) { - Res = read(Fd,Buf,min(Size,(unsigned long)sizeof(Buf))); - if (Res < 0 || (unsigned)Res != min(Size,(unsigned long)sizeof(Buf))) - return false; + unsigned n = sizeof(Buf); + if (!ToEOF) n = min(Size,(unsigned long)n); + Res = read(Fd,Buf,n); + if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read + return false; + if (ToEOF && Res == 0) // EOF + break; Size -= Res; Add(Buf,Res); } diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 0b1bc3c98..a991b8988 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -387,6 +387,17 @@ string SubstVar(string Str,const struct SubstVar *Vars) return Str; } /*}}}*/ +// OutputInDepth - return a string with separator multiplied with depth /*{{{*/ +// --------------------------------------------------------------------- +/* Returns a string with the supplied separator depth + 1 times in it */ +std::string OutputInDepth(const unsigned long Depth, const char* Separator) +{ + std::string output = ""; + for(unsigned long d=Depth+1; d > 0; d--) + output.append(Separator); + return output; +} + /*}}}*/ // URItoFileName - Convert the uri into a unique file name /*{{{*/ // --------------------------------------------------------------------- /* This converts a URI into a safe filename. It quotes all unsafe characters diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index 51416a24a..e1f9e3a1f 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -48,6 +48,7 @@ string DeQuoteString(const string &Str); string SizeToStr(double Bytes); string TimeToStr(unsigned long Sec); 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); diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 55ba1f8c4..517b771a5 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -109,6 +109,8 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) return false; if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Replaces) == false) return false; + if (ParseDepends(Ver,"Enhances",pkgCache::Dep::Enhances) == false) + return false; // Obsolete. if (ParseDepends(Ver,"Optional",pkgCache::Dep::Suggests) == false) @@ -637,6 +639,8 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI, FileI->Version = WriteUniqString(Start,Stop - Start); if (Section.Find("Origin",Start,Stop) == true) FileI->Origin = WriteUniqString(Start,Stop - Start); + if (Section.Find("Codename",Start,Stop) == true) + FileI->Codename = WriteUniqString(Start,Stop - Start); if (Section.Find("Label",Start,Stop) == true) FileI->Label = WriteUniqString(Start,Stop - Start); if (Section.Find("Architecture",Start,Stop) == true) diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index ee035191f..f3ab6960c 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -115,6 +115,13 @@ debReleaseIndex::debReleaseIndex(string URI,string Dist) this->Type = "deb"; } +debReleaseIndex::~debReleaseIndex() +{ + for (vector<const debSectionEntry *>::const_iterator I = SectionEntries.begin(); + I != SectionEntries.end(); I++) + delete *I; +} + vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const { vector <struct IndexTarget *>* IndexTargets = new vector <IndexTarget *>; diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h index c021a1b5a..8e6a1463b 100644 --- a/apt-pkg/deb/debmetaindex.h +++ b/apt-pkg/deb/debmetaindex.h @@ -22,6 +22,7 @@ class debReleaseIndex : public metaIndex { public: debReleaseIndex(string URI, string Dist); + ~debReleaseIndex(); virtual string ArchiveURI(string File) const {return URI + File;}; virtual bool GetIndexes(pkgAcquire *Owner, bool GetAll=false) const; diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc index ace4e00b5..2f87c767b 100644 --- a/apt-pkg/deb/debsrcrecords.cc +++ b/apt-pkg/deb/debsrcrecords.cc @@ -152,3 +152,11 @@ bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List) return true; } /*}}}*/ +// SrcRecordParser::~SrcRecordParser - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +debSrcRecordParser::~debSrcRecordParser() +{ + delete[] Buffer; +} + /*}}}*/ diff --git a/apt-pkg/deb/debsrcrecords.h b/apt-pkg/deb/debsrcrecords.h index 8b1237ccd..a3b5a8286 100644 --- a/apt-pkg/deb/debsrcrecords.h +++ b/apt-pkg/deb/debsrcrecords.h @@ -50,6 +50,7 @@ class debSrcRecordParser : public pkgSrcRecords::Parser debSrcRecordParser(string File,pkgIndexFile const *Index) : Parser(Index), Fd(File,FileFd::ReadOnly), Tags(&Fd,102400), Buffer(0), BufSize(0) {} + ~debSrcRecordParser(); }; #endif diff --git a/apt-pkg/deb/debsystem.cc b/apt-pkg/deb/debsystem.cc index 82464d998..59f826d96 100644 --- a/apt-pkg/deb/debsystem.cc +++ b/apt-pkg/deb/debsystem.cc @@ -17,8 +17,8 @@ #include <apt-pkg/configuration.h> #include <apt-pkg/error.h> #include <apt-pkg/fileutl.h> -#include <apti18n.h> - +#include <apti18n.h> + #include <sys/types.h> #include <unistd.h> #include <dirent.h> diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 2411bfe89..b1b8f970f 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -15,6 +15,7 @@ #include <apt-pkg/algorithms.h> #include <apt-pkg/fileutl.h> +#include <apt-pkg/strutl.h> #include <apt-pkg/configuration.h> #include <apt-pkg/pkgsystem.h> #include <apt-pkg/tagfile.h> @@ -47,7 +48,6 @@ ConfigValueInSubTree(const char* SubTree, const char *needle) return false; } - pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) : cache(cache), released(false) { @@ -83,6 +83,8 @@ pkgDepCache::ActionGroup::~ActionGroup() pkgDepCache::pkgDepCache(pkgCache *pCache,Policy *Plcy) : group_level(0), Cache(pCache), PkgState(0), DepState(0) { + DebugMarker = _config->FindB("Debug::pkgDepCache::Marker", false); + DebugAutoInstall = _config->FindB("Debug::pkgDepCache::AutoInstall", false); delLocalPolicy = 0; LocalPolicy = Plcy; if (LocalPolicy == 0) @@ -705,7 +707,8 @@ void pkgDepCache::Update(PkgIterator const &Pkg) // DepCache::MarkKeep - Put the package in the keep state /*{{{*/ // --------------------------------------------------------------------- /* */ -void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser) +void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser, + unsigned long Depth) { // Simplifies other routines. if (Pkg.end() == true) @@ -746,6 +749,9 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser) P.Flags &= ~Flag::Auto; #endif + if (DebugMarker == true) + std::clog << OutputInDepth(Depth) << "MarkKeep " << Pkg << std::endl; + RemoveSizes(Pkg); RemoveStates(Pkg); @@ -765,7 +771,8 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser) // DepCache::MarkDelete - Put the package in the delete state /*{{{*/ // --------------------------------------------------------------------- /* */ -void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge) +void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge, + unsigned long Depth) { // Simplifies other routines. if (Pkg.end() == true) @@ -787,6 +794,9 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge) if (Pkg->VersionList == 0) return; + if (DebugMarker == true) + std::clog << OutputInDepth(Depth) << "MarkDelete " << Pkg << std::endl; + RemoveSizes(Pkg); RemoveStates(Pkg); @@ -826,7 +836,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, P.CandidateVer == (Version *)Pkg.CurrentVer())) { if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0) - MarkKeep(Pkg, false, FromUser); + MarkKeep(Pkg, false, FromUser, Depth+1); return; } @@ -868,6 +878,9 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, if (AutoInst == false) return; + if (DebugMarker == true) + std::clog << OutputInDepth(Depth) << "MarkInstall " << Pkg << std::endl; + DepIterator Dep = P.InstVerIter(*this).DependsList(); for (; Dep.end() != true;) { @@ -937,12 +950,12 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, } } if(isNewImportantDep) - if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true) - std::clog << "new important dependency: " + if(DebugAutoInstall == true) + std::clog << OutputInDepth(Depth) << "new important dependency: " << Start.TargetPkg().Name() << std::endl; if(isPreviouslySatisfiedImportantDep) - if(_config->FindB("Debug::pkgDepCache::AutoInstall", false) == true) - std::clog << "previously satisfied important dependency on " + if(DebugAutoInstall == true) + std::clog << OutputInDepth(Depth) << "previously satisfied important dependency on " << Start.TargetPkg().Name() << std::endl; // skip important deps if the package is already installed @@ -991,17 +1004,19 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, } } - if (InstPkg.end() == false) + if (InstPkg.end() == false && + AutoInstOk(InstPkg, (*this)[InstPkg].CandidateVerIter(*this), Start)) { - if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true) - std::clog << "Installing " << InstPkg.Name() - << " as dep of " << Pkg.Name() + if(DebugAutoInstall == true) + std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.Name() + << " as " << Start.DepType() << " of " << Pkg.Name() << std::endl; // now check if we should consider it a automatic dependency or not if(Pkg.Section() && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", Pkg.Section())) { - if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true) - std::clog << "Setting NOT as auto-installed (direct dep of pkg in APT::Never-MarkAuto-Sections)" << std::endl; + if(DebugAutoInstall == true) + std::clog << OutputInDepth(Depth) << "Setting NOT as auto-installed (direct " + << Start.DepType() << " of pkg in APT::Never-MarkAuto-Sections)" << std::endl; MarkInstall(InstPkg,true,Depth + 1, true); } else @@ -1028,15 +1043,31 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, PkgIterator Pkg = Ver.ParentPkg(); if (Start->Type != Dep::DpkgBreaks) - MarkDelete(Pkg); + { + if(AutoInstOk(Pkg, VerIterator(*this), Start)) + MarkDelete(Pkg); + } else - if (PkgState[Pkg->ID].CandidateVer != *I) + if (PkgState[Pkg->ID].CandidateVer != *I && + AutoInstOk(Pkg, VerIterator(*this, PkgState[Pkg->ID].CandidateVer), Start)) MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps); } continue; } } } + +// DepCache::AutoInstOk - check if it is to install this package /*{{{*/ +// --------------------------------------------------------------------- +/* The default implementation just honors dpkg hold + But an application using this library can override this method + to control the MarkInstall behaviour */ +bool pkgDepCache::AutoInstOk(const PkgIterator &Pkg, + const VerIterator &v, + const DepIterator &d) +{ + return (Pkg->SelectedState != pkgCache::State::Hold); +} /*}}}*/ // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/ // --------------------------------------------------------------------- diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index f41ad17e9..10f9c1091 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -294,7 +294,10 @@ class pkgDepCache : protected pkgCache::Namespace unsigned long iBrokenCount; unsigned long iPolicyBrokenCount; unsigned long iBadCount; - + + bool DebugMarker; + bool DebugAutoInstall; + Policy *delLocalPolicy; // For memory clean up.. Policy *LocalPolicy; @@ -360,6 +363,20 @@ class pkgDepCache : protected pkgCache::Namespace */ virtual bool MarkFollowsSuggests(); + /** \return \b true if it's OK for MarkInstall to recursively + * install the given version of the given package. + * + * \param p the package that MarkInstall wants to install. + * \param v the version being installed, or an end iterator + * if p is being removed. + * \param d the dependency being fixed. + * + * The default implementation unconditionally returns \b true. + */ + virtual bool AutoInstOk(const PkgIterator &p, + const VerIterator &v, + const DepIterator &d); + /** \brief Update the Marked and Garbage fields of all packages. * * This routine is implicitly invoked after all state manipulators @@ -387,11 +404,13 @@ class pkgDepCache : protected pkgCache::Namespace */ // @{ void MarkKeep(PkgIterator const &Pkg, bool Soft = false, - bool FromUser = true); - void MarkDelete(PkgIterator const &Pkg,bool Purge = false); + bool FromUser = true, unsigned long Depth = 0); + void MarkDelete(PkgIterator const &Pkg, bool Purge = false, + unsigned long Depth = 0); void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true, unsigned long Depth = 0, bool FromUser = true, bool ForceImportantDeps = false); + void SetReInstall(PkgIterator const &Pkg,bool To); void SetCandidateVersion(VerIterator TargetVer); diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc index 338bef66c..4abfb726f 100644 --- a/apt-pkg/init.cc +++ b/apt-pkg/init.cc @@ -67,6 +67,7 @@ bool pkgInitConfig(Configuration &Cnf) Cnf.Set("Dir::Etc::main","apt.conf"); Cnf.Set("Dir::Etc::parts","apt.conf.d"); Cnf.Set("Dir::Etc::preferences","preferences"); + Cnf.Set("Dir::Etc::preferencesparts","preferences.d"); Cnf.Set("Dir::Bin::methods","/usr/lib/apt/methods"); // State diff --git a/apt-pkg/init.h b/apt-pkg/init.h index 6d8693be9..165299253 100644 --- a/apt-pkg/init.h +++ b/apt-pkg/init.h @@ -18,7 +18,7 @@ // See the makefile #define APT_PKG_MAJOR 4 -#define APT_PKG_MINOR 6 +#define APT_PKG_MINOR 8 #define APT_PKG_RELEASE 0 extern const char *pkgVersion; diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 087f17740..059f8532b 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -13,7 +13,7 @@ include ../buildlib/defaults.mak # methods/makefile - FIXME LIBRARY=apt-pkg LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER) -MAJOR=4.7 +MAJOR=4.8 MINOR=0 SLIBS=$(PTHREADLIB) $(INTLLIBS) -lutil APT_DOMAIN:=libapt-pkg$(MAJOR) diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h index 2b87d7da9..779b6ab14 100644 --- a/apt-pkg/metaindex.h +++ b/apt-pkg/metaindex.h @@ -39,7 +39,13 @@ class metaIndex virtual vector<pkgIndexFile *> *GetIndexFiles() = 0; virtual bool IsTrusted() const = 0; - virtual ~metaIndex() {}; + virtual ~metaIndex() { + if (Indexes == 0) + return; + for (vector<pkgIndexFile *>::iterator I = (*Indexes).begin(); I != (*Indexes).end(); ++I) + delete *I; + delete Indexes; + } }; #endif diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 6687864ee..2a9756c45 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -21,6 +21,7 @@ /*}}}*/ // Include Files /*{{{*/ #include <apt-pkg/pkgcache.h> +#include <apt-pkg/policy.h> #include <apt-pkg/indexfile.h> #include <apt-pkg/version.h> #include <apt-pkg/error.h> @@ -49,7 +50,7 @@ pkgCache::Header::Header() /* Whenever the structures change the major version should be bumped, whenever the generator changes the minor version should be bumped. */ - MajorVersion = 7; + MajorVersion = 8; MinorVersion = 0; Dirty = false; @@ -223,7 +224,7 @@ const char *pkgCache::DepType(unsigned char Type) { const char *Types[] = {"",_("Depends"),_("PreDepends"),_("Suggests"), _("Recommends"),_("Conflicts"),_("Replaces"), - _("Obsoletes"),_("Breaks")}; + _("Obsoletes"),_("Breaks"), _("Enhances")}; if (Type < sizeof(Types)/sizeof(*Types)) return Types[Type]; return ""; @@ -290,6 +291,56 @@ pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const return NeedsNothing; } /*}}}*/ +// PkgIterator::CandVersion - Returns the candidate version string /*{{{*/ +// --------------------------------------------------------------------- +/* Return string representing of the candidate version. */ +const char * +pkgCache::PkgIterator::CandVersion() const +{ + //TargetVer is empty, so don't use it. + VerIterator version = pkgPolicy::pkgPolicy(Owner).GetCandidateVer(*this); + if (version.IsGood()) + return version.VerStr(); + return 0; +}; + /*}}}*/ +// PkgIterator::CurVersion - Returns the current version string /*{{{*/ +// --------------------------------------------------------------------- +/* Return string representing of the current version. */ +const char * +pkgCache::PkgIterator::CurVersion() const +{ + VerIterator version = CurrentVer(); + if (version.IsGood()) + return CurrentVer().VerStr(); + return 0; +}; + /*}}}*/ +// ostream operator to handle string representation of a package /*{{{*/ +// --------------------------------------------------------------------- +/* Output name < cur.rent.version -> candid.ate.version | new.est.version > (section) + Note that the characters <|>() are all literal above. Versions will be ommited + if they provide no new information (e.g. there is no newer version than candidate) + If no version and/or section can be found "none" is used. */ +std::ostream& +operator<<(ostream& out, pkgCache::PkgIterator Pkg) +{ + if (Pkg.end() == true) + return out << "invalid package"; + + string current = string(Pkg.CurVersion() == 0 ? "none" : Pkg.CurVersion()); + string candidate = string(Pkg.CandVersion() == 0 ? "none" : Pkg.CandVersion()); + string newest = string(Pkg.VersionList().end() ? "none" : Pkg.VersionList().VerStr()); + + out << Pkg.Name() << " < " << current; + if (current != candidate) + out << " -> " << candidate; + if ( newest != "none" && candidate != newest) + out << " | " << newest; + out << " > ( " << string(Pkg.Section()==0?"none":Pkg.Section()) << " )"; + return out; +} + /*}}}*/ // DepIterator::IsCritical - Returns true if the dep is important /*{{{*/ // --------------------------------------------------------------------- /* Currently critical deps are defined as depends, predepends and @@ -607,6 +658,8 @@ string pkgCache::PkgFileIterator::RelStr() Res = Res + (Res.empty() == true?"o=":",o=") + Origin(); if (Archive() != 0) Res = Res + (Res.empty() == true?"a=":",a=") + Archive(); + if (Codename() != 0) + Res = Res + (Res.empty() == true?"n=":",n=") + Codename(); if (Label() != 0) Res = Res + (Res.empty() == true?"l=":",l=") + Label(); if (Component() != 0) diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 759e9a225..e58515fb1 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -70,7 +70,7 @@ class pkgCache struct Dep { enum DepType {Depends=1,PreDepends=2,Suggests=3,Recommends=4, - Conflicts=5,Replaces=6,Obsoletes=7,DpkgBreaks=8}; + Conflicts=5,Replaces=6,Obsoletes=7,DpkgBreaks=8,Enhances=9}; enum DepCompareOp {Or=0x10,NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3, Greater=0x4,Equals=0x5,NotEquals=0x6}; }; @@ -223,6 +223,7 @@ 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 diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index 8b083fd44..b9a951990 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -32,6 +32,9 @@ #include <apti18n.h> +#include <dirent.h> +#include <sys/stat.h> +#include <algorithm> #include <iostream> #include <sstream> /*}}}*/ @@ -239,7 +242,66 @@ signed short pkgPolicy::GetPriority(pkgCache::PkgIterator const &Pkg) return 0; } /*}}}*/ +// PreferenceSection class - Overriding the default TrimRecord method /*{{{*/ +// --------------------------------------------------------------------- +/* The preference file is a user generated file so the parser should + therefore be a bit more friendly by allowing comments and new lines + all over the place rather than forcing a special format */ +class PreferenceSection : public pkgTagSection +{ + void TrimRecord(bool BeforeRecord, const char* &End) + { + for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r' || Stop[0] == '#'); Stop++) + if (Stop[0] == '#') + Stop = (const char*) memchr(Stop,'\n',End-Stop); + } +}; + + +bool ReadPinDir(pkgPolicy &Plcy,string Dir) +{ + if (Dir.empty() == true) + Dir = _config->FindDir("Dir::Etc::PreferencesParts"); + + DIR *D = opendir(Dir.c_str()); + if (D == 0) + return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str()); + vector<string> 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()); + + // Read the files + for (vector<string>::const_iterator I = List.begin(); I != List.end(); I++) + if (ReadPinFile(Plcy, *I) == false) + return false; + return true; +} + + /*}}}*/ // ReadPinFile - Load the pin file into a Policy /*{{{*/ // --------------------------------------------------------------------- /* I'd like to see the preferences file store more than just pin information @@ -259,12 +321,12 @@ bool ReadPinFile(pkgPolicy &Plcy,string File) if (_error->PendingError() == true) return false; - pkgTagSection Tags; + PreferenceSection Tags; while (TF.Step(Tags) == true) { string Name = Tags.FindS("Package"); if (Name.empty() == true) - return _error->Error(_("Invalid record in the preferences file, no Package header")); + return _error->Error(_("Invalid record in the preferences file %s, no Package header"), File.c_str()); if (Name == "*") Name = string(); diff --git a/apt-pkg/policy.h b/apt-pkg/policy.h index d5f3b2f75..4894682fa 100644 --- a/apt-pkg/policy.h +++ b/apt-pkg/policy.h @@ -84,5 +84,6 @@ class pkgPolicy : public pkgDepCache::Policy }; bool ReadPinFile(pkgPolicy &Plcy,string File = ""); +bool ReadPinDir(pkgPolicy &Plcy,string Dir = ""); #endif diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 893cb8ee7..7c5d15a58 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -81,7 +81,7 @@ bool pkgTagFile::Resize() End = Start + EndSize; return true; } - + /*}}}*/ // TagFile::Step - Advance to the next section /*{{{*/ // --------------------------------------------------------------------- /* If the Section Scanner fails we refill the buffer and try again. @@ -212,10 +212,12 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength) if (Stop == 0) return false; - + TagCount = 0; while (TagCount+1 < sizeof(Indexes)/sizeof(Indexes[0]) && Stop < End) { + TrimRecord(true,End); + // Start a new index and add it to the hash if (isspace(Stop[0]) == 0) { @@ -227,14 +229,14 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength) if (Stop == 0) return false; - + for (; Stop+1 < End && Stop[1] == '\r'; Stop++); // Double newline marks the end of the record if (Stop+1 < End && Stop[1] == '\n') { Indexes[TagCount] = Stop - Section; - for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r'); Stop++); + TrimRecord(false,End); return true; } @@ -244,6 +246,16 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength) return false; } /*}}}*/ +// TagSection::TrimRecord - Trim off any garbage before/after a record /*{{{*/ +// --------------------------------------------------------------------- +/* There should be exactly 2 newline at the end of the record, no more. */ +void pkgTagSection::TrimRecord(bool BeforeRecord, const char*& End) +{ + if (BeforeRecord == true) + return; + for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r'); Stop++); +} + /*}}}*/ // TagSection::Trim - Trim off any trailing garbage /*{{{*/ // --------------------------------------------------------------------- /* There should be exactly 1 newline at the end of the buffer, no more. */ @@ -390,7 +402,6 @@ bool pkgTagSection::FindFlag(const char *Tag,unsigned long &Flags, return true; } /*}}}*/ - // TFRewrite - Rewrite a control record /*{{{*/ // --------------------------------------------------------------------- /* This writes the control record to stdout rewriting it as necessary. The diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h index 6536932dd..321329a23 100644 --- a/apt-pkg/tagfile.h +++ b/apt-pkg/tagfile.h @@ -27,7 +27,6 @@ class pkgTagSection { const char *Section; - const char *Stop; // We have a limit of 256 tags per section. unsigned int Indexes[256]; @@ -35,6 +34,9 @@ class pkgTagSection unsigned int TagCount; + protected: + const char *Stop; + public: inline bool operator ==(const pkgTagSection &rhs) {return Section == rhs.Section;}; @@ -49,6 +51,7 @@ class pkgTagSection bool Scan(const char *Start,unsigned long MaxLength); inline unsigned long size() const {return Stop - Section;}; void Trim(); + virtual void TrimRecord(bool BeforeRecord, const char* &End); inline unsigned int Count() const {return TagCount;}; inline void Get(const char *&Start,const char *&Stop,unsigned int I) const diff --git a/apt-pkg/versionmatch.cc b/apt-pkg/versionmatch.cc index 5c25c2f7b..b4d1d4696 100644 --- a/apt-pkg/versionmatch.cc +++ b/apt-pkg/versionmatch.cc @@ -63,8 +63,8 @@ pkgVersionMatch::pkgVersionMatch(string Data,MatchType Type) : Type(Type) if (isdigit(Data[0])) RelVerStr = Data; else - RelArchive = Data; - + RelRelease = Data; + if (RelVerStr.length() > 0 && RelVerStr.end()[-1] == '*') { RelVerPrefixMatch = true; @@ -87,19 +87,21 @@ pkgVersionMatch::pkgVersionMatch(string Data,MatchType Type) : Type(Type) { if (strlen(Fragments[J]) < 3) continue; - + if (stringcasecmp(Fragments[J],Fragments[J]+2,"v=") == 0) RelVerStr = Fragments[J]+2; else if (stringcasecmp(Fragments[J],Fragments[J]+2,"o=") == 0) RelOrigin = Fragments[J]+2; else if (stringcasecmp(Fragments[J],Fragments[J]+2,"a=") == 0) RelArchive = Fragments[J]+2; + else if (stringcasecmp(Fragments[J],Fragments[J]+2,"n=") == 0) + RelCodename = Fragments[J]+2; else if (stringcasecmp(Fragments[J],Fragments[J]+2,"l=") == 0) RelLabel = Fragments[J]+2; else if (stringcasecmp(Fragments[J],Fragments[J]+2,"c=") == 0) RelComponent = Fragments[J]+2; } - + if (RelVerStr.end()[-1] == '*') { RelVerPrefixMatch = true; @@ -169,15 +171,16 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File) { if (MatchAll == true) return true; - + /* cout << RelVerStr << ',' << RelOrigin << ',' << RelArchive << ',' << RelLabel << endl; cout << File.Version() << ',' << File.Origin() << ',' << File.Archive() << ',' << File.Label() << endl;*/ - + if (RelVerStr.empty() == true && RelOrigin.empty() == true && RelArchive.empty() == true && RelLabel.empty() == true && + RelRelease.empty() == true && RelCodename.empty() == true && RelComponent.empty() == true) return false; - + if (RelVerStr.empty() == false) if (File->Version == 0 || MatchVer(File.Version(),RelVerStr,RelVerPrefixMatch) == false) @@ -187,11 +190,19 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File) stringcasecmp(RelOrigin,File.Origin()) != 0) return false; if (RelArchive.empty() == false) - { - if (File->Archive == 0 || + if (File->Archive == 0 || stringcasecmp(RelArchive,File.Archive()) != 0) - return false; - } + return false; + if (RelCodename.empty() == false) + if (File->Codename == 0 || + stringcasecmp(RelCodename,File.Codename()) != 0) + return false; + if (RelRelease.empty() == false) + if ((File->Archive == 0 || + stringcasecmp(RelRelease,File.Archive()) != 0) && + (File->Codename == 0 || + stringcasecmp(RelRelease,File.Codename()) != 0)) + return false; if (RelLabel.empty() == false) if (File->Label == 0 || stringcasecmp(RelLabel,File.Label()) != 0) @@ -202,7 +213,7 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File) return false; return true; } - + if (Type == Origin) { if (OrSite.empty() == false) { @@ -213,7 +224,7 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File) return false; return (OrSite == File.Site()); /* both strings match */ } - + return false; } /*}}}*/ diff --git a/apt-pkg/versionmatch.h b/apt-pkg/versionmatch.h index fe264aa46..a8f3c84ac 100644 --- a/apt-pkg/versionmatch.h +++ b/apt-pkg/versionmatch.h @@ -3,29 +3,32 @@ // $Id: versionmatch.h,v 1.4 2001/05/29 03:07:12 jgg Exp $ /* ###################################################################### - Version Matching - + Version Matching + This module takes a matching string and a type and locates the version record that satisfies the constraint described by the matching string. Version: 1.2* Release: o=Debian,v=2.1*,c=main Release: v=2.1* + Release: a=testing + Release: n=squeeze Release: * Origin: ftp.debian.org - + Release may be a complex type that can specify matches for any of: Version (v= with prefix) Origin (o=) - Archive (a=) + Archive (a=) eg, unstable, testing, stable + Codename (n=) e.g. etch, lenny, squeeze, sid Label (l=) Component (c=) 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. - + form - if it starts with a number it is Version otherwise it is an + Archive or a Codename. + Release may be a '*' to match all releases. - + ##################################################################### */ /*}}}*/ #ifndef PKGLIB_VERSIONMATCH_H @@ -47,6 +50,8 @@ class pkgVersionMatch string RelVerStr; bool RelVerPrefixMatch; string RelOrigin; + string RelRelease; + string RelCodename; string RelArchive; string RelLabel; string RelComponent; |