summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/algorithms.cc270
-rw-r--r--apt-pkg/algorithms.h20
-rw-r--r--apt-pkg/cacheiterators.h5
-rw-r--r--apt-pkg/contrib/configuration.cc13
-rw-r--r--apt-pkg/contrib/fileutl.cc6
-rw-r--r--apt-pkg/contrib/fileutl.h4
-rw-r--r--apt-pkg/contrib/progress.cc32
-rw-r--r--apt-pkg/contrib/progress.h8
-rw-r--r--apt-pkg/depcache.h4
-rw-r--r--apt-pkg/pkgcache.cc14
-rw-r--r--apt-pkg/pkgcachegen.cc8
-rw-r--r--apt-pkg/tagfile.cc13
12 files changed, 325 insertions, 72 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index ce0c41efd..2e4ca5c2c 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -1,10 +1,16 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: algorithms.cc,v 1.3 1998/07/12 23:58:20 jgg Exp $
+// $Id: algorithms.cc,v 1.4 1998/10/02 04:39:42 jgg Exp $
/* ######################################################################
Algorithms - A set of misc algorithms
+ The pkgProblemResolver class has become insanely complex and
+ very sophisticated, it handles every test case I have thrown at it
+ to my satisfaction. Understanding exactly why all the steps the class
+ does are required is difficult and changing though not very risky
+ may result in other cases not working.
+
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
@@ -13,6 +19,7 @@
#endif
#include <apt-pkg/algorithms.h>
#include <apt-pkg/error.h>
+#include <apt-pkg/configuration.h>
#include <iostream.h>
/*}}}*/
@@ -37,7 +44,7 @@ bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/)
PkgIterator Pkg = Sim.FindPkg(iPkg.Name());
Flags[Pkg->ID] = 1;
- cout << "Inst " << Pkg.Name();
+ clog << "Inst " << Pkg.Name();
Sim.MarkInstall(Pkg,false);
// Look for broken conflicts+predepends.
@@ -51,7 +58,7 @@ bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/)
{
if ((Sim[D] & pkgDepCache::DepInstall) == 0)
{
- cout << " [" << I.Name() << " on " << D.TargetPkg().Name() << ']';
+ clog << " [" << I.Name() << " on " << D.TargetPkg().Name() << ']';
if (D->Type == pkgCache::Dep::Conflicts)
_error->Error("Fatal, conflicts violated %s",I.Name());
}
@@ -61,7 +68,7 @@ bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/)
if (Sim.BrokenCount() != 0)
ShortBreaks();
else
- cout << endl;
+ clog << endl;
return true;
}
/*}}}*/
@@ -79,7 +86,7 @@ bool pkgSimulate::Configure(PkgIterator iPkg)
// Sim.MarkInstall(Pkg,false);
if (Sim[Pkg].InstBroken() == true)
{
- cout << "Conf " << Pkg.Name() << " broken" << endl;
+ clog << "Conf " << Pkg.Name() << " broken" << endl;
Sim.Update();
@@ -91,21 +98,21 @@ bool pkgSimulate::Configure(PkgIterator iPkg)
continue;
if (D->Type == pkgCache::Dep::Conflicts)
- cout << " Conflicts:" << D.TargetPkg().Name();
+ clog << " Conflicts:" << D.TargetPkg().Name();
else
- cout << " Depends:" << D.TargetPkg().Name();
+ clog << " Depends:" << D.TargetPkg().Name();
}
- cout << endl;
+ clog << endl;
_error->Error("Conf Broken %s",Pkg.Name());
}
else
- cout << "Conf " << Pkg.Name();
+ clog << "Conf " << Pkg.Name();
if (Sim.BrokenCount() != 0)
ShortBreaks();
else
- cout << endl;
+ clog << endl;
return true;
}
@@ -120,12 +127,12 @@ bool pkgSimulate::Remove(PkgIterator iPkg)
Flags[Pkg->ID] = 3;
Sim.MarkDelete(Pkg);
- cout << "Remv " << Pkg.Name();
+ clog << "Remv " << Pkg.Name();
if (Sim.BrokenCount() != 0)
ShortBreaks();
else
- cout << endl;
+ clog << endl;
return true;
}
@@ -135,18 +142,18 @@ bool pkgSimulate::Remove(PkgIterator iPkg)
/* */
void pkgSimulate::ShortBreaks()
{
- cout << " [";
+ clog << " [";
for (PkgIterator I = Sim.PkgBegin(); I.end() == false; I++)
{
if (Sim[I].InstBroken() == true)
{
if (Flags[I->ID] == 0)
- cout << I.Name() << ' ';
+ clog << I.Name() << ' ';
/* else
- cout << I.Name() << "! ";*/
+ clog << I.Name() << "! ";*/
}
}
- cout << ']' << endl;
+ clog << ']' << endl;
}
/*}}}*/
// ApplyStatus - Adjust for non-ok packages /*{{{*/
@@ -182,8 +189,8 @@ bool pkgApplyStatus(pkgDepCache &Cache)
/*}}}*/
// FixBroken - Fix broken packages /*{{{*/
// ---------------------------------------------------------------------
-/* This autoinstalls every broken package and then runs ScoredFix on the
- result. */
+/* This autoinstalls every broken package and then runs the problem resolver
+ on the result. */
bool pkgFixBroken(pkgDepCache &Cache)
{
// Auto upgrade all broken packages
@@ -215,7 +222,7 @@ bool pkgFixBroken(pkgDepCache &Cache)
pre-existing package. This creates the initial set of conditions which
most likely contain problems because too many things were installed.
- ScoredFix is used to resolve the problems.
+ The problem resolver is used to resolve the problems.
*/
bool pkgDistUpgrade(pkgDepCache &Cache)
{
@@ -252,6 +259,34 @@ bool pkgDistUpgrade(pkgDepCache &Cache)
return Fix.Resolve();
}
/*}}}*/
+// AllUpgrade - Upgrade as many packages as possible /*{{{*/
+// ---------------------------------------------------------------------
+/* Right now the system must be consistent before this can be called.
+ It also will not change packages marked for install, it only tries
+ to install packages not marked for install */
+bool pkgAllUpgrade(pkgDepCache &Cache)
+{
+ pkgProblemResolver Fix(Cache);
+
+ if (Cache.BrokenCount() != 0)
+ return false;
+
+ // Upgrade all installed packages
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
+ {
+ if (Cache[I].Install() == true)
+ Fix.Protect(I);
+
+ if (I->SelectedState == pkgCache::State::Hold)
+ continue;
+
+ if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
+ Cache.MarkInstall(I,false);
+ }
+
+ return Fix.ResolveByKeep();
+}
+ /*}}}*/
// ProblemResolver::pkgProblemResolver - Constructor /*{{{*/
// ---------------------------------------------------------------------
@@ -265,7 +300,7 @@ pkgProblemResolver::pkgProblemResolver(pkgDepCache &Cache) : Cache(Cache)
memset(Flags,0,sizeof(*Flags)*Size);
// Set debug to true to see its decision logic
- Debug = false;
+ Debug = _config->FindB("Debug::pkgProblemResolver",false);
}
/*}}}*/
// ProblemResolver::ScoreSort - Sort the list by score /*{{{*/
@@ -383,11 +418,16 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
{
if ((Flags[Pkg->ID] & Upgradable) == 0 || Cache[Pkg].Upgradable() == false)
return false;
+
Flags[Pkg->ID] &= ~Upgradable;
bool WasKept = Cache[Pkg].Keep();
Cache.MarkInstall(Pkg,false);
+ // This must be a virtual package or something like that.
+ if (Cache[Pkg].InstVerIter(Cache).end() == true)
+ return false;
+
// Isolate the problem dependency
bool Fail = false;
for (pkgCache::DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false;)
@@ -415,19 +455,28 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
// Hm, the group is broken.. I have no idea how to handle this
if (Start != End)
{
- cout << "Note, a broken or group was found in " << Pkg.Name() << "." << endl;
+ clog << "Note, a broken or group was found in " << Pkg.Name() << "." << endl;
Fail = true;
break;
}
-
+
+ // Do not change protected packages
+ PkgIterator P = Start.SmartTargetPkg();
+ if ((Flags[P->ID] & Protected) == Protected)
+ {
+ if (Debug == true)
+ clog << " Reinet Failed because of protected " << P.Name() << endl;
+ Fail = true;
+ break;
+ }
+
// Upgrade the package if the candidate version will fix the problem.
if ((Cache[Start] & pkgDepCache::DepCVer) == pkgDepCache::DepCVer)
{
- PkgIterator P = Start.SmartTargetPkg();
if (DoUpgrade(P) == false)
{
if (Debug == true)
- cout << " Reinst Failed because of " << P.Name() << endl;
+ clog << " Reinst Failed because of " << P.Name() << endl;
Fail = true;
break;
}
@@ -440,7 +489,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
continue;
if (Debug == true)
- cout << " Reinst Failed early because of " << Start.TargetPkg().Name() << endl;
+ clog << " Reinst Failed early because of " << Start.TargetPkg().Name() << endl;
Fail = true;
break;
}
@@ -457,7 +506,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
}
if (Debug == true)
- cout << " Re-Instated " << Pkg.Name() << endl;
+ clog << " Re-Instated " << Pkg.Name() << endl;
return true;
}
/*}}}*/
@@ -477,7 +526,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
upgrade packages to advoid problems. */
bool pkgProblemResolver::Resolve(bool BrokenFix)
{
- unsigned long Size = Cache.HeaderP->PackageCount;
+ unsigned long Size = Cache.HeaderP->PackageCount;
// Record which packages are marked for install
bool Again = false;
@@ -505,7 +554,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
while (Again == true);
if (Debug == true)
- cout << "Starting" << endl;
+ clog << "Starting" << endl;
MakeScores();
@@ -524,13 +573,13 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
if (Scores[(*K)->ID] != 0)
{
pkgCache::PkgIterator Pkg(Cache,*K);
- cout << Scores[(*K)->ID] << ' ' << Pkg.Name() <<
+ clog << Scores[(*K)->ID] << ' ' << Pkg.Name() <<
' ' << (pkgCache::Version *)Pkg.CurrentVer() << ' ' <<
Cache[Pkg].InstallVer << ' ' << Cache[Pkg].CandidateVer << endl;
} */
if (Debug == true)
- cout << "Starting 2" << endl;
+ 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
@@ -549,13 +598,15 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
if (Cache[I].CandidateVer != Cache[I].InstallVer &&
I->CurrentVer != 0 && Cache[I].InstallVer != 0 &&
(Flags[I->ID] & PreInstalled) != 0 &&
- (Flags[I->ID] & Protected) == 0)
+ (Flags[I->ID] & Protected) == 0 &&
+ (Flags[I->ID] & ReInstateTried) == 0)
{
if (Debug == true)
- cout << " Try to Re-Instate " << I.Name() << endl;
+ clog << " Try to Re-Instate " << I.Name() << endl;
int OldBreaks = Cache.BrokenCount();
pkgCache::Version *OldVer = Cache[I].InstallVer;
-
+ Flags[I->ID] &= ReInstateTried;
+
Cache.MarkInstall(I,false);
if (Cache[I].InstBroken() == true ||
OldBreaks < Cache.BrokenCount())
@@ -567,7 +618,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
}
else
if (Debug == true)
- cout << "Re-Instated " << I.Name() << endl;
+ clog << "Re-Instated " << I.Name() << " (" << OldBreaks << " vs " << Cache.BrokenCount() << ')' << endl;
}
if (Cache[I].InstallVer == 0 || Cache[I].InstBroken() == false)
@@ -601,13 +652,13 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
// Hm, the group is broken.. I have no idea how to handle this
if (Start != End)
{
- cout << "Note, a broken or group was found in " << I.Name() << "." << endl;
+ clog << "Note, a broken or group was found in " << I.Name() << "." << endl;
Cache.MarkDelete(I);
break;
}
if (Debug == true)
- cout << "Package " << I.Name() << " has broken dep on " << End.TargetPkg().Name() << endl;
+ clog << "Package " << I.Name() << " has broken dep on " << End.TargetPkg().Name() << endl;
/* Conflicts is simple, decide if we should remove this package
or the conflicted one */
@@ -619,7 +670,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
pkgCache::PkgIterator Pkg = Ver.ParentPkg();
if (Debug == true)
- cout << " Considering " << Pkg.Name() << ' ' << (int)Scores[Pkg->ID] <<
+ clog << " Considering " << Pkg.Name() << ' ' << (int)Scores[Pkg->ID] <<
" as a solution to " << I.Name() << ' ' << (int)Scores[I->ID] << endl;
if (Scores[I->ID] <= Scores[Pkg->ID] ||
((Cache[End] & pkgDepCache::DepGNow) == 0 &&
@@ -627,24 +678,24 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
{
if ((Flags[I->ID] & Protected) != 0)
continue;
-
+
// See if a keep will do
Cache.MarkKeep(I);
if (Cache[I].InstBroken() == false)
{
if (Debug == true)
- cout << " Holding Back " << I.Name() << " rather than change " << End.TargetPkg().Name() << endl;
+ clog << " Holding Back " << I.Name() << " rather than change " << End.TargetPkg().Name() << endl;
}
else
{
if (BrokenFix == false || DoUpgrade(I) == false)
{
if (Debug == true)
- cout << " Removing " << I.Name() << " rather than change " << End.TargetPkg().Name() << endl;
+ clog << " Removing " << I.Name() << " rather than change " << End.TargetPkg().Name() << endl;
Cache.MarkDelete(I);
if (Counter > 1)
Scores[I->ID] = Scores[Pkg->ID];
- }
+ }
}
Change = true;
@@ -660,6 +711,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
LEnd->Pkg = Pkg;
LEnd->Dep = End;
LEnd++;
+
if (End->Type != pkgCache::Dep::Conflicts)
break;
}
@@ -672,12 +724,12 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
if (Cache[I].InstBroken() == false)
{
if (Debug == true)
- cout << " Holding Back " << I.Name() << " because I can't find " << End.TargetPkg().Name() << endl;
+ clog << " Holding Back " << I.Name() << " because I can't find " << End.TargetPkg().Name() << endl;
}
else
{
if (Debug == true)
- cout << " Removing " << I.Name() << " because I can't find " << End.TargetPkg().Name() << endl;
+ clog << " Removing " << I.Name() << " because I can't find " << End.TargetPkg().Name() << endl;
Cache.MarkDelete(I);
}
@@ -700,14 +752,14 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
if (J->Dep->Type == pkgCache::Dep::Conflicts)
{
if (Debug == true)
- cout << " Fixing " << I.Name() << " via remove of " << J->Pkg.Name() << endl;
+ clog << " Fixing " << I.Name() << " via remove of " << J->Pkg.Name() << endl;
Cache.MarkDelete(J->Pkg);
}
}
else
{
if (Debug == true)
- cout << " Fixing " << I.Name() << " via keep of " << J->Pkg.Name() << endl;
+ clog << " Fixing " << I.Name() << " via keep of " << J->Pkg.Name() << endl;
Cache.MarkKeep(J->Pkg);
}
@@ -718,13 +770,137 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
}
if (Debug == true)
- cout << "Done" << endl;
+ clog << "Done" << endl;
delete [] Scores;
delete [] PList;
if (Cache.BrokenCount() != 0)
- return _error->Error("Internal error, ScoredFix generated breaks.");
+ return _error->Error("Internal error, pkgProblemResolver::Resolve generated breaks.");
+
+ return true;
+}
+ /*}}}*/
+// ProblemResolver::ResolveByKeep - Resolve problems using keep /*{{{*/
+// ---------------------------------------------------------------------
+/* This is the work horse of the soft upgrade routine. It is very gental
+ in that it does not install or remove any packages. It is assumed that the
+ system was non-broken previously. */
+bool pkgProblemResolver::ResolveByKeep()
+{
+ unsigned long Size = Cache.HeaderP->PackageCount;
+
+ if (Debug == true)
+ clog << "Entering ResolveByKeep" << endl;
+
+ MakeScores();
+
+ /* We have to order the packages so that the broken fixing pass
+ operates from highest score to lowest. This prevents problems when
+ high score packages cause the removal of lower score packages that
+ would cause the removal of even lower score packages. */
+ pkgCache::Package **PList = new pkgCache::Package *[Size];
+ pkgCache::Package **PEnd = PList;
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
+ *PEnd++ = I;
+ This = this;
+ qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort);
+
+ // Consider each broken package
+ pkgCache::Package **LastStop = 0;
+ for (pkgCache::Package **K = PList; K != PEnd; K++)
+ {
+ pkgCache::PkgIterator I(Cache,*K);
+
+ if (Cache[I].InstallVer == 0 || Cache[I].InstBroken() == false)
+ continue;
+
+ /* Keep the package. If this works then great, otherwise we have
+ to be significantly more agressive and manipulate its dependencies */
+ if ((Flags[I->ID] & Protected) == 0)
+ {
+ if (Debug == true)
+ clog << "Keeping package " << I.Name() << endl;
+ Cache.MarkKeep(I);
+ if (Cache[I].InstBroken() == false)
+ {
+ K = PList;
+ continue;
+ }
+ }
+
+ // Isolate the problem dependencies
+ for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false;)
+ {
+ // Compute a single dependency element (glob or)
+ pkgCache::DepIterator Start = D;
+ pkgCache::DepIterator End = D;
+ unsigned char State = 0;
+ for (bool LastOR = true; D.end() == false && LastOR == true; D++)
+ {
+ State |= Cache[D];
+ LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
+ if (LastOR == true)
+ End = D;
+ }
+
+ // We only worry about critical deps.
+ if (End.IsCritical() != true)
+ continue;
+
+ // Dep is ok
+ if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
+ continue;
+
+ // Hm, the group is broken.. I have no idea how to handle this
+ if (Start != End)
+ {
+ clog << "Note, a broken or group was found in " << I.Name() << "." << endl;
+ if ((Flags[I->ID] & Protected) == 0)
+ Cache.MarkKeep(I);
+ break;
+ }
+
+ if (Debug == true)
+ clog << "Package " << I.Name() << " has broken dep on " << End.TargetPkg().Name() << endl;
+
+ // Look at all the possible provides on this package
+ pkgCache::Version **VList = End.AllTargets();
+ bool Done = false;
+ for (pkgCache::Version **V = VList; *V != 0; V++)
+ {
+ pkgCache::VerIterator Ver(Cache,*V);
+ pkgCache::PkgIterator Pkg = Ver.ParentPkg();
+
+ // It is not keepable
+ if (Cache[Pkg].InstallVer == 0 ||
+ Pkg->CurrentVer == 0)
+ continue;
+
+ if ((Flags[I->ID] & Protected) == 0)
+ {
+ if (Debug == true)
+ clog << " Keeping Package " << Pkg.Name() << " due to dep" << endl;
+ Cache.MarkKeep(Pkg);
+ }
+
+ if (Cache[I].InstBroken() == false)
+ break;
+ }
+
+ if (Cache[I].InstBroken() == false)
+ break;
+ }
+
+ if (Cache[I].InstBroken() == true)
+ continue;
+
+ // Restart again.
+ if (K == LastStop)
+ return _error->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.",I.Name());
+ LastStop = K;
+ K = PList;
+ }
return true;
}
diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h
index d17a42447..0379357c2 100644
--- a/apt-pkg/algorithms.h
+++ b/apt-pkg/algorithms.h
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: algorithms.h,v 1.3 1998/07/19 21:24:11 jgg Exp $
+// $Id: algorithms.h,v 1.4 1998/10/02 04:39:43 jgg Exp $
/* ######################################################################
Algorithms - A set of misc algorithms
@@ -16,7 +16,15 @@
field in the status file. It is important to get proper crash recovery.
pkgFixBroken corrects a broken system so that it is in a sane state.
+
+ pkgAllUpgrade attempts to upgade as many packages as possible but
+ without installing new packages.
+ The problem resolver class contains a number of complex algorithms
+ to try to best-guess an upgrade state. It solves the problem of
+ maximizing the number of install state packages while having no broken
+ packages.
+
##################################################################### */
/*}}}*/
// Header section: pkglib
@@ -60,7 +68,7 @@ class pkgProblemResolver
typedef pkgCache::Package Package;
enum Flags {Protected = (1 << 0), PreInstalled = (1 << 1),
- Upgradable = (1 << 2)};
+ Upgradable = (1 << 2), ReInstateTried = (1 << 3)};
signed short *Scores;
unsigned char *Flags;
bool Debug;
@@ -81,13 +89,19 @@ class pkgProblemResolver
public:
inline void Protect(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] |= Protected;};
+
+ // Try to intelligently resolve problems by installing and removing packages
bool Resolve(bool BrokenFix = false);
-
+
+ // Try to resolve problems only by using keep
+ bool ResolveByKeep();
+
pkgProblemResolver(pkgDepCache &Cache);
};
bool pkgDistUpgrade(pkgDepCache &Cache);
bool pkgApplyStatus(pkgDepCache &Cache);
bool pkgFixBroken(pkgDepCache &Cache);
+bool pkgAllUpgrade(pkgDepCache &Cache);
#endif
diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
index 390c923b9..7cdc197a2 100644
--- a/apt-pkg/cacheiterators.h
+++ b/apt-pkg/cacheiterators.h
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: cacheiterators.h,v 1.6 1998/07/12 23:58:23 jgg Exp $
+// $Id: cacheiterators.h,v 1.7 1998/10/02 04:39:44 jgg Exp $
/* ######################################################################
Cache Iterators - Iterators for navigating the cache structure
@@ -173,7 +173,8 @@ class pkgCache::DepIterator
bool IsCritical();
Version **AllTargets();
bool SmartTargetPkg(PkgIterator &Result);
-
+ const char *CompType();
+
inline DepIterator(pkgCache &Owner,Dependency *Trg,Version * = 0) :
Dep(Trg), Type(DepVer), Owner(&Owner)
{
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index b12fed6be..433b92244 100644
--- a/apt-pkg/contrib/configuration.cc
+++ b/apt-pkg/contrib/configuration.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: configuration.cc,v 1.5 1998/09/26 05:34:26 jgg Exp $
+// $Id: configuration.cc,v 1.6 1998/10/02 04:39:49 jgg Exp $
/* ######################################################################
Configuration Class
@@ -105,6 +105,7 @@ string Configuration::Find(const char *Name,const char *Default)
// Configuration::FindDir - Find a directory /*{{{*/
// ---------------------------------------------------------------------
/* Directories are stored as the base dir in the Parent node and the
+ sub directory in sub nodes
*/
string Configuration::FindDir(const char *Name,const char *Default = 0)
{
@@ -117,8 +118,16 @@ string Configuration::FindDir(const char *Name,const char *Default = 0)
return Default;
}
+ // Absolute path
if (Itm->Value[0] == '/' || Itm->Parent == 0)
return Itm->Value;
+
+ // ./ is also considered absolute as is anything with ~ in it
+ if (Itm->Value[0] != 0 &&
+ ((Itm->Value[0] == '.' && Itm->Value[1] == '/') ||
+ (Itm->Value[0] == '~' && Itm->Value[1] == '/')))
+ return Itm->Value;
+
if (Itm->Parent->Value.end()[-1] == '/')
return Itm->Parent->Value + Itm->Value;
else
@@ -167,7 +176,7 @@ bool Configuration::FindB(const char *Name,bool Default)
strcasecmp(Itm->Value.c_str(),"true") == 0 ||
strcasecmp(Itm->Value.c_str(),"with") == 0 ||
strcasecmp(Itm->Value.c_str(),"enable") == 0)
- return false;
+ return true;
return Default;
}
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index d18f7853e..60b9f8b75 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: fileutl.cc,v 1.7 1998/08/26 04:52:26 jgg Exp $
+// $Id: fileutl.cc,v 1.8 1998/10/02 04:39:50 jgg Exp $
/* ######################################################################
File Utilities
@@ -140,6 +140,10 @@ FileFd::FileFd(string FileName,OpenMode Mode, unsigned long Perms)
case WriteExists:
iFd = open(FileName.c_str(),O_RDWR);
break;
+
+ case WriteAny:
+ iFd = open(FileName.c_str(),O_RDWR | O_CREAT,Perms);
+ break;
// Dont use this in public directories
case LockEmpty:
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index a99d5fee6..c468c95d3 100644
--- a/apt-pkg/contrib/fileutl.h
+++ b/apt-pkg/contrib/fileutl.h
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: fileutl.h,v 1.5 1998/08/26 04:52:27 jgg Exp $
+// $Id: fileutl.h,v 1.6 1998/10/02 04:39:52 jgg Exp $
/* ######################################################################
File Utilities
@@ -38,7 +38,7 @@ class FileFd
string FileName;
public:
- enum OpenMode {ReadOnly,WriteEmpty,WriteExists,LockEmpty};
+ enum OpenMode {ReadOnly,WriteEmpty,WriteExists,WriteAny,LockEmpty};
bool Read(void *To,unsigned long Size);
bool Write(void *From,unsigned long Size);
diff --git a/apt-pkg/contrib/progress.cc b/apt-pkg/contrib/progress.cc
index 9a29c4b66..0f2218f3c 100644
--- a/apt-pkg/contrib/progress.cc
+++ b/apt-pkg/contrib/progress.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: progress.cc,v 1.7 1998/09/07 05:28:38 jgg Exp $
+// $Id: progress.cc,v 1.8 1998/10/02 04:39:53 jgg Exp $
/* ######################################################################
OpProgress - Operation Progress
@@ -13,6 +13,7 @@
#endif
#include <apt-pkg/progress.h>
#include <apt-pkg/error.h>
+#include <apt-pkg/configuration.h>
#include <stdio.h>
/*}}}*/
@@ -108,6 +109,18 @@ bool OpProgress::CheckChange(float Interval)
return true;
}
/*}}}*/
+// OpTextProgress::OpTextProgress - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+OpTextProgress::OpTextProgress(Configuration &Config) :
+ NoUpdate(false), NoDisplay(false), LastLen(0)
+{
+ if (Config.FindI("quiet",0) >= 1)
+ NoUpdate = true;
+ if (Config.FindI("quiet",0) >= 2)
+ NoDisplay = true;
+};
+ /*}}}*/
// OpTextProgress::Done - Clean up the display /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -123,7 +136,13 @@ void OpTextProgress::Done()
Write(S);
cout << endl;
OldOp = string();
- }
+ }
+
+ if (NoUpdate == true && NoDisplay == false && OldOp.empty() == false)
+ {
+ OldOp = string();
+ cout << endl;
+ }
}
/*}}}*/
// OpTextProgress::Update - Simple text spinner /*{{{*/
@@ -139,7 +158,14 @@ void OpTextProgress::Update()
{
if (MajorChange == false)
return;
- cout << Op << endl;
+ if (NoDisplay == false)
+ {
+ if (OldOp.empty() == false)
+ cout << endl;
+ OldOp = "a";
+ cout << Op << "..." << flush;
+ }
+
return;
}
diff --git a/apt-pkg/contrib/progress.h b/apt-pkg/contrib/progress.h
index 554cb16ea..094c4b016 100644
--- a/apt-pkg/contrib/progress.h
+++ b/apt-pkg/contrib/progress.h
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: progress.h,v 1.3 1998/08/26 04:52:29 jgg Exp $
+// $Id: progress.h,v 1.4 1998/10/02 04:39:54 jgg Exp $
/* ######################################################################
OpProgress - Operation Progress
@@ -29,6 +29,7 @@
#include <string>
#include <sys/time.h>
+class Configuration;
class OpProgress
{
unsigned long Current;
@@ -72,6 +73,7 @@ class OpTextProgress : public OpProgress
string OldOp;
bool NoUpdate;
+ bool NoDisplay;
unsigned long LastLen;
virtual void Update();
void Write(const char *S);
@@ -80,7 +82,9 @@ class OpTextProgress : public OpProgress
virtual void Done();
- OpTextProgress(bool NoUpdate = false) : NoUpdate(NoUpdate), LastLen(0) {};
+ OpTextProgress(bool NoUpdate = false) : NoUpdate(NoUpdate),
+ NoDisplay(false), LastLen(0) {};
+ OpTextProgress(Configuration &Config);
virtual ~OpTextProgress() {Done();};
};
diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h
index 8d90a529f..bd64ee5a2 100644
--- a/apt-pkg/depcache.h
+++ b/apt-pkg/depcache.h
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: depcache.h,v 1.4 1998/09/07 05:28:35 jgg Exp $
+// $Id: depcache.h,v 1.5 1998/10/02 04:39:45 jgg Exp $
/* ######################################################################
DepCache - Dependency Extension data for the cache
@@ -94,7 +94,7 @@ class pkgDepCache : public pkgCache
inline bool Delete() const {return Mode == ModeDelete;};
inline bool Keep() const {return Mode == ModeKeep;};
inline bool Upgrade() const {return Status > 0 && Mode == ModeInstall;};
- inline bool Upgradable() const {return Status == 1;};
+ inline bool Upgradable() const {return Status >= 1;};
inline bool Downgrade() const {return Status < 0;};
inline bool Held() const {return Status != 0 && Keep();};
inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;};
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index 02b28fa47..2e62f2ea4 100644
--- a/apt-pkg/pkgcache.cc
+++ b/apt-pkg/pkgcache.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: pkgcache.cc,v 1.8 1998/07/19 04:22:00 jgg Exp $
+// $Id: pkgcache.cc,v 1.9 1998/10/02 04:39:46 jgg Exp $
/* ######################################################################
Package Cache - Accessor code for the cache
@@ -336,6 +336,18 @@ pkgCache::Version **pkgCache::DepIterator::AllTargets()
return Res;
}
/*}}}*/
+// DepIterator::CompType - Return a string describing the compare type /*{{{*/
+// ---------------------------------------------------------------------
+/* This returns a string representation of the dependency compare
+ type */
+const char *pkgCache::DepIterator::CompType()
+{
+ const char *Ops[] = {"","<=",">=","<",">","=","!="};
+ if ((Dep->CompareOp & 0xF) < sizeof(Ops))
+ return Ops[Dep->CompareOp & 0xF];
+ return "";
+}
+ /*}}}*/
// VerIterator::CompareVer - Fast version compare for same pkgs /*{{{*/
// ---------------------------------------------------------------------
/* This just looks over the version list to see if B is listed before A. In
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index 6b3bfa3c5..567628ef5 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: pkgcachegen.cc,v 1.17 1998/09/26 05:34:23 jgg Exp $
+// $Id: pkgcachegen.cc,v 1.18 1998/10/02 04:39:47 jgg Exp $
/* ######################################################################
Package Cache Generator - Generator for the cache structure.
@@ -413,7 +413,7 @@ bool pkgSrcCacheCheck(pkgSourceList &List)
}
MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
- if (_error->PendingError() == true)
+ if (_error->PendingError() == true || Map.Size() == 0)
{
_error->Discard();
return false;
@@ -474,7 +474,7 @@ bool pkgPkgCacheCheck(string CacheFile)
}
MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
- if (_error->PendingError() == true)
+ if (_error->PendingError() == true || Map.Size() == 0)
{
_error->Discard();
return false;
@@ -565,7 +565,7 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress)
string CacheFile = _config->FindDir("Dir::Cache::pkgcache");
bool SrcOk = pkgSrcCacheCheck(List);
- bool PkgOk = pkgPkgCacheCheck(CacheFile);
+ bool PkgOk = SrcOk && pkgPkgCacheCheck(CacheFile);
// Rebuild the source and package caches
if (SrcOk == false)
diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc
index f6855f17a..50d669977 100644
--- a/apt-pkg/tagfile.cc
+++ b/apt-pkg/tagfile.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: tagfile.cc,v 1.10 1998/07/19 04:42:10 jgg Exp $
+// $Id: tagfile.cc,v 1.11 1998/10/02 04:39:48 jgg Exp $
/* ######################################################################
Fast scanner for RFC-822 type header information
@@ -45,7 +45,10 @@ bool pkgTagFile::Step(pkgTagSection &Tag)
return false;
if (Tag.Scan(Start,End - Start) == false)
+ {
+ cout << string(Start,End-Start) << endl;
return _error->Error("Unable to parse package file");
+ }
}
Start += Tag.size();
iOffset += Tag.size();
@@ -125,13 +128,16 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
{
if (Stop[-1] != '\n')
continue;
+
+ // Skip line feeds
+ for (; Stop[0] == '\r' && Stop < End; Stop++);
+
if (Stop[0] == '\n')
{
// Extra one at the end to simplify find
Indexes[TagCount] = Stop - Section;
- for (; Stop[0] == '\n' && Stop < End; Stop++);
+ for (; (Stop[0] == '\n' || Stop[0] == '\r') && Stop < End; Stop++);
return true;
- break;
}
if (isspace(Stop[0]) == 0)
@@ -167,6 +173,7 @@ bool pkgTagSection::Find(const char *Tag,const char *&Start,
End = Section + Indexes[I+1];
for (; (isspace(*Start) != 0 || *Start == ':') && Start < End; Start++);
for (; isspace(End[-1]) != 0 && End > Start; End--);
+
return true;
}
Start = End = 0;