summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/acquire.cc2
-rw-r--r--apt-pkg/acquire.h2
-rw-r--r--apt-pkg/algorithms.cc126
-rw-r--r--apt-pkg/cachefile.cc2
-rw-r--r--apt-pkg/cacheiterators.h14
-rw-r--r--apt-pkg/contrib/configuration.cc7
-rw-r--r--apt-pkg/contrib/hashes.cc13
-rw-r--r--apt-pkg/contrib/md5.cc13
-rw-r--r--apt-pkg/contrib/strutl.cc11
-rw-r--r--apt-pkg/contrib/strutl.h1
-rw-r--r--apt-pkg/deb/deblistparser.cc4
-rw-r--r--apt-pkg/deb/debmetaindex.cc7
-rw-r--r--apt-pkg/deb/debmetaindex.h1
-rw-r--r--apt-pkg/deb/debsrcrecords.cc8
-rw-r--r--apt-pkg/deb/debsrcrecords.h1
-rw-r--r--apt-pkg/deb/debsystem.cc4
-rw-r--r--apt-pkg/depcache.cc63
-rw-r--r--apt-pkg/depcache.h25
-rw-r--r--apt-pkg/init.cc1
-rw-r--r--apt-pkg/init.h2
-rw-r--r--apt-pkg/makefile2
-rw-r--r--apt-pkg/metaindex.h8
-rw-r--r--apt-pkg/pkgcache.cc57
-rw-r--r--apt-pkg/pkgcache.h3
-rw-r--r--apt-pkg/policy.cc66
-rw-r--r--apt-pkg/policy.h1
-rw-r--r--apt-pkg/tagfile.cc21
-rw-r--r--apt-pkg/tagfile.h5
-rw-r--r--apt-pkg/versionmatch.cc37
-rw-r--r--apt-pkg/versionmatch.h21
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;