From afb1e2e3bb580077c6c917e6ea98baad8f3c39b3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 10 May 2005 08:27:59 +0000 Subject: * ported/cleaned up the "Automatic dependency handling" patch from Michael Hofmann --- apt-pkg/deb/dpkgpm.h | 2 +- apt-pkg/depcache.cc | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- apt-pkg/depcache.h | 6 ++++++ apt-pkg/pkgcache.h | 1 + apt-pkg/pkgcachegen.cc | 2 ++ 5 files changed, 58 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index b59b9dc93..8bfdff5eb 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -40,7 +40,7 @@ class pkgDPkgPM : public pkgPackageManager bool RunScripts(const char *Cnf); bool RunScriptsWithPkgs(const char *Cnf); bool SendV2Pkgs(FILE *F); - + // The Actuall installation implementation virtual bool Install(PkgIterator Pkg,string File); virtual bool Configure(PkgIterator Pkg); diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index c6bf3185a..5da411e4d 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -16,6 +16,10 @@ #include #include #include + +#include +#include +#include #include /*}}}*/ @@ -72,7 +76,10 @@ bool pkgDepCache::Init(OpProgress *Prog) // Find the proper cache slot StateCache &State = PkgState[I->ID]; State.iFlags = 0; - + State.DirtyState = pkgCache::State::RemoveUnknown; + //State.AutomaticRemove = I->AutomaticRemove; + State.AutomaticRemove = pkgCache::State::RemoveUnknown; + // Figure out the install version State.CandidateVer = GetCandidateVer(I); State.InstallVer = I.CurrentVer(); @@ -447,6 +454,35 @@ void pkgDepCache::Update(OpProgress *Prog) AddStates(I); } + // read the state file ------------------------------ + FileFd state_file; + string state = _config->FindDir("Dir::State") + "pkgstates"; + if(FileExists(state)) { + state_file.Open(state, FileFd::ReadOnly); + int file_size = state_file.Size(); + Prog->OverallProgress(0, file_size, 1, _("Reading extended state information")); + + pkgTagFile tagfile(&state_file); + pkgTagSection section; + int amt=0; + while(tagfile.Step(section)) { + string pkgname = section.FindS("Package"); + pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname); + // Silently ignore unknown packages and packages with no actual + // version. + if(!pkg.end() && !pkg.VersionList().end()) { + short reason = section.FindI("Remove-Reason", pkgCache::State::RemoveManual); + PkgState[pkg->ID].AutomaticRemove = reason; + //std::cout << "Set: " << pkgname << " to " << reason << std::endl; + amt+=section.size(); + Prog->OverallProgress(amt, file_size, 1, _("Reading extended state information")); + } + Prog->OverallProgress(file_size, file_size, 1, _("Reading extended state information")); + } + } + //-------------------------------------- + + if (Prog != 0) Prog->Progress(Done); } @@ -582,7 +618,8 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge) else P.Mode = ModeDelete; P.InstallVer = 0; - P.Flags &= Flag::Auto; + // This was not inverted before, but I think it should be + P.Flags &= ~Flag::Auto; AddStates(Pkg); Update(Pkg); @@ -754,6 +791,15 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To) AddSizes(Pkg); } /*}}}*/ +// DepCache::SetDirty - Switch the package between dirty states /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgDepCache::SetDirty(PkgIterator const &Pkg, pkgCache::State::PkgRemoveState To) +{ + StateCache &P = PkgState[Pkg->ID]; + P.DirtyState = To; +} + /*}}}*/ // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/ // --------------------------------------------------------------------- /* */ diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 6d51920e9..f974bfacf 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -79,6 +79,10 @@ class pkgDepCache : protected pkgCache::Namespace unsigned short Flags; unsigned short iFlags; // Internal flags + // Traversal status and state for automatic removal + unsigned char DirtyState; + unsigned char AutomaticRemove; + // Various tree indicators signed char Status; // -1,0,1,2 unsigned char Mode; // ModeList @@ -99,6 +103,7 @@ class pkgDepCache : protected pkgCache::Namespace inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;}; inline bool InstBroken() const {return (DepState & DepInstMin) != DepInstMin;}; inline bool Install() const {return Mode == ModeInstall;}; + inline unsigned char Dirty() const {return DirtyState;}; inline VerIterator InstVerIter(pkgCache &Cache) {return VerIterator(Cache,InstallVer);}; inline VerIterator CandidateVerIter(pkgCache &Cache) @@ -189,6 +194,7 @@ class pkgDepCache : protected pkgCache::Namespace unsigned long Depth = 0); void SetReInstall(PkgIterator const &Pkg,bool To); void SetCandidateVersion(VerIterator TargetVer); + void SetDirty(PkgIterator const &Pkg, pkgCache::State::PkgRemoveState To); // This is for debuging void Update(OpProgress *Prog = 0); diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index b07951dfb..083f20ac2 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -75,6 +75,7 @@ class pkgCache enum PkgInstState {Ok=0,ReInstReq=1,HoldInst=2,HoldReInstReq=3}; enum PkgCurrentState {NotInstalled=0,UnPacked=1,HalfConfigured=2, HalfInstalled=4,ConfigFiles=5,Installed=6}; + enum PkgRemoveState {RemoveUnknown=0, RemoveManual=1,RemoveSuggested=2,RemoveRecommended=3,RemoveRequired=4}; }; struct Flag diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 075af3eec..e90c1e50d 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -26,6 +26,8 @@ #include #include +#include + #include #include -- cgit v1.2.3 From a83d884db24933000f19dbff706529db057d50c1 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 23 Jun 2005 16:40:54 +0000 Subject: * cleanups --- apt-pkg/depcache.cc | 91 ++++++++++++++++++++++++++++++++++++----------------- apt-pkg/depcache.h | 4 +++ 2 files changed, 66 insertions(+), 29 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 5da411e4d..552a45a16 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -20,7 +20,7 @@ #include #include #include - +#include #include /*}}}*/ @@ -103,6 +103,66 @@ bool pkgDepCache::Init(OpProgress *Prog) } /*}}}*/ +bool pkgDepCache::readStateFile(OpProgress *Prog) +{ + FileFd state_file; + string state = _config->FindDir("Dir::State") + "pkgstates"; + if(FileExists(state)) { + state_file.Open(state, FileFd::ReadOnly); + int file_size = state_file.Size(); + Prog->OverallProgress(0, file_size, 1, + _("Reading extended state information")); + + pkgTagFile tagfile(&state_file); + pkgTagSection section; + int amt=0; + while(tagfile.Step(section)) { + string pkgname = section.FindS("Package"); + pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname); + // Silently ignore unknown packages and packages with no actual + // version. + if(!pkg.end() && !pkg.VersionList().end()) { + short reason = section.FindI("Remove-Reason", + pkgCache::State::RemoveManual); + PkgState[pkg->ID].AutomaticRemove = reason; + //std::cout << "Set: " << pkgname << " to " << reason << std::endl; + amt+=section.size(); + Prog->OverallProgress(amt, file_size, 1, + _("Reading extended state information")); + } + Prog->OverallProgress(file_size, file_size, 1, + _("Reading extended state information")); + } + } + + return true; +} + +bool pkgDepCache::writeStateFile(OpProgress *prog) +{ + // write the auto-mark list ---------------------------------- + + FileFd StateFile; + string state = _config->FindDir("Dir::State") + "pkgstates"; + + if(!StateFile.Open(state, FileFd::WriteEmpty)) + return _error->Error(_("Failed to write StateFile %s"), + state.c_str()); + + std::ostringstream ostr; + for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end();pkg++) { + if(PkgState[pkg->ID].AutomaticRemove != pkgCache::State::RemoveUnknown) { + ostr.str(string("")); + ostr << "Package: " << pkg.Name() + << "\nRemove-Reason: " + << (int)(PkgState[pkg->ID].AutomaticRemove) << "\n\n"; + StateFile.Write(ostr.str().c_str(), ostr.str().size()); + //std::cout << "Writing auto-mark: " << ostr.str() << endl; + } + } + return true; +} + // DepCache::CheckDep - Checks a single dependency /*{{{*/ // --------------------------------------------------------------------- /* This first checks the dependency against the main target package and @@ -454,34 +514,7 @@ void pkgDepCache::Update(OpProgress *Prog) AddStates(I); } - // read the state file ------------------------------ - FileFd state_file; - string state = _config->FindDir("Dir::State") + "pkgstates"; - if(FileExists(state)) { - state_file.Open(state, FileFd::ReadOnly); - int file_size = state_file.Size(); - Prog->OverallProgress(0, file_size, 1, _("Reading extended state information")); - - pkgTagFile tagfile(&state_file); - pkgTagSection section; - int amt=0; - while(tagfile.Step(section)) { - string pkgname = section.FindS("Package"); - pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname); - // Silently ignore unknown packages and packages with no actual - // version. - if(!pkg.end() && !pkg.VersionList().end()) { - short reason = section.FindI("Remove-Reason", pkgCache::State::RemoveManual); - PkgState[pkg->ID].AutomaticRemove = reason; - //std::cout << "Set: " << pkgname << " to " << reason << std::endl; - amt+=section.size(); - Prog->OverallProgress(amt, file_size, 1, _("Reading extended state information")); - } - Prog->OverallProgress(file_size, file_size, 1, _("Reading extended state information")); - } - } - //-------------------------------------- - + readStateFile(Prog); if (Prog != 0) Prog->Progress(Done); diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index f974bfacf..e02ed72f0 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -198,6 +198,10 @@ class pkgDepCache : protected pkgCache::Namespace // This is for debuging void Update(OpProgress *Prog = 0); + + // read persistent states + bool readStateFile(OpProgress *prog); + bool writeStateFile(OpProgress *prog); // Size queries inline double UsrSize() {return iUsrSize;}; -- cgit v1.2.3 From 80fa0d8a1a77f4dab696dcf11d1908ecda761fab Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 24 Jun 2005 09:36:22 +0000 Subject: * moved most of the real work into depcache::writeStateFile --- apt-pkg/algorithms.cc | 11 +++++++++++ apt-pkg/depcache.cc | 11 +++++++++++ 2 files changed, 22 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 479927d65..2799c2fdd 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -1061,6 +1061,17 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) return _error->Error(_("Unable to correct problems, you have held broken packages.")); } + // set the auto-flags (mvo: I'm not sure if we _really_ need this, but + // I didn't managed + pkgCache::PkgIterator I = Cache.PkgBegin(); + for (;I.end() != true; I++) { + if (Cache[I].NewInstall() && !(Flags[I->ID] & PreInstalled)) { + std::cout << "Resolve installed new pkg: " << I.Name() << " (now marking it as auto)" << std::endl; + Cache[I].Flags |= pkgCache::Flag::Auto; + } + } + + return true; } /*}}}*/ diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 552a45a16..c490d89bc 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -151,6 +151,17 @@ bool pkgDepCache::writeStateFile(OpProgress *prog) std::ostringstream ostr; for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end();pkg++) { + + // clear out no longer installed pkg + if(PkgState[pkg->ID].Delete() || pkg.CurrentVer() == NULL) + PkgState[pkg->ID].AutomaticRemove = pkgCache::State::RemoveUnknown; + + // check if we have new information + if(PkgState[pkg->ID].Flags & pkgCache::Flag::Auto) { + std::cout << "pkg: " << pkg.Name() << " is auto-dep" << std::endl; + PkgState[pkg->ID].AutomaticRemove = pkgCache::State::RemoveRequired; + } + if(PkgState[pkg->ID].AutomaticRemove != pkgCache::State::RemoveUnknown) { ostr.str(string("")); ostr << "Package: " << pkg.Name() -- cgit v1.2.3 From d36ab88eb8a5e490e4a817b87f20cb3f890e0da1 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 24 Jun 2005 09:58:47 +0000 Subject: * write the state file after a successfull commit from the pkgManager --- apt-pkg/packagemanager.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index a08ccd602..a97c94fdf 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -637,6 +637,11 @@ pkgPackageManager::OrderResult pkgPackageManager::DoInstall() if (Res != Failed) if (Go() == false) return Failed; + + // if all was fine update the state file + if(Res == Completed) + Cache.writeStateFile(NULL); + return Res; } /*}}}*/ -- cgit v1.2.3 From db1e7193fa7d5b86656c05112b9d6ad6e75845b8 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 24 Jun 2005 12:34:34 +0000 Subject: * moved the importend algorithm to algorithm.h as "pkgMarkUsed()" --- apt-pkg/algorithms.cc | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ apt-pkg/algorithms.h | 4 ++ 2 files changed, 108 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 2799c2fdd..98bd8dd8b 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -1243,3 +1243,107 @@ void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List) qsort(List,Count,sizeof(*List),PrioComp); } /*}}}*/ + + +// pkgMarkPkgUsed - Mark used packages as dirty /*{{{*/ +// --------------------------------------------------------------------- +/* Mark all reachable packages as dirty. */ +void pkgMarkPkgUsed(pkgDepCache &Cache, pkgCache::PkgIterator Pkg, + pkgCache::State::PkgRemoveState DirtLevel) +{ + // If it is not installed, and we are in manual mode, ignore it + if ((Pkg->CurrentVer == 0 && Cache[Pkg].Install() == false || Cache[Pkg].Delete() == true) && + DirtLevel == pkgCache::State::RemoveManual) + { +// fprintf(stdout,"This one is not installed/virtual %s %d %d\n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel); + return; + } + + // If it is not installed, and it is not virtual, ignore it + if ((Pkg->CurrentVer == 0 && Cache[Pkg].Install() == false || Cache[Pkg].Delete() == true) && + Pkg->VersionList != 0) + { +// fprintf(stdout,"This one is not installed %s %d %d\n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel); + return; + } + + // If it is similar or more dirty than we are ;-), because we've been here already, don't mark it + // This is necessary because virtual packages just relay the current level, + // so it may be possible e.g. that this was already seen with ::RemoveSuggested, but + // we are ::RemoveRequired + if (Cache[Pkg].Dirty() >= DirtLevel) + { + //fprintf(stdout,"Seen already %s %d %d\n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel); + return; + } + + // If it is less important than the current DirtLevel, don't mark it + if (Cache[Pkg].AutomaticRemove != pkgCache::State::RemoveManual && + Cache[Pkg].AutomaticRemove > DirtLevel) + { +// fprintf(stdout,"We don't need %s %d %d %d\n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel, Cache[Pkg].Dirty()); + return; + } + + // Mark it as used + Cache.SetDirty(Pkg, DirtLevel); + + //fprintf(stdout,"We keep %s %d %d\n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel); + + // We are a virtual package + if (Pkg->VersionList == 0) + { +// fprintf(stdout,"We are virtual %s %d %d\n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel); + for (pkgCache::PrvIterator Prv = Pkg.ProvidesList(); ! Prv.end(); ++Prv) + pkgMarkPkgUsed (Cache, Prv.OwnerPkg(), DirtLevel); + return; + } + + // Depending on the type of dependency, follow it + for (pkgCache::DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); ! D.end(); ++D) + { +// fprintf(stdout,"We depend on %s %s\n", D.TargetPkg().Name(), D.DepType()); + + switch(D->Type) + { + case pkgCache::Dep::Depends: + case pkgCache::Dep::PreDepends: + pkgMarkPkgUsed (Cache, D.TargetPkg(), pkgCache::State::RemoveRequired); + break; + case pkgCache::Dep::Recommends: + pkgMarkPkgUsed (Cache, D.TargetPkg(), pkgCache::State::RemoveRecommended); + break; + case pkgCache::Dep::Suggests: + pkgMarkPkgUsed (Cache, D.TargetPkg(), pkgCache::State::RemoveSuggested); + break; + case pkgCache::Dep::Conflicts: + case pkgCache::Dep::Replaces: + case pkgCache::Dep::Obsoletes: + // We don't handle these here + break; + } + } +// fprintf(stdout,"We keep %s %d %d \n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel); +} + /*}}}*/ + +bool pkgMarkUsed(pkgDepCache &Cache) +{ + // debug only + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); ! Pkg.end(); ++Pkg) + if(!Cache[Pkg].Dirty() && Cache[Pkg].AutomaticRemove > 0) + std::cout << "has auto-remove information: " << Pkg.Name() + << " " << (int)Cache[Pkg].AutomaticRemove + << std::endl; + + // init with defaults + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); ! Pkg.end(); ++Pkg) + Cache.SetDirty(Pkg, pkgCache::State::RemoveUnknown); + + // go recursive over the cache + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); ! Pkg.end(); ++Pkg) + pkgMarkPkgUsed (Cache, Pkg, pkgCache::State::RemoveManual); + + + return true; +} diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 174a7f58d..210127ab9 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -132,5 +132,9 @@ bool pkgAllUpgrade(pkgDepCache &Cache); bool pkgMinimizeUpgrade(pkgDepCache &Cache); void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List); + +// mark all reachable packages, everything that is not reach can +// be removed +bool pkgMarkUsed(pkgDepCache &Cache); #endif -- cgit v1.2.3 From 3c9b111f0fea7b57f1eebc2c03a057240e9b7a06 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 24 Jun 2005 19:46:26 +0000 Subject: * merged with the apt--improved-do-install patch Patches applied: * michael.vogt@ubuntu.com--2005/apt--improved-do-install--0--base-0 tag of apt@packages.debian.org/apt--main--0--patch-88 * michael.vogt@ubuntu.com--2005/apt--improved-do-install--0--patch-1 * merged with apt--fixes to make it build * michael.vogt@ubuntu.com--2005/apt--improved-do-install--0--patch-2 * added "DoInstall{Pre,Post}Fork()" --- apt-pkg/depcache.cc | 3 ++- apt-pkg/packagemanager.cc | 18 ------------------ apt-pkg/packagemanager.h | 36 ++++++++++++++++++++++++++++++++++-- 3 files changed, 36 insertions(+), 21 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index c490d89bc..269fe8543 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -140,7 +140,8 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) bool pkgDepCache::writeStateFile(OpProgress *prog) { - // write the auto-mark list ---------------------------------- + // FIXME: this function needs to be called inside the commit() + // of the package manager. so after FileFd StateFile; string state = _config->FindDir("Dir::State") + "pkgstates"; diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index a97c94fdf..71a0dd034 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -627,21 +627,3 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() return Completed; } /*}}}*/ -// PM::DoInstall - Does the installation /*{{{*/ -// --------------------------------------------------------------------- -/* This uses the filenames in FileNames and the information in the - DepCache to perform the installation of packages.*/ -pkgPackageManager::OrderResult pkgPackageManager::DoInstall() -{ - OrderResult Res = OrderInstall(); - if (Res != Failed) - if (Go() == false) - return Failed; - - // if all was fine update the state file - if(Res == Completed) - Cache.writeStateFile(NULL); - - return Res; -} - /*}}}*/ diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index 43f2c4ace..da1f21e6c 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -29,6 +29,7 @@ #include #include +#include using std::string; @@ -70,13 +71,44 @@ class pkgPackageManager : protected pkgCache::Namespace virtual bool Remove(PkgIterator /*Pkg*/,bool /*Purge*/=false) {return false;}; virtual bool Go(int statusFd=-1) {return true;}; virtual void Reset() {}; - + + // the result of the operation + OrderResult Res; + public: // Main action members bool GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, pkgRecords *Recs); - OrderResult DoInstall(); + + // Do the installation + OrderResult DoInstall() { + if(DoInstallPreFork() == Failed) + return Failed; + + return DoInstallPostFork(); + } + + // stuff that needs to be done before the fork() of a library that + // uses apt + OrderResult DoInstallPreFork() { + Res = OrderInstall(); + return Res; + }; + + // stuff that needs to be done after the fork + OrderResult DoInstallPostFork(int statusFd=-1) { + bool goResult = Go(statusFd); + if(goResult == false) + return Failed; + + // if all was fine update the state file + if(Res == Completed) + Cache.writeStateFile(NULL); + + return Res; + }; + bool FixMissing(); pkgPackageManager(pkgDepCache *Cache); -- cgit v1.2.3 From 20edfd5399dada2d10ad791336797c4118eb60a8 Mon Sep 17 00:00:00 2001 From: Matt Zimmerman Date: Sun, 26 Jun 2005 20:13:10 +0000 Subject: Merge with mainline Patches applied: * apt@packages.debian.org/apt--main--0--patch-93 Merge with mvo * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-22 * added myself to uploaders, changelog is signed with mvo@debian.org and in sync with the debian/experimental upload * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-23 * apt-cache show shows all virtual packages instead of nothing (thanks to otavio) * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-24 * changelog updated * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-25 * make pinning on component work again (we just use the section, as apt-0.6 don't use per-section Release files anymore) * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-27 * updated the changelog * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-28 * merged with my apt--fixes--0 branch * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-29 * added a missing OpProgress::Done() in depCache::Init(), removed the show-virtual-packages patch in apt-cache because matt does not like him :/ * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-30 * fix a stupid bug in the depcache::Init() code * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-31 * merged/removed conflicts with apt--main--0 * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-32 * merged apt--main and make sure that the po files come from apt--main (because they are more recent) --- apt-pkg/deb/debindexfile.cc | 4 ++-- apt-pkg/deb/deblistparser.cc | 11 +++++++++-- apt-pkg/deb/deblistparser.h | 3 ++- apt-pkg/depcache.cc | 3 +++ 4 files changed, 16 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index f26265fff..ff8bce85d 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -24,7 +24,7 @@ #include #include #include - + #include /*}}}*/ @@ -290,7 +290,7 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const FileFd Rel(ReleaseFile,FileFd::ReadOnly); if (_error->PendingError() == true) return false; - Parser.LoadReleaseInfo(File,Rel); + Parser.LoadReleaseInfo(File,Rel,Section); } return true; diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 96a80582d..25b533773 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -564,13 +564,20 @@ bool debListParser::Step() // --------------------------------------------------------------------- /* */ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI, - FileFd &File) + FileFd &File, string component) { pkgTagFile Tags(&File, File.Size() + 256); // XXX pkgTagSection Section; if (Tags.Step(Section) == false) return false; + //mvo: I don't think we need to fill that in (it's unused since apt-0.6) + //FileI->Architecture = WriteUniqString(Arch); + + // apt-secure does no longer download individual (per-section) Release + // file. to provide Component pinning we use the section name now + FileI->Component = WriteUniqString(component); + const char *Start; const char *Stop; if (Section.Find("Suite",Start,Stop) == true) @@ -589,7 +596,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI, if (Section.FindFlag("NotAutomatic",FileI->Flags, pkgCache::Flag::NotAutomatic) == false) _error->Warning("Bad NotAutomatic flag"); - + return !_error->PendingError(); } /*}}}*/ diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 9f305211a..3a0e0421b 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -55,7 +55,8 @@ class debListParser : public pkgCacheGenerator::ListParser virtual bool Step(); - bool LoadReleaseInfo(pkgCache::PkgFileIterator FileI,FileFd &File); + bool LoadReleaseInfo(pkgCache::PkgFileIterator FileI,FileFd &File, + string section); static const char *ParseDepends(const char *Start,const char *Stop, string &Package,string &Ver,unsigned int &Op, diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index c6bf3185a..dd1c794c9 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -91,6 +91,9 @@ bool pkgDepCache::Init(OpProgress *Prog) } Update(Prog); + + if(Prog != 0) + Prog->Done(); return true; } -- cgit v1.2.3 From 29ba053e05b1a496500036dbd667002d1b8b5ec2 Mon Sep 17 00:00:00 2001 From: Matt Zimmerman Date: Sun, 26 Jun 2005 21:30:27 +0000 Subject: Merge with mvo Patches applied: * michael.vogt@ubuntu.com--2005/apt--bts225947--0--base-0 tag of apt@packages.debian.org/apt--main--0--patch-79 * michael.vogt@ubuntu.com--2005/apt--bts225947--0--patch-1 * merged with mainline and apt--fixes--0 * michael.vogt@ubuntu.com--2005/apt--bts225947--0--patch-2 * patch from aj (slighly modified to use auto_ptr<>) applied * michael.vogt@ubuntu.com--2005/apt--bts225947--0--patch-3 * changelog updated * michael.vogt@ubuntu.com--2005/apt--bts225947--0--patch-4 * work for arch=all packages too now * michael.vogt@ubuntu.com--2005/apt--fixes--0--patch-5 * merged with apt--main--0 * michael.vogt@ubuntu.com--2005/apt--fixes--0--patch-7 * fixed incorrect man-page example * michael.vogt@ubuntu.com--2005/apt--fixes--0--patch-8 * changelog udpate * michael.vogt@ubuntu.com--2005/apt--sane-handle-timeout--0--base-0 tag of apt@packages.debian.org/apt--main--0--patch-87 * michael.vogt@ubuntu.com--2005/apt--sane-handle-timeout--0--patch-1 * report timeouts (from Connect) and fail if they happen in pkgAcqMetaSig * michael.vogt@ubuntu.com--2005/apt--sane-handle-timeout--0--patch-2 * merged with the fixes branch to make it build again * michael.vogt@ubuntu.com--2005/apt--ubuntu--0--patch-1 tag of apt@packages.debian.org/apt--main--0--patch-88 * michael.vogt@ubuntu.com--2005/apt--ubuntu--0--patch-2 * merged apt--mvo (to make pining on components work again) * michael.vogt@ubuntu.com--2005/apt--ubuntu--0--patch-3 * merged with apt--fixes--0 (to make the building of the french manpages work and to fix a incorrect man-page example * michael.vogt@ubuntu.com--2005/apt--ubuntu--0--patch-4 * merged with the bts225947 code * michael.vogt@ubuntu.com--2005/apt--ubuntu--0--patch-5 * merged the imporoved timoeut handling patch * michael.vogt@ubuntu.com--2005/apt--ubuntu--0--patch-6 * merged with matt * michael.vogt@ubuntu.com--2005/apt--ubuntu--0--patch-7 * removed another conflict with apt--main --- apt-pkg/acquire-item.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index b2f896627..14acad85a 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -400,6 +400,12 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI); unlink(Final.c_str()); + // if we get a timeout if fail + if(LookupTag(Message,"FailReason") == "Timeout") { + Item::Failed(Message,Cnf); + return; + } + // queue a pkgAcqMetaIndex with no sigfile new pkgAcqMetaIndex(Owner, MetaIndexURI, MetaIndexURIDesc, MetaIndexShortDesc, "", IndexTargets, MetaIndexParser); -- cgit v1.2.3 From e004867d0979224adb9cbeb9705f156e16e3fe26 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 27 Jun 2005 16:29:16 +0000 Subject: * merged with mainline Patches applied: * andrelop@debian.org/apt--translation--0--base-0 tag of apt@packages.debian.org/apt--main--0--patch-79 * andrelop@debian.org/apt--translation--0--patch-1 Sync with Matt version. * andrelop@debian.org/apt--translation--0--patch-2 Update pt_BR translation * andrelop@debian.org/apt--translation--0--patch-3 Sync with bubulle's branch. * apt@packages.debian.org/apt--main--0--patch-89 Branch for Debian * apt@packages.debian.org/apt--main--0--patch-90 Update version in configure * apt@packages.debian.org/apt--main--0--patch-91 Fix French man page build * apt@packages.debian.org/apt--main--0--patch-92 Add the current Debian archive signing key * apt@packages.debian.org/apt--main--0--patch-93 Merge with mvo * apt@packages.debian.org/apt--main--0--patch-94 Update changelog * apt@packages.debian.org/apt--main--0--patch-95 Merge Christian's branch * apt@packages.debian.org/apt--main--0--patch-96 Update changelog * apt@packages.debian.org/apt--main--0--patch-97 Update priority of apt-utils to important, to match the override file * bubulle@debian.org--2005/apt--main--0--patch-82 Fix permissions * bubulle@debian.org--2005/apt--main--0--patch-83 French translation spellchecked * bubulle@debian.org--2005/apt--main--0--patch-84 Spell corrections in German translations * bubulle@debian.org--2005/apt--main--0--patch-85 Correct some file permissions * bubulle@debian.org--2005/apt--main--0--patch-86 Correct Hebrew translation * bubulle@debian.org--2005/apt--main--0--patch-87 Sync Portuguese translation with the POT file * bubulle@debian.org--2005/apt--main--0--patch-88 Updated Danish translation (not yet complete) * bubulle@debian.org--2005/apt--main--0--patch-89 Sync with Andre Luis Lopes and Otavio branches * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-22 * added myself to uploaders, changelog is signed with mvo@debian.org and in sync with the debian/experimental upload * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-23 * apt-cache show shows all virtual packages instead of nothing (thanks to otavio) * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-24 * changelog updated * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-25 * make pinning on component work again (we just use the section, as apt-0.6 don't use per-section Release files anymore) * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-27 * updated the changelog * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-28 * merged with my apt--fixes--0 branch * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-29 * added a missing OpProgress::Done() in depCache::Init(), removed the show-virtual-packages patch in apt-cache because matt does not like him :/ * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-30 * fix a stupid bug in the depcache::Init() code * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-31 * merged/removed conflicts with apt--main--0 * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-32 * merged apt--main and make sure that the po files come from apt--main (because they are more recent) --- apt-pkg/algorithms.cc | 11 ++++++----- apt-pkg/deb/debindexfile.cc | 4 ++-- apt-pkg/deb/deblistparser.cc | 11 +++++++++-- apt-pkg/deb/deblistparser.h | 3 ++- apt-pkg/depcache.cc | 3 +++ 5 files changed, 22 insertions(+), 10 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 98bd8dd8b..dd16b5dc8 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -1330,11 +1330,12 @@ void pkgMarkPkgUsed(pkgDepCache &Cache, pkgCache::PkgIterator Pkg, bool pkgMarkUsed(pkgDepCache &Cache) { // debug only - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); ! Pkg.end(); ++Pkg) - if(!Cache[Pkg].Dirty() && Cache[Pkg].AutomaticRemove > 0) - std::cout << "has auto-remove information: " << Pkg.Name() - << " " << (int)Cache[Pkg].AutomaticRemove - << std::endl; + if(_config->FindI("Debug::pkgAutoRemove",false) == true) + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); ! Pkg.end(); ++Pkg) + if(!Cache[Pkg].Dirty() && Cache[Pkg].AutomaticRemove > 0) + std::cout << "has auto-remove information: " << Pkg.Name() + << " " << (int)Cache[Pkg].AutomaticRemove + << std::endl; // init with defaults for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); ! Pkg.end(); ++Pkg) diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index f26265fff..ff8bce85d 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -24,7 +24,7 @@ #include #include #include - + #include /*}}}*/ @@ -290,7 +290,7 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const FileFd Rel(ReleaseFile,FileFd::ReadOnly); if (_error->PendingError() == true) return false; - Parser.LoadReleaseInfo(File,Rel); + Parser.LoadReleaseInfo(File,Rel,Section); } return true; diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 96a80582d..25b533773 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -564,13 +564,20 @@ bool debListParser::Step() // --------------------------------------------------------------------- /* */ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI, - FileFd &File) + FileFd &File, string component) { pkgTagFile Tags(&File, File.Size() + 256); // XXX pkgTagSection Section; if (Tags.Step(Section) == false) return false; + //mvo: I don't think we need to fill that in (it's unused since apt-0.6) + //FileI->Architecture = WriteUniqString(Arch); + + // apt-secure does no longer download individual (per-section) Release + // file. to provide Component pinning we use the section name now + FileI->Component = WriteUniqString(component); + const char *Start; const char *Stop; if (Section.Find("Suite",Start,Stop) == true) @@ -589,7 +596,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI, if (Section.FindFlag("NotAutomatic",FileI->Flags, pkgCache::Flag::NotAutomatic) == false) _error->Warning("Bad NotAutomatic flag"); - + return !_error->PendingError(); } /*}}}*/ diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 9f305211a..3a0e0421b 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -55,7 +55,8 @@ class debListParser : public pkgCacheGenerator::ListParser virtual bool Step(); - bool LoadReleaseInfo(pkgCache::PkgFileIterator FileI,FileFd &File); + bool LoadReleaseInfo(pkgCache::PkgFileIterator FileI,FileFd &File, + string section); static const char *ParseDepends(const char *Start,const char *Stop, string &Package,string &Ver,unsigned int &Op, diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 269fe8543..54cfcb8bb 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -98,6 +98,9 @@ bool pkgDepCache::Init(OpProgress *Prog) } Update(Prog); + + if(Prog != 0) + Prog->Done(); return true; } -- cgit v1.2.3 From 120365cee294d00706928b0327ac755ab3448eca Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 28 Jun 2005 08:41:51 +0000 Subject: * cleanups, documentation updates (don't show any debug output if no Debug::pkgAutomaticRemove was set, don't remove if not APT::Get::AutomaticRemove (--automatic-remove) was set) --- apt-pkg/algorithms.cc | 7 +++++-- apt-pkg/depcache.cc | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index dd16b5dc8..5167d11eb 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -1066,7 +1066,10 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) pkgCache::PkgIterator I = Cache.PkgBegin(); for (;I.end() != true; I++) { if (Cache[I].NewInstall() && !(Flags[I->ID] & PreInstalled)) { - std::cout << "Resolve installed new pkg: " << I.Name() << " (now marking it as auto)" << std::endl; + if(_config->FindI("Debug::pkgAutoRemove",false)) { + std::clog << "Resolve installed new pkg: " << I.Name() + << " (now marking it as auto)" << std::endl; + } Cache[I].Flags |= pkgCache::Flag::Auto; } } @@ -1333,7 +1336,7 @@ bool pkgMarkUsed(pkgDepCache &Cache) if(_config->FindI("Debug::pkgAutoRemove",false) == true) for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); ! Pkg.end(); ++Pkg) if(!Cache[Pkg].Dirty() && Cache[Pkg].AutomaticRemove > 0) - std::cout << "has auto-remove information: " << Pkg.Name() + std::clog << "has auto-remove information: " << Pkg.Name() << " " << (int)Cache[Pkg].AutomaticRemove << std::endl; diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 54cfcb8bb..e30baa4b2 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -20,6 +20,8 @@ #include #include #include + +#include #include #include /*}}}*/ @@ -162,7 +164,8 @@ bool pkgDepCache::writeStateFile(OpProgress *prog) // check if we have new information if(PkgState[pkg->ID].Flags & pkgCache::Flag::Auto) { - std::cout << "pkg: " << pkg.Name() << " is auto-dep" << std::endl; + if(_config->FindI("Debug::pkgAutoRemove",false)) + std::clog << "pkg: " << pkg.Name() << " is auto-dep" << std::endl; PkgState[pkg->ID].AutomaticRemove = pkgCache::State::RemoveRequired; } @@ -172,7 +175,6 @@ bool pkgDepCache::writeStateFile(OpProgress *prog) << "\nRemove-Reason: " << (int)(PkgState[pkg->ID].AutomaticRemove) << "\n\n"; StateFile.Write(ostr.str().c_str(), ostr.str().size()); - //std::cout << "Writing auto-mark: " << ostr.str() << endl; } } return true; -- cgit v1.2.3 From be65f52793235fa0419af5bb6c867da28506c227 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 28 Jun 2005 09:16:51 +0000 Subject: * bumped the library version --- apt-pkg/makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 5f48f0f52..8de7d945e 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=3.9 +MAJOR=3.10 MINOR=0 SLIBS=$(PTHREADLIB) $(INTLLIBS) APT_DOMAIN:=libapt-pkg$(MAJOR) -- cgit v1.2.3 From 0a57c0f0e4d0bc3474ce4d2101f36a997891d30d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 29 Jun 2005 06:11:36 +0000 Subject: * use mark-and-sweep from aptitude now as GC algorithm --- apt-pkg/algorithms.cc | 245 +++++++++++++++++++++++++++++++++----------------- apt-pkg/depcache.cc | 43 ++++----- apt-pkg/depcache.h | 16 ++-- apt-pkg/pkgcache.h | 1 - 4 files changed, 190 insertions(+), 115 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 5167d11eb..bed90f5d0 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -20,7 +20,10 @@ #include #include #include +#include +#include #include + #include @@ -1248,106 +1251,186 @@ void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List) /*}}}*/ -// pkgMarkPkgUsed - Mark used packages as dirty /*{{{*/ -// --------------------------------------------------------------------- -/* Mark all reachable packages as dirty. */ -void pkgMarkPkgUsed(pkgDepCache &Cache, pkgCache::PkgIterator Pkg, - pkgCache::State::PkgRemoveState DirtLevel) +// mark a single package in Mark-and-Sweep +void pkgMarkPackage(pkgDepCache &Cache, + const pkgCache::PkgIterator &pkg, + const pkgCache::VerIterator &ver, + bool follow_recommends, + bool follow_suggests) { - // If it is not installed, and we are in manual mode, ignore it - if ((Pkg->CurrentVer == 0 && Cache[Pkg].Install() == false || Cache[Pkg].Delete() == true) && - DirtLevel == pkgCache::State::RemoveManual) + pkgDepCache::StateCache &state=Cache[pkg]; + pkgCache::VerIterator candver=state.CandidateVerIter(Cache); + pkgCache::VerIterator instver=state.InstVerIter(Cache); + +#if 0 + // If a package was garbage-collected but is now being marked, we + // should re-select it + // For cases when a pkg is set to upgrade and this trigger the + // removal of a no-longer used dependency. if the pkg is set to + // keep again later it will result in broken deps + if(state.Delete() && state.RemoveReason=pkgDepCache::Unused) { -// fprintf(stdout,"This one is not installed/virtual %s %d %d\n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel); - return; + if(ver==candver) + mark_install(pkg, false, false, NULL); + else if(ver==pkg.CurrentVer()) + MarkKeep(pkg); + + instver=state.InstVerIter(*this); } +#endif - // If it is not installed, and it is not virtual, ignore it - if ((Pkg->CurrentVer == 0 && Cache[Pkg].Install() == false || Cache[Pkg].Delete() == true) && - Pkg->VersionList != 0) - { -// fprintf(stdout,"This one is not installed %s %d %d\n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel); + // Ignore versions other than the InstVer, and ignore packages + // that are already going to be removed or just left uninstalled. + if(!(ver==instver && !instver.end())) return; - } - // If it is similar or more dirty than we are ;-), because we've been here already, don't mark it - // This is necessary because virtual packages just relay the current level, - // so it may be possible e.g. that this was already seen with ::RemoveSuggested, but - // we are ::RemoveRequired - if (Cache[Pkg].Dirty() >= DirtLevel) - { - //fprintf(stdout,"Seen already %s %d %d\n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel); + // if we are marked already we are done + if(state.Marked) return; - } - - // If it is less important than the current DirtLevel, don't mark it - if (Cache[Pkg].AutomaticRemove != pkgCache::State::RemoveManual && - Cache[Pkg].AutomaticRemove > DirtLevel) + + //std::cout << "Setting Marked for: " << pkg.Name() << std::endl; + state.Marked=true; + + if(!ver.end()) { -// fprintf(stdout,"We don't need %s %d %d %d\n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel, Cache[Pkg].Dirty()); - return; + for(pkgCache::DepIterator d=ver.DependsList(); !d.end(); ++d) + { + if(d->Type==pkgCache::Dep::Depends || + d->Type==pkgCache::Dep::PreDepends || + (follow_recommends && + d->Type==pkgCache::Dep::Recommends) || + (follow_suggests && + d->Type==pkgCache::Dep::Suggests)) + { + // Try all versions of this package. + for(pkgCache::VerIterator V=d.TargetPkg().VersionList(); + !V.end(); ++V) + { + if(_system->VS->CheckDep(V.VerStr(),d->CompareOp, d.TargetVer())) + { + pkgMarkPackage(Cache, V.ParentPkg(), V, + follow_recommends, follow_suggests); + } + } + // Now try virtual packages + for(pkgCache::PrvIterator prv=d.TargetPkg().ProvidesList(); + !prv.end(); ++prv) + { + if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp, + d.TargetVer())) + { + pkgMarkPackage(Cache, prv.OwnerPkg(), prv.OwnerVer(), + follow_recommends, follow_suggests); + } + } + } + } } +} - // Mark it as used - Cache.SetDirty(Pkg, DirtLevel); - - //fprintf(stdout,"We keep %s %d %d\n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel); - // We are a virtual package - if (Pkg->VersionList == 0) +bool pkgMarkUsed(pkgDepCache &Cache) +{ + bool follow_recommends; + bool follow_suggests; + + // init the states + for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p) { -// fprintf(stdout,"We are virtual %s %d %d\n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel); - for (pkgCache::PrvIterator Prv = Pkg.ProvidesList(); ! Prv.end(); ++Prv) - pkgMarkPkgUsed (Cache, Prv.OwnerPkg(), DirtLevel); - return; + Cache[p].Marked=false; + Cache[p].Garbage=false; } - // Depending on the type of dependency, follow it - for (pkgCache::DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); ! D.end(); ++D) - { -// fprintf(stdout,"We depend on %s %s\n", D.TargetPkg().Name(), D.DepType()); + // init vars + follow_recommends=_config->FindB("APT::AutoRemove::RecommendsImportant",false); + follow_suggests=_config->FindB("APT::AutoRemove::SuggestsImportend", false); - switch(D->Type) + + // do the mark part + for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p) + { + if(Cache[p].InstallReason==pkgDepCache::Manual || + (p->Flags & pkgCache::Flag::Essential)) { - case pkgCache::Dep::Depends: - case pkgCache::Dep::PreDepends: - pkgMarkPkgUsed (Cache, D.TargetPkg(), pkgCache::State::RemoveRequired); - break; - case pkgCache::Dep::Recommends: - pkgMarkPkgUsed (Cache, D.TargetPkg(), pkgCache::State::RemoveRecommended); - break; - case pkgCache::Dep::Suggests: - pkgMarkPkgUsed (Cache, D.TargetPkg(), pkgCache::State::RemoveSuggested); - break; - case pkgCache::Dep::Conflicts: - case pkgCache::Dep::Replaces: - case pkgCache::Dep::Obsoletes: - // We don't handle these here - break; + if(Cache[p].Keep() && !p.CurrentVer().end()) + pkgMarkPackage(Cache, p, p.CurrentVer(), + follow_recommends, follow_suggests); + else if(Cache[p].Install()) + pkgMarkPackage(Cache, p, Cache[p].InstVerIter(Cache), + follow_recommends, follow_suggests); } } -// fprintf(stdout,"We keep %s %d %d \n", Pkg.Name(), Pkg->AutomaticRemove, DirtLevel); -} - /*}}}*/ -bool pkgMarkUsed(pkgDepCache &Cache) -{ - // debug only - if(_config->FindI("Debug::pkgAutoRemove",false) == true) - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); ! Pkg.end(); ++Pkg) - if(!Cache[Pkg].Dirty() && Cache[Pkg].AutomaticRemove > 0) - std::clog << "has auto-remove information: " << Pkg.Name() - << " " << (int)Cache[Pkg].AutomaticRemove - << std::endl; - - // init with defaults - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); ! Pkg.end(); ++Pkg) - Cache.SetDirty(Pkg, pkgCache::State::RemoveUnknown); - - // go recursive over the cache - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); ! Pkg.end(); ++Pkg) - pkgMarkPkgUsed (Cache, Pkg, pkgCache::State::RemoveManual); - + // do the sweep + for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p) + { + pkgDepCache::StateCache &state=Cache[p]; + + if(!state.Marked) + { + // mark installed but not yet marked stuff as garbage + if(p->CurrentVer != 0) { + state.Garbage=true; + std::cout << "Garbage: " << p.Name() << std::endl; + } + +#if 0 // mvo: the below bits still needs to be ported + + // Be sure not to re-delete already deleted packages. + if(delete_unused && (!p.CurrentVer().end() || state.Install()) && + !state.Delete()) + { + bool do_delete=true; + + // If the package is being upgraded, check if we're + // losing a versioned dep. If the dependency matches + // the previous version and not the new version, keep + // the package back instead of removing it. + if(!p.CurrentVer().end() && state.Install()) + { + const char *vs=p.CurrentVer().VerStr(); + + // Check direct revdeps only. THIS ASSUMES NO + // VERSIONED PROVIDES, but Debian probably won't + // have them for ages if ever. + for(pkgCache::DepIterator revdep=p.RevDependsList(); + !revdep.end(); ++revdep) + { + pkgCache::PkgIterator depender=revdep.ParentPkg(); + // Find which version of the depending package + // will be installed. + pkgCache::VerIterator instver=(*this)[depender].InstVerIter(*this); + + // Only pay attention to strong positive + // dependencies whose parents will be installed. + if(revdep.ParentVer()==instver && + (revdep->Type==pkgCache::Dep::Depends || + revdep->Type==pkgCache::Dep::PreDepends || + (revdep->Type==pkgCache::Dep::Recommends && + follow_recommends))) + { + // If the previous version matched, cancel the + // deletion. (note that I assume that the new + // version does NOT match; otherwise it would + // not be unused!) + if(_system->VS->CheckDep(vs, + revdep->CompareOp, + revdep.TargetVer())) + { + mark_keep(p, false, false, undo); + do_delete=false; + break; + } + } + } + } + + if(do_delete) + mark_delete(p, false, true, undo); + } +#endif + } + } return true; } diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index e30baa4b2..52b43d83d 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -78,9 +78,7 @@ bool pkgDepCache::Init(OpProgress *Prog) // Find the proper cache slot StateCache &State = PkgState[I->ID]; State.iFlags = 0; - State.DirtyState = pkgCache::State::RemoveUnknown; - //State.AutomaticRemove = I->AutomaticRemove; - State.AutomaticRemove = pkgCache::State::RemoveUnknown; + State.InstallReason = Manual; // Figure out the install version State.CandidateVer = GetCandidateVer(I); @@ -116,7 +114,7 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) state_file.Open(state, FileFd::ReadOnly); int file_size = state_file.Size(); Prog->OverallProgress(0, file_size, 1, - _("Reading extended state information")); + _("Reading state information")); pkgTagFile tagfile(&state_file); pkgTagSection section; @@ -127,16 +125,17 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) // Silently ignore unknown packages and packages with no actual // version. if(!pkg.end() && !pkg.VersionList().end()) { - short reason = section.FindI("Remove-Reason", - pkgCache::State::RemoveManual); - PkgState[pkg->ID].AutomaticRemove = reason; - //std::cout << "Set: " << pkgname << " to " << reason << std::endl; + short reason = section.FindI("Install-Reason",pkgDepCache::Manual); + PkgState[pkg->ID].InstallReason = (ChangedReason)reason; + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::cout << "Install-Reason for: " << pkgname + << " is " << reason << std::endl; amt+=section.size(); Prog->OverallProgress(amt, file_size, 1, - _("Reading extended state information")); + _("Reading state information")); } Prog->OverallProgress(file_size, file_size, 1, - _("Reading extended state information")); + _("Reading state information")); } } @@ -145,9 +144,6 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) bool pkgDepCache::writeStateFile(OpProgress *prog) { - // FIXME: this function needs to be called inside the commit() - // of the package manager. so after - FileFd StateFile; string state = _config->FindDir("Dir::State") + "pkgstates"; @@ -160,20 +156,20 @@ bool pkgDepCache::writeStateFile(OpProgress *prog) // clear out no longer installed pkg if(PkgState[pkg->ID].Delete() || pkg.CurrentVer() == NULL) - PkgState[pkg->ID].AutomaticRemove = pkgCache::State::RemoveUnknown; + PkgState[pkg->ID].InstallReason = Manual; // check if we have new information if(PkgState[pkg->ID].Flags & pkgCache::Flag::Auto) { if(_config->FindI("Debug::pkgAutoRemove",false)) std::clog << "pkg: " << pkg.Name() << " is auto-dep" << std::endl; - PkgState[pkg->ID].AutomaticRemove = pkgCache::State::RemoveRequired; + PkgState[pkg->ID].InstallReason = Libapt; } - if(PkgState[pkg->ID].AutomaticRemove != pkgCache::State::RemoveUnknown) { + if(PkgState[pkg->ID].InstallReason != Manual) { ostr.str(string("")); - ostr << "Package: " << pkg.Name() - << "\nRemove-Reason: " - << (int)(PkgState[pkg->ID].AutomaticRemove) << "\n\n"; + ostr << "Package: " << pkg.Name() + << "\nInstall-Reason: " + << (int)(PkgState[pkg->ID].InstallReason) << "\n\n"; StateFile.Write(ostr.str().c_str(), ostr.str().size()); } } @@ -841,15 +837,6 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To) AddSizes(Pkg); } /*}}}*/ -// DepCache::SetDirty - Switch the package between dirty states /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void pkgDepCache::SetDirty(PkgIterator const &Pkg, pkgCache::State::PkgRemoveState To) -{ - StateCache &P = PkgState[Pkg->ID]; - P.DirtyState = To; -} - /*}}}*/ // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/ // --------------------------------------------------------------------- /* */ diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index e02ed72f0..c91e09ab3 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -63,6 +63,10 @@ class pkgDepCache : protected pkgCache::Namespace enum VersionTypes {NowVersion, InstallVersion, CandidateVersion}; enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2}; + + // Flags for the GC + enum ChangedReason {Manual, UserAuto, Libapt, FromResolver, PkgIsUnused}; + struct StateCache { // Epoch stripped text versions of the two version fields @@ -79,9 +83,13 @@ class pkgDepCache : protected pkgCache::Namespace unsigned short Flags; unsigned short iFlags; // Internal flags - // Traversal status and state for automatic removal - unsigned char DirtyState; - unsigned char AutomaticRemove; + // mark and sweep flags + ChangedReason InstallReason; +#if 0 + ChangedReason RemoveReason; +#endif + bool Marked; + bool Garbage; // Various tree indicators signed char Status; // -1,0,1,2 @@ -103,7 +111,6 @@ class pkgDepCache : protected pkgCache::Namespace inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;}; inline bool InstBroken() const {return (DepState & DepInstMin) != DepInstMin;}; inline bool Install() const {return Mode == ModeInstall;}; - inline unsigned char Dirty() const {return DirtyState;}; inline VerIterator InstVerIter(pkgCache &Cache) {return VerIterator(Cache,InstallVer);}; inline VerIterator CandidateVerIter(pkgCache &Cache) @@ -194,7 +201,6 @@ class pkgDepCache : protected pkgCache::Namespace unsigned long Depth = 0); void SetReInstall(PkgIterator const &Pkg,bool To); void SetCandidateVersion(VerIterator TargetVer); - void SetDirty(PkgIterator const &Pkg, pkgCache::State::PkgRemoveState To); // This is for debuging void Update(OpProgress *Prog = 0); diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 083f20ac2..b07951dfb 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -75,7 +75,6 @@ class pkgCache enum PkgInstState {Ok=0,ReInstReq=1,HoldInst=2,HoldReInstReq=3}; enum PkgCurrentState {NotInstalled=0,UnPacked=1,HalfConfigured=2, HalfInstalled=4,ConfigFiles=5,Installed=6}; - enum PkgRemoveState {RemoveUnknown=0, RemoveManual=1,RemoveSuggested=2,RemoveRecommended=3,RemoveRequired=4}; }; struct Flag -- cgit v1.2.3 From bc80031f74e4acfca5b8ca7188b12ee885a713bd Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 29 Jun 2005 11:43:32 +0000 Subject: * fix a bug when readStateFile is called with no OpProgress object --- apt-pkg/depcache.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 05512e179..366687382 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -112,8 +112,9 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) if(FileExists(state)) { state_file.Open(state, FileFd::ReadOnly); int file_size = state_file.Size(); - Prog->OverallProgress(0, file_size, 1, - _("Reading state information")); + if(Prog != NULL) + Prog->OverallProgress(0, file_size, 1, + _("Reading state information")); pkgTagFile tagfile(&state_file); pkgTagSection section; @@ -131,11 +132,13 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) std::cout << "Install-Reason for: " << pkgname << " is " << reason << std::endl; amt+=section.size(); - Prog->OverallProgress(amt, file_size, 1, - _("Reading state information")); + if(Prog != NULL) + Prog->OverallProgress(amt, file_size, 1, + _("Reading state information")); } - Prog->OverallProgress(file_size, file_size, 1, - _("Reading state information")); + if(Prog != NULL) + Prog->OverallProgress(file_size, file_size, 1, + _("Reading state information")); } } -- cgit v1.2.3 From 2ac6ce927cda2847baf8e71a74e595e6b82c6d98 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 30 Jun 2005 08:02:37 +0000 Subject: * added a callback to pkgMarkUsed() so that frontend can extend the root-set of the auto-remover easily --- apt-pkg/algorithms.cc | 10 ++++++---- apt-pkg/algorithms.h | 18 +++++++++++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index c679e76f6..11f5b5671 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -1329,7 +1329,7 @@ void pkgMarkPackage(pkgDepCache &Cache, } -bool pkgMarkUsed(pkgDepCache &Cache) +bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc func) { bool follow_recommends; bool follow_suggests; @@ -1343,14 +1343,16 @@ bool pkgMarkUsed(pkgDepCache &Cache) // init vars follow_recommends=_config->FindB("APT::AutoRemove::RecommendsImportant",false); - follow_suggests=_config->FindB("APT::AutoRemove::SuggestsImportend", false); + follow_suggests=_config->FindB("APT::AutoRemove::SuggestsImportant", false); // do the mark part for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p) { - if(!(Cache[p].Flags & pkgCache::Flag::Auto) || - (p->Flags & pkgCache::Flag::Essential)) + if( (func != NULL ? (*func)(p) : false) || + !(Cache[p].Flags & pkgCache::Flag::Auto) || + (p->Flags & pkgCache::Flag::Essential)) + { if(Cache[p].Keep() && !p.CurrentVer().end()) pkgMarkPackage(Cache, p, p.CurrentVer(), diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 210127ab9..82d7b7aad 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -133,8 +133,20 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache); void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List); -// mark all reachable packages, everything that is not reach can -// be removed -bool pkgMarkUsed(pkgDepCache &Cache); + +// callback function that can be used by the client to bring in +// certain own packages into the root set +typedef bool (*InRootSetFunc)(pkgCache::PkgIterator); + +// Mark all reachable packages with pkgDepCache::StateCache.Marked +// the root-set are all essential packages+everything that was installed +// manually +// +// If InRootSetFunc is set, it will be called for each PkgIterator. This +// is usefull for clients that have there own idea about the root-set +// +// Everything that is not reach can be removed +bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc f=NULL); + #endif -- cgit v1.2.3 From 22dcc318d978813b3c4d1ae1a1f41933d0e1d69b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 30 Jun 2005 08:53:45 +0000 Subject: * added APT::NeverAutoRemove (a list of regexp for package names that should never be automatically removed) --- apt-pkg/algorithms.cc | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 11f5b5671..8e55649ca 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -26,7 +26,8 @@ #include - +#include +#include #include /*}}}*/ using namespace std; @@ -1329,6 +1330,19 @@ void pkgMarkPackage(pkgDepCache &Cache, } +// Helper for APT::NeverAutoRemove, always include the packages matching +// this regexp into the root-set +inline bool +pkgMarkAlwaysInclude(pkgCache::PkgIterator p, vector alwaysMark) +{ + for(unsigned int i=0;iFindB("APT::AutoRemove::SuggestsImportant", false); + // init the "NeverAutoRemove" variable + vector neverAutoRemoveRegexp; + Configuration::Item const *Opts; + Opts = _config->Tree("APT::NeverAutoRemove"); + if (Opts != 0 && Opts->Child != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + + regex_t *p = new regex_t; + if(regcomp(p,Opts->Value.c_str(), + REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0) + { + regfree(p); + for(unsigned int i=0;iError("Regex compilation error for APT::NeverAutoRemove"); + } + neverAutoRemoveRegexp.push_back(p); + } + } + + // do the mark part for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p) { if( (func != NULL ? (*func)(p) : false) || + pkgMarkAlwaysInclude(p, neverAutoRemoveRegexp) || !(Cache[p].Flags & pkgCache::Flag::Auto) || (p->Flags & pkgCache::Flag::Essential)) @@ -1434,5 +1475,11 @@ bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc func) #endif } } + + // cleanup + for(unsigned int i=0;i Date: Thu, 30 Jun 2005 10:47:22 +0000 Subject: * some WS fixes --- apt-pkg/algorithms.cc | 6 ++++-- apt-pkg/algorithms.h | 9 +++++---- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 8e55649ca..8626d33dc 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -1386,18 +1386,20 @@ bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc func) } - // do the mark part + // do the mark part, this is the core bit of the algorithm for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p) { if( (func != NULL ? (*func)(p) : false) || - pkgMarkAlwaysInclude(p, neverAutoRemoveRegexp) || + pkgMarkAlwaysInclude(p, neverAutoRemoveRegexp) || !(Cache[p].Flags & pkgCache::Flag::Auto) || (p->Flags & pkgCache::Flag::Essential)) { + // the package is installed (and set to keep) if(Cache[p].Keep() && !p.CurrentVer().end()) pkgMarkPackage(Cache, p, p.CurrentVer(), follow_recommends, follow_suggests); + // the package is to be installed else if(Cache[p].Install()) pkgMarkPackage(Cache, p, Cache[p].InstVerIter(Cache), follow_recommends, follow_suggests); diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 82d7b7aad..02b40e15f 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -135,12 +135,13 @@ void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List); // callback function that can be used by the client to bring in -// certain own packages into the root set +// certain own packages into the root set (if the client returns +// True the package will be considered as part of the root set) typedef bool (*InRootSetFunc)(pkgCache::PkgIterator); -// Mark all reachable packages with pkgDepCache::StateCache.Marked -// the root-set are all essential packages+everything that was installed -// manually +// Mark all reachable packages with "pkgDepCache::StateCache.Marked=1" +// the root-set are all essential packages+everything that was not +// installed automatically // // If InRootSetFunc is set, it will be called for each PkgIterator. This // is usefull for clients that have there own idea about the root-set -- cgit v1.2.3 From fc5aece9d8600b68cf8d654b379b6d840f2a5524 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 30 Jun 2005 10:50:08 +0000 Subject: * Install-Reason -> Auto-Installed in pkgstates --- apt-pkg/depcache.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 366687382..81c79d812 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -125,12 +125,11 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) // Silently ignore unknown packages and packages with no actual // version. if(!pkg.end() && !pkg.VersionList().end()) { - short reason = section.FindI("Install-Reason", 0); + short reason = section.FindI("Auto-Installed", 0); if(reason > 0) PkgState[pkg->ID].Flags |= pkgCache::Flag::Auto; if(_config->FindB("Debug::pkgAutoRemove",false)) - std::cout << "Install-Reason for: " << pkgname - << " is " << reason << std::endl; + std::cout << "Auto-Installed : " << pkgname << std::endl; amt+=section.size(); if(Prog != NULL) Prog->OverallProgress(amt, file_size, 1, @@ -165,7 +164,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog) std::clog << "AutoInstal: " << pkg.Name() << std::endl; ostr.str(string("")); ostr << "Package: " << pkg.Name() - << "\nInstall-Reason: 1\n\n"; + << "\nAuto-Installed: 1\n\n"; StateFile.Write(ostr.str().c_str(), ostr.str().size()); } } -- cgit v1.2.3 From f8ac1720a94468d1384e88a57729e6d9801b56fd Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 30 Jun 2005 13:34:32 +0000 Subject: * slighly more debug output, renamed "--automatic-remove" to "--auto-remove" --- apt-pkg/algorithms.cc | 16 ++++++++++------ apt-pkg/depcache.cc | 4 ++-- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 8626d33dc..3978e7561 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -1353,6 +1353,11 @@ bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc func) { Cache[p].Marked=false; Cache[p].Garbage=false; + + // debug output + if(_config->FindB("Debug::pkgAutoRemove",false) + && Cache[p].Flags & pkgCache::Flag::Auto) + std::clog << "AutoDep: " << p.Name() << std::endl; } // init vars @@ -1412,14 +1417,13 @@ bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc func) { pkgDepCache::StateCache &state=Cache[p]; - if(!state.Marked) + // if it is not marked and it is installed, it's garbage + if(!state.Marked && !p.CurrentVer().end()) { - // mark installed but not yet marked stuff as garbage - if(p->CurrentVer != 0) { - state.Garbage=true; + state.Garbage=true; + if(_config->FindB("Debug::pkgAutoRemove",false)) std::cout << "Garbage: " << p.Name() << std::endl; - } - + #if 0 // mvo: the below bits still needs to be ported // Be sure not to re-delete already deleted packages. diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 81c79d812..9adc4e390 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -127,7 +127,7 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) if(!pkg.end() && !pkg.VersionList().end()) { short reason = section.FindI("Auto-Installed", 0); if(reason > 0) - PkgState[pkg->ID].Flags |= pkgCache::Flag::Auto; + PkgState[pkg->ID].Flags |= Flag::Auto; if(_config->FindB("Debug::pkgAutoRemove",false)) std::cout << "Auto-Installed : " << pkgname << std::endl; amt+=section.size(); @@ -159,7 +159,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog) std::ostringstream ostr; for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end();pkg++) { - if(PkgState[pkg->ID].Flags & pkgCache::Flag::Auto) { + if(PkgState[pkg->ID].Flags & Flag::Auto) { if(_config->FindB("Debug::pkgAutoRemove",false)) std::clog << "AutoInstal: " << pkg.Name() << std::endl; ostr.str(string("")); -- cgit v1.2.3 From 45f7495cf1b62d402616caffacd9f343ca71c44d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 4 Jul 2005 16:38:42 +0000 Subject: * invert the auto-mark flag only for new installs (in MarkInstall()), keep it as it is for upgrades --- apt-pkg/depcache.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 9adc4e390..4c52c6c71 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -708,7 +708,9 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, P.Mode = ModeInstall; P.InstallVer = P.CandidateVer; - P.Flags &= ~Flag::Auto; + // invert the auto-flag only for new installs, not for upgrades + if(P.Status == 0) + P.Flags &= ~Flag::Auto; if (P.CandidateVer == (Version *)Pkg.CurrentVer()) P.Mode = ModeKeep; -- cgit v1.2.3 From f77bf408f3f7ae650bac2a967f28610737acf1ab Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 5 Aug 2005 11:59:11 +0000 Subject: * merged with apt@packages.debian.org/apt--main--0 Patches applied: * apt@packages.debian.org/apt--main--0--patch-100 Use debian.org address in mainline * apt@packages.debian.org/apt--main--0--patch-101 Update pot file * apt@packages.debian.org/apt--main--0--patch-102 Open 0.6.40 * apt@packages.debian.org/apt--main--0--patch-103 Patch from Jordi Mallach to mark some additional strings for translation * apt@packages.debian.org/apt--main--0--patch-104 Updated Catalan translation from Jordi Mallach * apt@packages.debian.org/apt--main--0--patch-105 Merge from bubulle@debian.org--2005/apt--main--0 * apt@packages.debian.org/apt--main--0--patch-106 Restore lost changelog entries * apt@packages.debian.org/apt--main--0--patch-107 Merge michael.vogt@ubuntu.com--2005/apt--progress-reporting--0 * apt@packages.debian.org/apt--main--0--patch-108 Merge michael.vogt@ubuntu.com--2005/apt--progress-reporting--0 * bubulle@debian.org--2005/apt--main--0--patch-90 Merge with Matt * bubulle@debian.org--2005/apt--main--0--patch-91 Updated Slovak translation * bubulle@debian.org--2005/apt--main--0--patch-92 Add apt-key French man page * bubulle@debian.org--2005/apt--main--0--patch-93 Update Greek translations * bubulle@debian.org--2005/apt--main--0--patch-94 Merge with Matt * bubulle@debian.org--2005/apt--main--0--patch-95 Sync PO files with the POT file/French translation update * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--base-0 tag of apt@packages.debian.org/apt--main--0--patch-85 * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-1 * inital proof of concept code, understands what dpkg tells it already * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-2 * progress reporting works now * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-3 * added "APT::Status-Fd" variable * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-4 * do i18n now too * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-5 * define N_(x) if it is not defined already * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-6 * PackageManager::DoInstall(int status_fd) added (does not break the ABI) * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-7 * merged with apt--fixes--0 to make it build again * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-8 * added support for "error" and "conffile-prompt" messages from dpkg * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-9 merge with main * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-10 * use sizeof() for all snprintf() uses; fix a potential line break problem in the status reading code; changed the N_() to _() calls * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-11 * added APT::KeepFDs configuration list for file descriptors that apt should leave open (needed for various frontends like debconf, synaptic) * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-12 * fixed a API breakage * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-13 * doc added, should be releasable now * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-14 * merged with apt--main--0 * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-15 * more source comments, added Debug::DpkgPM debug code to inspect the dpkg<->apt communication, broke the abi (ok with matt) * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-16 * the progress reporting has it's own "Debug::pkgDPkgProgressReporting" debug variable now * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-17 * merged PackageOps and TranslatedPackageOps into a single Map with the new DpkgState struct * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-18 * clear the APT::Keep-Fds configuration when it's no longer needed * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-19 * rewrote the reading from dpkg so that it never blocks * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-20 * merged the two status arrays into one * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-21 * added support for download progress reporting too (for Kamion and base-config) * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-22 * ABI break; added Configuration::Clear(string List, {int,string} value) added (to remove a single Value from a list); test/conf_clear.cc added --- apt-pkg/acquire.cc | 21 ++++ apt-pkg/contrib/configuration.cc | 46 ++++++++- apt-pkg/contrib/configuration.h | 7 +- apt-pkg/contrib/fileutl.cc | 24 ++++- apt-pkg/contrib/fileutl.h | 2 +- apt-pkg/deb/dpkgpm.cc | 213 ++++++++++++++++++++++++++++++++++----- apt-pkg/deb/dpkgpm.h | 9 +- apt-pkg/packagemanager.cc | 4 +- apt-pkg/packagemanager.h | 2 +- 9 files changed, 291 insertions(+), 37 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index 70dce4f54..62209e65b 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -803,6 +804,26 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) Time = NewTime; } + int fd = _config->FindI("APT::Status-Fd",-1); + if(fd > 0) + { + ostringstream status; + + char msg[200]; + long i = CurrentItems < TotalItems ? CurrentItems + 1 : CurrentItems; + unsigned long ETA = + (unsigned long)((TotalBytes - CurrentBytes) / CurrentCPS); + + snprintf(msg,sizeof(msg), _("Downloading file %li of %li (%s remaining)"), i, TotalItems, TimeToStr(ETA).c_str()); + + // build the status str + status << "dlstatus:" << i + << ":" << (CurrentBytes/float(TotalBytes)*100.0) + << ":" << msg + << endl; + write(fd, status.str().c_str(), status.str().size()); + } + return true; } /*}}}*/ diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc index 69f8d1dca..4b2c0fbb5 100644 --- a/apt-pkg/contrib/configuration.cc +++ b/apt-pkg/contrib/configuration.cc @@ -325,6 +325,47 @@ void Configuration::Set(const char *Name,int Value) char S[300]; snprintf(S,sizeof(S),"%i",Value); Itm->Value = S; +} + /*}}}*/ +// Configuration::Clear - Clear an single value from a list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void Configuration::Clear(string Name, int Value) +{ + char S[300]; + snprintf(S,sizeof(S),"%i",Value); + Clear(Name, S); +} + /*}}}*/ +// Configuration::Clear - Clear an single value from a list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void Configuration::Clear(string Name, string Value) +{ + Item *Top = Lookup(Name.c_str(),false); + if (Top == 0 || Top->Child == 0) + return; + + Item *Tmp, *Prev, *I; + Prev = I = Top->Child; + + while(I != NULL) + { + if(I->Value == Value) + { + Tmp = I; + // was first element, point parent to new first element + if(Top->Child == Tmp) + Top->Child = I->Next; + I = I->Next; + Prev->Next = I; + delete Tmp; + } else { + Prev = I; + I = I->Next; + } + } + } /*}}}*/ // Configuration::Clear - Clear an entire tree /*{{{*/ @@ -333,9 +374,10 @@ void Configuration::Set(const char *Name,int Value) void Configuration::Clear(string Name) { Item *Top = Lookup(Name.c_str(),false); - if (Top == 0) + if (Top == 0) { + cout << "config item: " << Name << " not found" << endl; return; - + } Top->Value = string(); Item *Stop = Top; Top = Top->Child; diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h index 0ed8f59d3..789bc82cf 100644 --- a/apt-pkg/contrib/configuration.h +++ b/apt-pkg/contrib/configuration.h @@ -87,8 +87,13 @@ class Configuration bool Exists(const char *Name) const; bool ExistsAny(const char *Name) const; + // clear a whole tree void Clear(string Name); - + + // remove a certain value from a list (e.g. the list of "APT::Keep-Fds") + void Clear(string List, string Value); + void Clear(string List, int Value); + inline const Item *Tree(const char *Name) const {return Lookup(Name);}; inline void Dump() { Dump(std::clog); }; diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 0ce0c9b9d..9fd71728e 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -32,6 +33,7 @@ #include #include #include +#include /*}}}*/ using namespace std; @@ -306,7 +308,7 @@ bool WaitFd(int Fd,bool write,unsigned long timeout) /* This is used if you want to cleanse the environment for the forked child, it fixes up the important signals and nukes all of the fds, otherwise acts like normal fork. */ -pid_t ExecFork(int dontCloseThisFd) +pid_t ExecFork() { // Fork off the process pid_t Process = fork(); @@ -326,11 +328,27 @@ pid_t ExecFork(int dontCloseThisFd) signal(SIGWINCH,SIG_DFL); signal(SIGCONT,SIG_DFL); signal(SIGTSTP,SIG_DFL); - + + set KeepFDs; + Configuration::Item const *Opts = _config->Tree("APT::Keep-Fds"); + if (Opts != 0 && Opts->Child != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + int fd = atoi(Opts->Value.c_str()); + KeepFDs.insert(fd); + } + } + // Close all of our FDs - just in case for (int K = 3; K != 40; K++) - if(K != dontCloseThisFd) + { + if(KeepFDs.find(K) == KeepFDs.end()) fcntl(K,F_SETFD,FD_CLOEXEC); + } } return Process; diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 4716e261e..041aa3309 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -87,7 +87,7 @@ string SafeGetCWD(); void SetCloseExec(int Fd,bool Close); void SetNonBlock(int Fd,bool Block); bool WaitFd(int Fd,bool write = false,unsigned long timeout = 0); -pid_t ExecFork(int dontCloseThisFd=-1); +pid_t ExecFork(); bool ExecWait(pid_t Pid,const char *Name,bool Reap = false); // File string manipulators diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 61c48dcbb..2e85fc14e 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -25,7 +25,11 @@ #include #include #include -#include +#include +#include + +#include +#include /*}}}*/ using namespace std; @@ -325,8 +329,14 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) /*}}}*/ // DPkgPM::Go - Run the sequence /*{{{*/ // --------------------------------------------------------------------- -/* This globs the operations and calls dpkg */ -bool pkgDPkgPM::Go(int status_fd) +/* This globs the operations and calls dpkg + * + * If it is called with "OutStatusFd" set to a valid file descriptor + * apt will report the install progress over this fd. It maps the + * dpkg states a package goes through to human readable (and i10n-able) + * names and calculates a percentage for each step. +*/ +bool pkgDPkgPM::Go(int OutStatusFd) { unsigned int MaxArgs = _config->FindI("Dpkg::MaxArgs",8*1024); unsigned int MaxArgBytes = _config->FindI("Dpkg::MaxArgBytes",32*1024); @@ -336,7 +346,66 @@ bool pkgDPkgPM::Go(int status_fd) if (RunScriptsWithPkgs("DPkg::Pre-Install-Pkgs") == false) return false; + + // prepare the progress reporting + int Done = 0; + int Total = 0; + // map the dpkg states to the operations that are performed + // (this is sorted in the same way as Item::Ops) + static const struct DpkgState DpkgStatesOpMap[][5] = { + // Install operation + { + {"half-installed", _("Preparing %s")}, + {"unpacked", _("Unpacking %s") }, + NULL + }, + // Configure operation + { + {"unpacked",_("Preparing to configure %s") }, + {"half-configured", _("Configuring %s") }, + { "installed", _("Installed %s")}, + NULL + }, + // Remove operation + { + {"half-configured", _("Preparing for removal of %s")}, + {"half-installed", _("Removing %s")}, + {"config-files", _("Removed %s")}, + NULL + }, + // Purge operation + { + {"config-files", _("Preparing for remove with config %s")}, + {"not-installed", _("Removed with config %s")}, + NULL + }, + }; + + // the dpkg states that the pkg will run through, the string is + // the package, the vector contains the dpkg states that the package + // will go through + map > PackageOps; + // the dpkg states that are already done; the string is the package + // the int is the state that is already done (e.g. a package that is + // going to be install is already in state "half-installed") + map PackageOpsDone; + // init the PackageOps map, go over the list of packages that + // that will be [installed|configured|removed|purged] and add + // them to the PackageOps map (the dpkg states it goes through) + // and the PackageOpsTranslations (human readable strings) + for (vector::iterator I = List.begin(); I != List.end();I++) + { + string name = (*I).Pkg.Name(); + PackageOpsDone[name] = 0; + for(int i=0; (DpkgStatesOpMap[(*I).Op][i]).state != NULL; i++) + { + PackageOps[name].push_back(DpkgStatesOpMap[(*I).Op][i]); + Total++; + } + } + + // this loop is runs once per operation for (vector::iterator I = List.begin(); I != List.end();) { vector::iterator J = I; @@ -367,16 +436,15 @@ bool pkgDPkgPM::Go(int status_fd) } } - // if we got a status_fd argument, we pass it to apt char status_fd_buf[20]; - if(status_fd > 0) - { - Args[n++] = "--status-fd"; - Size += strlen(Args[n-1]); - snprintf(status_fd_buf,20,"%i",status_fd); - Args[n++] = status_fd_buf; - Size += strlen(Args[n-1]); - } + int fd[2]; + pipe(fd); + + Args[n++] = "--status-fd"; + Size += strlen(Args[n-1]); + snprintf(status_fd_buf,sizeof(status_fd_buf),"%i", fd[1]); + Args[n++] = status_fd_buf; + Size += strlen(Args[n-1]); switch (I->Op) { @@ -449,17 +517,17 @@ bool pkgDPkgPM::Go(int status_fd) it doesn't die but we do! So we must also ignore it */ sighandler_t old_SIGQUIT = signal(SIGQUIT,SIG_IGN); sighandler_t old_SIGINT = signal(SIGINT,SIG_IGN); - - // Fork dpkg + + // Fork dpkg pid_t Child; - if(status_fd > 0) - Child = ExecFork(status_fd); - else - Child = ExecFork(); + _config->Set("APT::Keep-Fds::",fd[1]); + Child = ExecFork(); // This is the child if (Child == 0) { + close(fd[0]); // close the read end of the pipe + if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0) _exit(100); @@ -487,19 +555,112 @@ bool pkgDPkgPM::Go(int status_fd) _exit(100); } + // clear the Keep-Fd again + _config->Clear("APT::Keep-Fds",fd[1]); + // Wait for dpkg int Status = 0; - while (waitpid(Child,&Status,0) != Child) - { - if (errno == EINTR) + + // we read from dpkg here + int _dpkgin = fd[0]; + fcntl(_dpkgin, F_SETFL, O_NONBLOCK); + close(fd[1]); // close the write end of the pipe + + // the read buffers for the communication with dpkg + char line[1024] = {0,}; + char buf[2] = {0,0}; + + // the result of the waitpid call + int res; + + while ((res=waitpid(Child,&Status, WNOHANG)) != Child) { + if(res < 0) { + // FIXME: move this to a function or something, looks ugly here + // error handling, waitpid returned -1 + if (errno == EINTR) + continue; + RunScripts("DPkg::Post-Invoke"); + + // Restore sig int/quit + signal(SIGQUIT,old_SIGQUIT); + signal(SIGINT,old_SIGINT); + return _error->Errno("waitpid","Couldn't wait for subprocess"); + } + + // read a single char, make sure that the read can't block + // (otherwise we may leave zombies) + int len = read(_dpkgin, buf, 1); + + // nothing to read, wait a bit for more + if(len <= 0) + { + usleep(1000); continue; - RunScripts("DPkg::Post-Invoke"); + } + + // sanity check (should never happen) + if(strlen(line) >= sizeof(line)-10) + { + _error->Error("got a overlong line from dpkg: '%s'",line); + line[0]=0; + } + // append to line, check if we got a complete line + strcat(line, buf); + if(buf[0] != '\n') + continue; + + if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) + std::clog << "got from dpkg '" << line << "'" << std::endl; + + // pass "error" and "conffile-prompt" messages from dpkg verbatim + if((strncmp(line,"error",strlen("error")) == 0) || + (strncmp(line,"conffile-prompt",strlen("conffile-prompt")) == 0)) + { + write(OutStatusFd, line, strlen(line)); + line[0]=0; + continue; + } + // line contains the dpkg status info now. it has the form: + // 'status: : ' (see dpkg(1) for details) + char* list[5]; + TokSplitString(':', line, list, 5); + char *pkg = list[1]; + char *action = list[2]; + vector &states = PackageOps[pkg]; + const char *next_action = states[PackageOpsDone[pkg]].state; + const char *translation = states[PackageOpsDone[pkg]].str; + char s[200]; + snprintf(s, sizeof(s), translation, pkg); + // check if the package moved to the next dpkg state + if(next_action && (strcmp(action, next_action) == 0)) + { + // we moved from one dpkg state to a new one, report that + PackageOpsDone[pkg]++; + Done++; + ostringstream status; + // build the status str + status << "pmstatus:" << pkg + << ":" << (Done/float(Total)*100.0) + << ":" << s + << endl; + if(OutStatusFd > 0) + write(OutStatusFd, status.str().c_str(), status.str().size()); + if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) + { + std::clog << "send to fd: '" << status.str() + << "'" << std::endl; + + } + + } + if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) + std::clog << "(parsed from dpkg) pkg: " << pkg + << " action: " << action << endl; - // Restore sig int/quit - signal(SIGQUIT,old_SIGQUIT); - signal(SIGINT,old_SIGINT); - return _error->Errno("waitpid","Couldn't wait for subprocess"); + // reset the line buffer + line[0]=0; } + close(_dpkgin); // Restore sig int/quit signal(SIGQUIT,old_SIGQUIT); diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index b59b9dc93..2ff8a9ac7 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -23,6 +23,13 @@ using std::vector; class pkgDPkgPM : public pkgPackageManager { protected: + + // used for progress reporting + struct DpkgState + { + const char *state; // the dpkg state (e.g. "unpack") + const char *str; // the human readable translation of the state + }; struct Item { @@ -45,7 +52,7 @@ class pkgDPkgPM : public pkgPackageManager virtual bool Install(PkgIterator Pkg,string File); virtual bool Configure(PkgIterator Pkg); virtual bool Remove(PkgIterator Pkg,bool Purge = false); - virtual bool Go(int status_fd=-1); + virtual bool Go(int StatusFd=-1); virtual void Reset(); public: diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index a08ccd602..155408bb4 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -631,11 +631,11 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() // --------------------------------------------------------------------- /* This uses the filenames in FileNames and the information in the DepCache to perform the installation of packages.*/ -pkgPackageManager::OrderResult pkgPackageManager::DoInstall() +pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int status_fd) { OrderResult Res = OrderInstall(); if (Res != Failed) - if (Go() == false) + if (Go(status_fd) == false) return Failed; return Res; } diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index 43f2c4ace..f64637d03 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -76,7 +76,7 @@ class pkgPackageManager : protected pkgCache::Namespace // Main action members bool GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, pkgRecords *Recs); - OrderResult DoInstall(); + OrderResult DoInstall(int statusFd=-1); bool FixMissing(); pkgPackageManager(pkgDepCache *Cache); -- cgit v1.2.3 From dfa11ecc05d342af77f86120c123a3ea618544b6 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 5 Aug 2005 12:04:22 +0000 Subject: * merged the fixes from apt--progress-reporting Patches applied: * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-23 * remvoed a debug string * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-24 * soname changed, fixed a bug in the parsing code when dpkg send the same state more than once (at the end) * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-25 * merged with apt@packages.debian.org/apt--main--0, added changelog entry for the 0.6.40.1 upload * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-26 * fix a bug when out-of-order states are send from dpkg * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-27 * changelog update * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-28 * a real changelog entry now --- apt-pkg/contrib/configuration.cc | 5 ++--- apt-pkg/deb/dpkgpm.cc | 21 +++++++++++++-------- apt-pkg/init.h | 2 +- apt-pkg/makefile | 2 +- 4 files changed, 17 insertions(+), 13 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc index 4b2c0fbb5..09e454be9 100644 --- a/apt-pkg/contrib/configuration.cc +++ b/apt-pkg/contrib/configuration.cc @@ -374,10 +374,9 @@ void Configuration::Clear(string Name, string Value) void Configuration::Clear(string Name) { Item *Top = Lookup(Name.c_str(),false); - if (Top == 0) { - cout << "config item: " << Name << " not found" << endl; + if (Top == 0) return; - } + Top->Value = string(); Item *Stop = Top; Top = Top->Child; diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 2e85fc14e..79a8c312b 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -357,27 +357,27 @@ bool pkgDPkgPM::Go(int OutStatusFd) { {"half-installed", _("Preparing %s")}, {"unpacked", _("Unpacking %s") }, - NULL + {NULL, NULL} }, // Configure operation { {"unpacked",_("Preparing to configure %s") }, {"half-configured", _("Configuring %s") }, { "installed", _("Installed %s")}, - NULL + {NULL, NULL} }, // Remove operation { {"half-configured", _("Preparing for removal of %s")}, {"half-installed", _("Removing %s")}, {"config-files", _("Removed %s")}, - NULL + {NULL, NULL} }, // Purge operation { {"config-files", _("Preparing for remove with config %s")}, {"not-installed", _("Removed with config %s")}, - NULL + {NULL, NULL} }, }; @@ -627,13 +627,18 @@ bool pkgDPkgPM::Go(int OutStatusFd) char *pkg = list[1]; char *action = list[2]; vector &states = PackageOps[pkg]; - const char *next_action = states[PackageOpsDone[pkg]].state; - const char *translation = states[PackageOpsDone[pkg]].str; - char s[200]; - snprintf(s, sizeof(s), translation, pkg); + const char *next_action = NULL; + if(PackageOpsDone[pkg] < states.size()) + next_action = states[PackageOpsDone[pkg]].state; // check if the package moved to the next dpkg state if(next_action && (strcmp(action, next_action) == 0)) { + // only read the translation if there is actually a next + // action + const char *translation = states[PackageOpsDone[pkg]].str; + char s[200]; + snprintf(s, sizeof(s), translation, pkg); + // we moved from one dpkg state to a new one, report that PackageOpsDone[pkg]++; Done++; diff --git a/apt-pkg/init.h b/apt-pkg/init.h index 74ac3a7ca..e21351797 100644 --- a/apt-pkg/init.h +++ b/apt-pkg/init.h @@ -18,7 +18,7 @@ // See the makefile #define APT_PKG_MAJOR 3 -#define APT_PKG_MINOR 5 +#define APT_PKG_MINOR 10 #define APT_PKG_RELEASE 0 extern const char *pkgVersion; diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 5f48f0f52..8de7d945e 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=3.9 +MAJOR=3.10 MINOR=0 SLIBS=$(PTHREADLIB) $(INTLLIBS) APT_DOMAIN:=libapt-pkg$(MAJOR) -- cgit v1.2.3 From 64995601ae9335dedd180d634940f1426598f7f0 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 9 Aug 2005 08:48:41 +0000 Subject: * merged with apt--main Patches applied: * apt@packages.debian.org/apt--main--0--patch-109 Merge michael.vogt@ubuntu.com--2005/apt--progress-reporting--0 * apt@packages.debian.org/apt--main--0--patch-110 Merge michael.vogt@ubuntu.com--2005/apt--progress-reporting--0 * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-29 * changelog finalized * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-30 * propper (and sane) support for pmerror and pmconffile added --- apt-pkg/deb/dpkgpm.cc | 60 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 18 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 79a8c312b..fe8fbca74 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -612,20 +612,49 @@ bool pkgDPkgPM::Go(int OutStatusFd) if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) std::clog << "got from dpkg '" << line << "'" << std::endl; - // pass "error" and "conffile-prompt" messages from dpkg verbatim - if((strncmp(line,"error",strlen("error")) == 0) || - (strncmp(line,"conffile-prompt",strlen("conffile-prompt")) == 0)) - { - write(OutStatusFd, line, strlen(line)); - line[0]=0; - continue; - } - // line contains the dpkg status info now. it has the form: - // 'status: : ' (see dpkg(1) for details) - char* list[5]; + // the status we output + ostringstream status; + + /* dpkg sends strings like this: + 'status: : ' + errors look like this: + 'status: /var/cache/apt/archives/krecipes_0.8.1-0ubuntu1_i386.deb : error : trying to overwrite `/usr/share/doc/kde/HTML/en/krecipes/krectip.png', which is also in package krecipes-data + and conffile-prompt like this + 'status: conffile-prompt: conffile : 'current-conffile' 'new-conffile' useredited distedited + + */ + char* list[4]; TokSplitString(':', line, list, 5); char *pkg = list[1]; - char *action = list[2]; + char *action = _strstrip(list[2]); + + if(strncmp(action,"error",strlen("error")) == 0) + { + status << "pmerror:" << list[1] + << ":" << (Done/float(Total)*100.0) + << ":" << list[3] + << endl; + if(OutStatusFd > 0) + write(OutStatusFd, status.str().c_str(), status.str().size()); + line[0]=0; + if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) + std::clog << "send: '" << status.str() << "'" << endl; + continue; + } + if(strncmp(action,"conffile",strlen("conffile")) == 0) + { + status << "pmconffile:" << list[1] + << ":" << (Done/float(Total)*100.0) + << ":" << list[3] + << endl; + if(OutStatusFd > 0) + write(OutStatusFd, status.str().c_str(), status.str().size()); + line[0]=0; + if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) + std::clog << "send: '" << status.str() << "'" << endl; + continue; + } + vector &states = PackageOps[pkg]; const char *next_action = NULL; if(PackageOpsDone[pkg] < states.size()) @@ -642,7 +671,6 @@ bool pkgDPkgPM::Go(int OutStatusFd) // we moved from one dpkg state to a new one, report that PackageOpsDone[pkg]++; Done++; - ostringstream status; // build the status str status << "pmstatus:" << pkg << ":" << (Done/float(Total)*100.0) @@ -651,11 +679,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) if(OutStatusFd > 0) write(OutStatusFd, status.str().c_str(), status.str().size()); if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) - { - std::clog << "send to fd: '" << status.str() - << "'" << std::endl; - - } + std::clog << "send: '" << status.str() << "'" << endl; } if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) -- cgit v1.2.3 From 2a7e07c7578048abd9f7bfd4ce0ca5c3696b9f3a Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 18 Aug 2005 10:38:58 +0000 Subject: * merged from main Patches applied: * apt@packages.debian.org/apt--main--0--patch-100 Use debian.org address in mainline * apt@packages.debian.org/apt--main--0--patch-101 Update pot file * apt@packages.debian.org/apt--main--0--patch-102 Open 0.6.40 * apt@packages.debian.org/apt--main--0--patch-103 Patch from Jordi Mallach to mark some additional strings for translation * apt@packages.debian.org/apt--main--0--patch-104 Updated Catalan translation from Jordi Mallach * apt@packages.debian.org/apt--main--0--patch-105 Merge from bubulle@debian.org--2005/apt--main--0 * apt@packages.debian.org/apt--main--0--patch-106 Restore lost changelog entries * apt@packages.debian.org/apt--main--0--patch-107 Merge michael.vogt@ubuntu.com--2005/apt--progress-reporting--0 * apt@packages.debian.org/apt--main--0--patch-108 Merge michael.vogt@ubuntu.com--2005/apt--progress-reporting--0 * apt@packages.debian.org/apt--main--0--patch-109 Merge michael.vogt@ubuntu.com--2005/apt--progress-reporting--0 * apt@packages.debian.org/apt--main--0--patch-110 Merge michael.vogt@ubuntu.com--2005/apt--progress-reporting--0 * bubulle@debian.org--2005/apt--main--0--patch-90 Merge with Matt * bubulle@debian.org--2005/apt--main--0--patch-91 Updated Slovak translation * bubulle@debian.org--2005/apt--main--0--patch-92 Add apt-key French man page * bubulle@debian.org--2005/apt--main--0--patch-93 Update Greek translations * bubulle@debian.org--2005/apt--main--0--patch-94 Merge with Matt * bubulle@debian.org--2005/apt--main--0--patch-95 Sync PO files with the POT file/French translation update * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--base-0 tag of apt@packages.debian.org/apt--main--0--patch-85 * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-1 * inital proof of concept code, understands what dpkg tells it already * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-2 * progress reporting works now * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-3 * added "APT::Status-Fd" variable * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-4 * do i18n now too * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-5 * define N_(x) if it is not defined already * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-6 * PackageManager::DoInstall(int status_fd) added (does not break the ABI) * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-7 * merged with apt--fixes--0 to make it build again * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-8 * added support for "error" and "conffile-prompt" messages from dpkg * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-9 merge with main * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-10 * use sizeof() for all snprintf() uses; fix a potential line break problem in the status reading code; changed the N_() to _() calls * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-11 * added APT::KeepFDs configuration list for file descriptors that apt should leave open (needed for various frontends like debconf, synaptic) * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-12 * fixed a API breakage * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-13 * doc added, should be releasable now * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-14 * merged with apt--main--0 * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-15 * more source comments, added Debug::DpkgPM debug code to inspect the dpkg<->apt communication, broke the abi (ok with matt) * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-16 * the progress reporting has it's own "Debug::pkgDPkgProgressReporting" debug variable now * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-17 * merged PackageOps and TranslatedPackageOps into a single Map with the new DpkgState struct * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-18 * clear the APT::Keep-Fds configuration when it's no longer needed * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-19 * rewrote the reading from dpkg so that it never blocks * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-20 * merged the two status arrays into one * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-21 * added support for download progress reporting too (for Kamion and base-config) * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-22 * ABI break; added Configuration::Clear(string List, {int,string} value) added (to remove a single Value from a list); test/conf_clear.cc added * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-23 * remvoed a debug string * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-24 * soname changed, fixed a bug in the parsing code when dpkg send the same state more than once (at the end) * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-25 * merged with apt@packages.debian.org/apt--main--0, added changelog entry for the 0.6.40.1 upload * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-26 * fix a bug when out-of-order states are send from dpkg * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-27 * changelog update * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-28 * a real changelog entry now * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-29 * changelog finalized * michael.vogt@ubuntu.com--2005/apt--progress-reporting--0--patch-30 * propper (and sane) support for pmerror and pmconffile added --- apt-pkg/acquire.cc | 21 ++++ apt-pkg/contrib/configuration.cc | 45 +++++++- apt-pkg/contrib/configuration.h | 7 +- apt-pkg/contrib/fileutl.cc | 24 +++- apt-pkg/contrib/fileutl.h | 2 +- apt-pkg/deb/dpkgpm.cc | 242 ++++++++++++++++++++++++++++++++++----- apt-pkg/deb/dpkgpm.h | 9 +- apt-pkg/init.h | 2 +- apt-pkg/makefile | 2 +- apt-pkg/packagemanager.cc | 12 ++ apt-pkg/packagemanager.h | 7 +- 11 files changed, 331 insertions(+), 42 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index 70dce4f54..62209e65b 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -803,6 +804,26 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) Time = NewTime; } + int fd = _config->FindI("APT::Status-Fd",-1); + if(fd > 0) + { + ostringstream status; + + char msg[200]; + long i = CurrentItems < TotalItems ? CurrentItems + 1 : CurrentItems; + unsigned long ETA = + (unsigned long)((TotalBytes - CurrentBytes) / CurrentCPS); + + snprintf(msg,sizeof(msg), _("Downloading file %li of %li (%s remaining)"), i, TotalItems, TimeToStr(ETA).c_str()); + + // build the status str + status << "dlstatus:" << i + << ":" << (CurrentBytes/float(TotalBytes)*100.0) + << ":" << msg + << endl; + write(fd, status.str().c_str(), status.str().size()); + } + return true; } /*}}}*/ diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc index 69f8d1dca..09e454be9 100644 --- a/apt-pkg/contrib/configuration.cc +++ b/apt-pkg/contrib/configuration.cc @@ -325,6 +325,47 @@ void Configuration::Set(const char *Name,int Value) char S[300]; snprintf(S,sizeof(S),"%i",Value); Itm->Value = S; +} + /*}}}*/ +// Configuration::Clear - Clear an single value from a list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void Configuration::Clear(string Name, int Value) +{ + char S[300]; + snprintf(S,sizeof(S),"%i",Value); + Clear(Name, S); +} + /*}}}*/ +// Configuration::Clear - Clear an single value from a list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void Configuration::Clear(string Name, string Value) +{ + Item *Top = Lookup(Name.c_str(),false); + if (Top == 0 || Top->Child == 0) + return; + + Item *Tmp, *Prev, *I; + Prev = I = Top->Child; + + while(I != NULL) + { + if(I->Value == Value) + { + Tmp = I; + // was first element, point parent to new first element + if(Top->Child == Tmp) + Top->Child = I->Next; + I = I->Next; + Prev->Next = I; + delete Tmp; + } else { + Prev = I; + I = I->Next; + } + } + } /*}}}*/ // Configuration::Clear - Clear an entire tree /*{{{*/ @@ -333,9 +374,9 @@ void Configuration::Set(const char *Name,int Value) void Configuration::Clear(string Name) { Item *Top = Lookup(Name.c_str(),false); - if (Top == 0) + if (Top == 0) return; - + Top->Value = string(); Item *Stop = Top; Top = Top->Child; diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h index 0ed8f59d3..789bc82cf 100644 --- a/apt-pkg/contrib/configuration.h +++ b/apt-pkg/contrib/configuration.h @@ -87,8 +87,13 @@ class Configuration bool Exists(const char *Name) const; bool ExistsAny(const char *Name) const; + // clear a whole tree void Clear(string Name); - + + // remove a certain value from a list (e.g. the list of "APT::Keep-Fds") + void Clear(string List, string Value); + void Clear(string List, int Value); + inline const Item *Tree(const char *Name) const {return Lookup(Name);}; inline void Dump() { Dump(std::clog); }; diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 0ce0c9b9d..9fd71728e 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -32,6 +33,7 @@ #include #include #include +#include /*}}}*/ using namespace std; @@ -306,7 +308,7 @@ bool WaitFd(int Fd,bool write,unsigned long timeout) /* This is used if you want to cleanse the environment for the forked child, it fixes up the important signals and nukes all of the fds, otherwise acts like normal fork. */ -pid_t ExecFork(int dontCloseThisFd) +pid_t ExecFork() { // Fork off the process pid_t Process = fork(); @@ -326,11 +328,27 @@ pid_t ExecFork(int dontCloseThisFd) signal(SIGWINCH,SIG_DFL); signal(SIGCONT,SIG_DFL); signal(SIGTSTP,SIG_DFL); - + + set KeepFDs; + Configuration::Item const *Opts = _config->Tree("APT::Keep-Fds"); + if (Opts != 0 && Opts->Child != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + int fd = atoi(Opts->Value.c_str()); + KeepFDs.insert(fd); + } + } + // Close all of our FDs - just in case for (int K = 3; K != 40; K++) - if(K != dontCloseThisFd) + { + if(KeepFDs.find(K) == KeepFDs.end()) fcntl(K,F_SETFD,FD_CLOEXEC); + } } return Process; diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 4716e261e..041aa3309 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -87,7 +87,7 @@ string SafeGetCWD(); void SetCloseExec(int Fd,bool Close); void SetNonBlock(int Fd,bool Block); bool WaitFd(int Fd,bool write = false,unsigned long timeout = 0); -pid_t ExecFork(int dontCloseThisFd=-1); +pid_t ExecFork(); bool ExecWait(pid_t Pid,const char *Name,bool Reap = false); // File string manipulators diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 61c48dcbb..fe8fbca74 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -25,7 +25,11 @@ #include #include #include -#include +#include +#include + +#include +#include /*}}}*/ using namespace std; @@ -325,8 +329,14 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) /*}}}*/ // DPkgPM::Go - Run the sequence /*{{{*/ // --------------------------------------------------------------------- -/* This globs the operations and calls dpkg */ -bool pkgDPkgPM::Go(int status_fd) +/* This globs the operations and calls dpkg + * + * If it is called with "OutStatusFd" set to a valid file descriptor + * apt will report the install progress over this fd. It maps the + * dpkg states a package goes through to human readable (and i10n-able) + * names and calculates a percentage for each step. +*/ +bool pkgDPkgPM::Go(int OutStatusFd) { unsigned int MaxArgs = _config->FindI("Dpkg::MaxArgs",8*1024); unsigned int MaxArgBytes = _config->FindI("Dpkg::MaxArgBytes",32*1024); @@ -336,7 +346,66 @@ bool pkgDPkgPM::Go(int status_fd) if (RunScriptsWithPkgs("DPkg::Pre-Install-Pkgs") == false) return false; + + // prepare the progress reporting + int Done = 0; + int Total = 0; + // map the dpkg states to the operations that are performed + // (this is sorted in the same way as Item::Ops) + static const struct DpkgState DpkgStatesOpMap[][5] = { + // Install operation + { + {"half-installed", _("Preparing %s")}, + {"unpacked", _("Unpacking %s") }, + {NULL, NULL} + }, + // Configure operation + { + {"unpacked",_("Preparing to configure %s") }, + {"half-configured", _("Configuring %s") }, + { "installed", _("Installed %s")}, + {NULL, NULL} + }, + // Remove operation + { + {"half-configured", _("Preparing for removal of %s")}, + {"half-installed", _("Removing %s")}, + {"config-files", _("Removed %s")}, + {NULL, NULL} + }, + // Purge operation + { + {"config-files", _("Preparing for remove with config %s")}, + {"not-installed", _("Removed with config %s")}, + {NULL, NULL} + }, + }; + // the dpkg states that the pkg will run through, the string is + // the package, the vector contains the dpkg states that the package + // will go through + map > PackageOps; + // the dpkg states that are already done; the string is the package + // the int is the state that is already done (e.g. a package that is + // going to be install is already in state "half-installed") + map PackageOpsDone; + + // init the PackageOps map, go over the list of packages that + // that will be [installed|configured|removed|purged] and add + // them to the PackageOps map (the dpkg states it goes through) + // and the PackageOpsTranslations (human readable strings) + for (vector::iterator I = List.begin(); I != List.end();I++) + { + string name = (*I).Pkg.Name(); + PackageOpsDone[name] = 0; + for(int i=0; (DpkgStatesOpMap[(*I).Op][i]).state != NULL; i++) + { + PackageOps[name].push_back(DpkgStatesOpMap[(*I).Op][i]); + Total++; + } + } + + // this loop is runs once per operation for (vector::iterator I = List.begin(); I != List.end();) { vector::iterator J = I; @@ -367,16 +436,15 @@ bool pkgDPkgPM::Go(int status_fd) } } - // if we got a status_fd argument, we pass it to apt char status_fd_buf[20]; - if(status_fd > 0) - { - Args[n++] = "--status-fd"; - Size += strlen(Args[n-1]); - snprintf(status_fd_buf,20,"%i",status_fd); - Args[n++] = status_fd_buf; - Size += strlen(Args[n-1]); - } + int fd[2]; + pipe(fd); + + Args[n++] = "--status-fd"; + Size += strlen(Args[n-1]); + snprintf(status_fd_buf,sizeof(status_fd_buf),"%i", fd[1]); + Args[n++] = status_fd_buf; + Size += strlen(Args[n-1]); switch (I->Op) { @@ -449,17 +517,17 @@ bool pkgDPkgPM::Go(int status_fd) it doesn't die but we do! So we must also ignore it */ sighandler_t old_SIGQUIT = signal(SIGQUIT,SIG_IGN); sighandler_t old_SIGINT = signal(SIGINT,SIG_IGN); - - // Fork dpkg + + // Fork dpkg pid_t Child; - if(status_fd > 0) - Child = ExecFork(status_fd); - else - Child = ExecFork(); + _config->Set("APT::Keep-Fds::",fd[1]); + Child = ExecFork(); // This is the child if (Child == 0) { + close(fd[0]); // close the read end of the pipe + if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0) _exit(100); @@ -487,19 +555,141 @@ bool pkgDPkgPM::Go(int status_fd) _exit(100); } + // clear the Keep-Fd again + _config->Clear("APT::Keep-Fds",fd[1]); + // Wait for dpkg int Status = 0; - while (waitpid(Child,&Status,0) != Child) - { - if (errno == EINTR) + + // we read from dpkg here + int _dpkgin = fd[0]; + fcntl(_dpkgin, F_SETFL, O_NONBLOCK); + close(fd[1]); // close the write end of the pipe + + // the read buffers for the communication with dpkg + char line[1024] = {0,}; + char buf[2] = {0,0}; + + // the result of the waitpid call + int res; + + while ((res=waitpid(Child,&Status, WNOHANG)) != Child) { + if(res < 0) { + // FIXME: move this to a function or something, looks ugly here + // error handling, waitpid returned -1 + if (errno == EINTR) + continue; + RunScripts("DPkg::Post-Invoke"); + + // Restore sig int/quit + signal(SIGQUIT,old_SIGQUIT); + signal(SIGINT,old_SIGINT); + return _error->Errno("waitpid","Couldn't wait for subprocess"); + } + + // read a single char, make sure that the read can't block + // (otherwise we may leave zombies) + int len = read(_dpkgin, buf, 1); + + // nothing to read, wait a bit for more + if(len <= 0) + { + usleep(1000); continue; - RunScripts("DPkg::Post-Invoke"); + } + + // sanity check (should never happen) + if(strlen(line) >= sizeof(line)-10) + { + _error->Error("got a overlong line from dpkg: '%s'",line); + line[0]=0; + } + // append to line, check if we got a complete line + strcat(line, buf); + if(buf[0] != '\n') + continue; + + if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) + std::clog << "got from dpkg '" << line << "'" << std::endl; + + // the status we output + ostringstream status; + + /* dpkg sends strings like this: + 'status: : ' + errors look like this: + 'status: /var/cache/apt/archives/krecipes_0.8.1-0ubuntu1_i386.deb : error : trying to overwrite `/usr/share/doc/kde/HTML/en/krecipes/krectip.png', which is also in package krecipes-data + and conffile-prompt like this + 'status: conffile-prompt: conffile : 'current-conffile' 'new-conffile' useredited distedited + + */ + char* list[4]; + TokSplitString(':', line, list, 5); + char *pkg = list[1]; + char *action = _strstrip(list[2]); + + if(strncmp(action,"error",strlen("error")) == 0) + { + status << "pmerror:" << list[1] + << ":" << (Done/float(Total)*100.0) + << ":" << list[3] + << endl; + if(OutStatusFd > 0) + write(OutStatusFd, status.str().c_str(), status.str().size()); + line[0]=0; + if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) + std::clog << "send: '" << status.str() << "'" << endl; + continue; + } + if(strncmp(action,"conffile",strlen("conffile")) == 0) + { + status << "pmconffile:" << list[1] + << ":" << (Done/float(Total)*100.0) + << ":" << list[3] + << endl; + if(OutStatusFd > 0) + write(OutStatusFd, status.str().c_str(), status.str().size()); + line[0]=0; + if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) + std::clog << "send: '" << status.str() << "'" << endl; + continue; + } + + vector &states = PackageOps[pkg]; + const char *next_action = NULL; + if(PackageOpsDone[pkg] < states.size()) + next_action = states[PackageOpsDone[pkg]].state; + // check if the package moved to the next dpkg state + if(next_action && (strcmp(action, next_action) == 0)) + { + // only read the translation if there is actually a next + // action + const char *translation = states[PackageOpsDone[pkg]].str; + char s[200]; + snprintf(s, sizeof(s), translation, pkg); + + // we moved from one dpkg state to a new one, report that + PackageOpsDone[pkg]++; + Done++; + // build the status str + status << "pmstatus:" << pkg + << ":" << (Done/float(Total)*100.0) + << ":" << s + << endl; + if(OutStatusFd > 0) + write(OutStatusFd, status.str().c_str(), status.str().size()); + if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) + std::clog << "send: '" << status.str() << "'" << endl; + + } + if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) + std::clog << "(parsed from dpkg) pkg: " << pkg + << " action: " << action << endl; - // Restore sig int/quit - signal(SIGQUIT,old_SIGQUIT); - signal(SIGINT,old_SIGINT); - return _error->Errno("waitpid","Couldn't wait for subprocess"); + // reset the line buffer + line[0]=0; } + close(_dpkgin); // Restore sig int/quit signal(SIGQUIT,old_SIGQUIT); diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 8bfdff5eb..0b181dc43 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -23,6 +23,13 @@ using std::vector; class pkgDPkgPM : public pkgPackageManager { protected: + + // used for progress reporting + struct DpkgState + { + const char *state; // the dpkg state (e.g. "unpack") + const char *str; // the human readable translation of the state + }; struct Item { @@ -45,7 +52,7 @@ class pkgDPkgPM : public pkgPackageManager virtual bool Install(PkgIterator Pkg,string File); virtual bool Configure(PkgIterator Pkg); virtual bool Remove(PkgIterator Pkg,bool Purge = false); - virtual bool Go(int status_fd=-1); + virtual bool Go(int StatusFd=-1); virtual void Reset(); public: diff --git a/apt-pkg/init.h b/apt-pkg/init.h index 74ac3a7ca..8255b406a 100644 --- a/apt-pkg/init.h +++ b/apt-pkg/init.h @@ -18,7 +18,7 @@ // See the makefile #define APT_PKG_MAJOR 3 -#define APT_PKG_MINOR 5 +#define APT_PKG_MINOR 11 #define APT_PKG_RELEASE 0 extern const char *pkgVersion; diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 8de7d945e..0e6aecc65 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=3.10 +MAJOR=3.11 MINOR=0 SLIBS=$(PTHREADLIB) $(INTLLIBS) APT_DOMAIN:=libapt-pkg$(MAJOR) diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 71a0dd034..87a21004f 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -627,3 +627,15 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() return Completed; } /*}}}*/ +// PM::DoInstall - Does the installation /*{{{*/ +// --------------------------------------------------------------------- +/* This uses the filenames in FileNames and the information in the + DepCache to perform the installation of packages.*/ +pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd) +{ + if(DoInstallPreFork() == Failed) + return Failed; + + return DoInstallPostFork(); +} + /*}}}*/ diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index f95b2ab56..48f53576c 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -83,12 +83,7 @@ class pkgPackageManager : protected pkgCache::Namespace pkgRecords *Recs); // Do the installation - OrderResult DoInstall() { - if(DoInstallPreFork() == Failed) - return Failed; - - return DoInstallPostFork(); - } + OrderResult DoInstall(int statusFd=-1); // stuff that needs to be done before the fork() of a library that // uses apt -- cgit v1.2.3 From 331956f9b59c8c30cce977e8729991559d46005c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 19 Aug 2005 08:50:57 +0000 Subject: * added a InRootSetFunc class for clients to add own packages to the mark'n'sweep root set --- apt-pkg/algorithms.cc | 10 ++++++++-- apt-pkg/algorithms.h | 14 ++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 3978e7561..82ea19c93 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -1342,8 +1342,14 @@ pkgMarkAlwaysInclude(pkgCache::PkgIterator p, vector alwaysMark) return false; } +bool pkgMarkUsed(pkgDepCache &Cache) +{ + InRootSetFunc f; + return pkgMarkUsed(Cache, f); +} + // the main mark algorithm -bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc func) +bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc &userFunc) { bool follow_recommends; bool follow_suggests; @@ -1394,7 +1400,7 @@ bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc func) // do the mark part, this is the core bit of the algorithm for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p) { - if( (func != NULL ? (*func)(p) : false) || + if( userFunc.InRootSet(p) || pkgMarkAlwaysInclude(p, neverAutoRemoveRegexp) || !(Cache[p].Flags & pkgCache::Flag::Auto) || (p->Flags & pkgCache::Flag::Essential)) diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 02b40e15f..e539a410e 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -134,10 +134,16 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache); void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List); -// callback function that can be used by the client to bring in +// class that can be subclassed by the client to bring in // certain own packages into the root set (if the client returns // True the package will be considered as part of the root set) -typedef bool (*InRootSetFunc)(pkgCache::PkgIterator); +class InRootSetFunc +{ + public: + virtual bool InRootSet(const pkgCache::PkgIterator &pkg) {return false;}; + virtual ~InRootSetFunc() {}; +}; + // Mark all reachable packages with "pkgDepCache::StateCache.Marked=1" // the root-set are all essential packages+everything that was not @@ -147,7 +153,7 @@ typedef bool (*InRootSetFunc)(pkgCache::PkgIterator); // is usefull for clients that have there own idea about the root-set // // Everything that is not reach can be removed -bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc f=NULL); - +bool pkgMarkUsed(pkgDepCache &Cache); +bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc &f); #endif -- cgit v1.2.3 From 5d4aff08accfd096d50d99a24df1437a2fa41c8d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 23 Aug 2005 17:45:11 +0000 Subject: * merged the trust-cdrom branch Patches applied: * michael.vogt@ubuntu.com--2005/apt--trust-cdrom--0--base-0 tag of apt@packages.debian.org/apt--main--0--patch-79 * michael.vogt@ubuntu.com--2005/apt--trust-cdrom--0--patch-1 * implemented "TrustCDROM" mode * michael.vogt@ubuntu.com--2005/apt--trust-cdrom--0--patch-2 * added APT::Authentication::TrustCDROM to the configure-index --- apt-pkg/deb/debmetaindex.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 526c8c0b2..85e5b16b3 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -165,6 +165,10 @@ bool debReleaseIndex::IsTrusted() const string VerifiedSigFile = _config->FindDir("Dir::State::lists") + URItoFileName(MetaIndexURI("Release")) + ".gpg"; + if(_config->FindB("APT::Authentication::TrustCDROM", false)) + if(URI.substr(0,strlen("cdrom:")) == "cdrom:") + return true; + if (FileExists(VerifiedSigFile)) return true; return false; -- cgit v1.2.3 From 74a05226eff7041cd8f2380fe599862d350a1ac3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 9 Nov 2005 11:39:27 +0000 Subject: * merged daniel burrows fixes for the auto-mark code Patches applied: * dburrows@debian.org--2005/apt--auto-mark--0--base-0 tag of michael.vogt@ubuntu.com--2005/apt--auto-mark--0--patch-22 * dburrows@debian.org--2005/apt--auto-mark--0--patch-1 doxygenize the new automark stuff * dburrows@debian.org--2005/apt--auto-mark--0--patch-2 Automatically update package markings after every state-changing public operation, and allow users of the dep-cache to group actions into a single action. * dburrows@debian.org--2005/apt--auto-mark--0--patch-3 Automatically update package markings after every state-changing public operation, and allow users of the dep-cache to group actions into a single action. * dburrows@debian.org--2005/apt--auto-mark--0--patch-4 Make action groups noncopyable * dburrows@debian.org--2005/apt--auto-mark--0--patch-5 Typo fix * dburrows@debian.org--2005/apt--auto-mark--0--patch-6 Add a FromUser flag to MarkKeep. * dburrows@debian.org--2005/apt--auto-mark--0--patch-7 Somehow the ActionGroup definition got duplicated; kill the duplicate. * dburrows@debian.org--2005/apt--auto-mark--0--patch-8 Cancel the automatic flag on packages that are being kept only if they are garbage. * dburrows@debian.org--2005/apt--auto-mark--0--patch-9 Don't clear the 'automatically installed' flag in MarkDelete. * dburrows@debian.org--2005/apt--auto-mark--0--patch-10 Add a FromUser flag to MarkInstall, and fix its handling of the Auto flag. * dburrows@debian.org--2005/apt--auto-mark--0--patch-11 Only clear the Auto flag on manual changes in MarkKeep. * dburrows@debian.org--2005/apt--auto-mark--0--patch-12 Make changes from the internal algorithms automatic. * dburrows@debian.org--2005/apt--auto-mark--0--patch-13 Use ActionGroups in algorithms that make lots of changes, and fix a compile error. * dburrows@debian.org--2005/apt--auto-mark--0--patch-14 Split the sweep code into a separate routine from pkgMarkUsed * dburrows@debian.org--2005/apt--auto-mark--0--patch-15 Update another call of MarkKeep to indicate that it's automatic. * dburrows@debian.org--2005/apt--auto-mark--0--patch-16 Move the mark-and-sweep code into pkgDepCache; call Sweep and document what it and Garbage are for; add a hook that can be used to generate a custom root-set function; move the big blob of regexp stuff into the custom root-set; fix the memory leak in the regexp stuff. * dburrows@debian.org--2005/apt--auto-mark--0--patch-17 Make ActionGroup take a reference instead of a pointer to the cache. * dburrows@debian.org--2005/apt--auto-mark--0--patch-18 Don't mark already-to-be-deleted packages as garbage, to imitate aptitude's behavior. * dburrows@debian.org--2005/apt--auto-mark--0--patch-19 Update apt-get for the new auto-mark protocol. * dburrows@debian.org--2005/apt--auto-mark--0--patch-20 Add a setter method for the Auto flag. * dburrows@debian.org--2005/apt--auto-mark--0--patch-21 Fix the test in apt-get about what to delete. * dburrows@debian.org--2005/apt--auto-mark--0--patch-22 Add a zero-argument mark-and-sweep routine and use it to do a mark-and-sweep on startup (so the garbage flags are initialized properly). * dburrows@debian.org--2005/apt--auto-mark--0--patch-23 Right, Status is 2 for new installs, not 0. * dburrows@debian.org--2005/apt--auto-mark--0--patch-24 POT updates. * dburrows@debian.org--2005/apt--auto-mark--0--patch-25 Actually initialize group_level to 0. * dburrows@debian.org--2005/apt--auto-mark--0--patch-26 Don't make an ActionGroup in Sweep, since there's no point and it also is an infinite loop. * dburrows@debian.org--2005/apt--auto-mark--0--patch-27 Add virtual hooks to control whether the garbage collector considers recommends and/or suggests to be strong links. * dburrows@debian.org--2005/apt--auto-mark--0--patch-28 Call the progress methods in the right order so we don't generate nonsensical progress notifications. * dburrows@debian.org--2005/apt--auto-mark--0--patch-29 Typo fix. * dburrows@debian.org--2005/apt--auto-mark--0--patch-30 Make RecommendsImportant default to true in apt, too. * dburrows@debian.org--2005/apt--auto-mark--0--patch-31 Add a release() method to action groups. * dburrows@debian.org--2005/apt--auto-mark--0--patch-32 Add an 'autoremove' command that is synonymous to '--auto-remove remove'. --- apt-pkg/algorithms.cc | 318 +++++++-------------------------------------- apt-pkg/algorithms.h | 23 ---- apt-pkg/depcache.cc | 322 ++++++++++++++++++++++++++++++++++++++++++---- apt-pkg/depcache.h | 212 +++++++++++++++++++++++++++++- apt-pkg/packagemanager.cc | 2 +- 5 files changed, 550 insertions(+), 327 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 82ea19c93..ac9d3be0b 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -20,14 +20,12 @@ #include #include #include -#include #include #include #include #include -#include #include /*}}}*/ using namespace std; @@ -224,6 +222,8 @@ void pkgSimulate::ShortBreaks() the necessary calculations to deal with the problems. */ bool pkgApplyStatus(pkgDepCache &Cache) { + pkgDepCache::ActionGroup group(Cache); + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { if (I->VersionList == 0) @@ -234,13 +234,13 @@ bool pkgApplyStatus(pkgDepCache &Cache) I->InstState == pkgCache::State::HoldReInstReq) { if (I->CurrentVer != 0 && I.CurrentVer().Downloadable() == true) - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); else { // Is this right? Will dpkg choke on an upgrade? if (Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable() == true) - Cache.MarkInstall(I); + Cache.MarkInstall(I, false, 0, false); else return _error->Error(_("The package %s needs to be reinstalled, " "but I can't find an archive for it."),I.Name()); @@ -257,12 +257,12 @@ bool pkgApplyStatus(pkgDepCache &Cache) case pkgCache::State::HalfConfigured: if ((I->CurrentVer != 0 && I.CurrentVer().Downloadable() == true) || I.State() != pkgCache::PkgIterator::NeedsUnpack) - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); else { if (Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable() == true) - Cache.MarkInstall(I); + Cache.MarkInstall(I, true, 0, false); else Cache.MarkDelete(I); } @@ -288,10 +288,12 @@ bool pkgApplyStatus(pkgDepCache &Cache) on the result. */ bool pkgFixBroken(pkgDepCache &Cache) { + pkgDepCache::ActionGroup group(Cache); + // Auto upgrade all broken packages for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) if (Cache[I].NowBroken() == true) - Cache.MarkInstall(I,true); + Cache.MarkInstall(I, true, 0, false); /* Fix packages that are in a NeedArchive state but don't have a downloadable install version */ @@ -304,7 +306,7 @@ bool pkgFixBroken(pkgDepCache &Cache) if (Cache[I].InstVerIter(Cache).Downloadable() == false) continue; - Cache.MarkInstall(I,true); + Cache.MarkInstall(I, true, 0, false); } pkgProblemResolver Fix(&Cache); @@ -321,23 +323,25 @@ bool pkgFixBroken(pkgDepCache &Cache) */ bool pkgDistUpgrade(pkgDepCache &Cache) { + pkgDepCache::ActionGroup group(Cache); + /* Auto upgrade all installed packages, this provides the basis for the installation */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) if (I->CurrentVer != 0) - Cache.MarkInstall(I,true); + Cache.MarkInstall(I, true, 0, false); /* Now, auto upgrade all essential packages - this ensures that the essential packages are present and working */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) - Cache.MarkInstall(I,true); + Cache.MarkInstall(I, true, 0, false); /* We do it again over all previously installed packages to force conflict resolution on them all. */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) if (I->CurrentVer != 0) - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); pkgProblemResolver Fix(&Cache); @@ -349,7 +353,7 @@ bool pkgDistUpgrade(pkgDepCache &Cache) if (I->SelectedState == pkgCache::State::Hold) { Fix.Protect(I); - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); } } } @@ -364,6 +368,8 @@ bool pkgDistUpgrade(pkgDepCache &Cache) to install packages not marked for install */ bool pkgAllUpgrade(pkgDepCache &Cache) { + pkgDepCache::ActionGroup group(Cache); + pkgProblemResolver Fix(&Cache); if (Cache.BrokenCount() != 0) @@ -380,7 +386,7 @@ bool pkgAllUpgrade(pkgDepCache &Cache) continue; if (I->CurrentVer != 0 && Cache[I].InstallVer != 0) - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); } return Fix.ResolveByKeep(); @@ -393,6 +399,8 @@ bool pkgAllUpgrade(pkgDepCache &Cache) the package is restored. */ bool pkgMinimizeUpgrade(pkgDepCache &Cache) { + pkgDepCache::ActionGroup group(Cache); + if (Cache.BrokenCount() != 0) return false; @@ -409,9 +417,9 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache) continue; // Keep it and see if that is OK - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); if (Cache.BrokenCount() != 0) - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); else { // If keep didnt actually do anything then there was no change.. @@ -569,6 +577,8 @@ void pkgProblemResolver::MakeScores() installable */ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) { + pkgDepCache::ActionGroup group(Cache); + if ((Flags[Pkg->ID] & Upgradable) == 0 || Cache[Pkg].Upgradable() == false) return false; if ((Flags[Pkg->ID] & Protected) == Protected) @@ -577,7 +587,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) Flags[Pkg->ID] &= ~Upgradable; bool WasKept = Cache[Pkg].Keep(); - Cache.MarkInstall(Pkg,false); + Cache.MarkInstall(Pkg, false, 0, false); // This must be a virtual package or something like that. if (Cache[Pkg].InstVerIter(Cache).end() == true) @@ -662,7 +672,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) if (Fail == true) { if (WasKept == true) - Cache.MarkKeep(Pkg); + Cache.MarkKeep(Pkg, false, false); else Cache.MarkDelete(Pkg); return false; @@ -689,6 +699,8 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) upgrade packages to advoid problems. */ bool pkgProblemResolver::Resolve(bool BrokenFix) { + pkgDepCache::ActionGroup group(Cache); + unsigned long Size = Cache.Head().PackageCount; // Record which packages are marked for install @@ -704,7 +716,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) { if (Cache[I].InstBroken() == true && BrokenFix == true) { - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); if (Cache[I].Install() == true) Again = true; } @@ -770,14 +782,14 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) pkgCache::Version *OldVer = Cache[I].InstallVer; Flags[I->ID] &= ReInstateTried; - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); if (Cache[I].InstBroken() == true || OldBreaks < Cache.BrokenCount()) { if (OldVer == 0) Cache.MarkDelete(I); else - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); } else if (Debug == true) @@ -822,7 +834,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) { if (Debug == true) clog << " Or group keep for " << I.Name() << endl; - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); Change = true; } } @@ -872,7 +884,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) } Change = true; - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); break; } @@ -909,7 +921,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) /* See if a keep will do, unless the package is protected, then installing it will be necessary */ bool Installed = Cache[I].Install(); - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); if (Cache[I].InstBroken() == false) { // Unwind operation will be keep now @@ -918,7 +930,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) // Restore if (InOr == true && Installed == true) - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); if (Debug == true) clog << " Holding Back " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl; @@ -990,7 +1002,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) // Restore if (InOr == true && Installed == true) - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); if (Debug == true) clog << " Holding Back " << I.Name() << " because I can't find " << Start.TargetPkg().Name() << endl; @@ -1035,7 +1047,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) { if (Debug == true) clog << " Fixing " << I.Name() << " via keep of " << J->Pkg.Name() << endl; - Cache.MarkKeep(J->Pkg); + Cache.MarkKeep(J->Pkg, false, false); } if (Counter > 1) @@ -1089,6 +1101,8 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) system was non-broken previously. */ bool pkgProblemResolver::ResolveByKeep() { + pkgDepCache::ActionGroup group(Cache); + unsigned long Size = Cache.Head().PackageCount; if (Debug == true) @@ -1122,7 +1136,7 @@ bool pkgProblemResolver::ResolveByKeep() { if (Debug == true) clog << "Keeping package " << I.Name() << endl; - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); if (Cache[I].InstBroken() == false) { K = PList - 1; @@ -1170,7 +1184,7 @@ bool pkgProblemResolver::ResolveByKeep() { if (Debug == true) clog << " Keeping Package " << Pkg.Name() << " due to dep" << endl; - Cache.MarkKeep(Pkg); + Cache.MarkKeep(Pkg, false, false); } if (Cache[I].InstBroken() == false) @@ -1207,6 +1221,8 @@ bool pkgProblemResolver::ResolveByKeep() /* This is used to make sure protected packages are installed */ void pkgProblemResolver::InstallProtect() { + pkgDepCache::ActionGroup group(Cache); + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { if ((Flags[I->ID] & Protected) == Protected) @@ -1214,7 +1230,7 @@ void pkgProblemResolver::InstallProtect() if ((Flags[I->ID] & ToRemove) == ToRemove) Cache.MarkDelete(I); else - Cache.MarkInstall(I,false); + Cache.MarkInstall(I, false, 0, false); } } } @@ -1251,247 +1267,3 @@ void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List) } /*}}}*/ - -// mark a single package in Mark-and-Sweep -void pkgMarkPackage(pkgDepCache &Cache, - const pkgCache::PkgIterator &pkg, - const pkgCache::VerIterator &ver, - bool follow_recommends, - bool follow_suggests) -{ - pkgDepCache::StateCache &state=Cache[pkg]; - pkgCache::VerIterator candver=state.CandidateVerIter(Cache); - pkgCache::VerIterator instver=state.InstVerIter(Cache); - -#if 0 - // If a package was garbage-collected but is now being marked, we - // should re-select it - // For cases when a pkg is set to upgrade and this trigger the - // removal of a no-longer used dependency. if the pkg is set to - // keep again later it will result in broken deps - if(state.Delete() && state.RemoveReason=pkgDepCache::Unused) - { - if(ver==candver) - mark_install(pkg, false, false, NULL); - else if(ver==pkg.CurrentVer()) - MarkKeep(pkg); - - instver=state.InstVerIter(*this); - } -#endif - - // Ignore versions other than the InstVer, and ignore packages - // that are already going to be removed or just left uninstalled. - if(!(ver==instver && !instver.end())) - return; - - // if we are marked already we are done - if(state.Marked) - return; - - //std::cout << "Setting Marked for: " << pkg.Name() << std::endl; - state.Marked=true; - - if(!ver.end()) - { - for(pkgCache::DepIterator d=ver.DependsList(); !d.end(); ++d) - { - if(d->Type==pkgCache::Dep::Depends || - d->Type==pkgCache::Dep::PreDepends || - (follow_recommends && - d->Type==pkgCache::Dep::Recommends) || - (follow_suggests && - d->Type==pkgCache::Dep::Suggests)) - { - // Try all versions of this package. - for(pkgCache::VerIterator V=d.TargetPkg().VersionList(); - !V.end(); ++V) - { - if(_system->VS->CheckDep(V.VerStr(),d->CompareOp, d.TargetVer())) - { - pkgMarkPackage(Cache, V.ParentPkg(), V, - follow_recommends, follow_suggests); - } - } - // Now try virtual packages - for(pkgCache::PrvIterator prv=d.TargetPkg().ProvidesList(); - !prv.end(); ++prv) - { - if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp, - d.TargetVer())) - { - pkgMarkPackage(Cache, prv.OwnerPkg(), prv.OwnerVer(), - follow_recommends, follow_suggests); - } - } - } - } - } -} - - -// Helper for APT::NeverAutoRemove, always include the packages matching -// this regexp into the root-set -inline bool -pkgMarkAlwaysInclude(pkgCache::PkgIterator p, vector alwaysMark) -{ - for(unsigned int i=0;iFindB("Debug::pkgAutoRemove",false) - && Cache[p].Flags & pkgCache::Flag::Auto) - std::clog << "AutoDep: " << p.Name() << std::endl; - } - - // init vars - follow_recommends=_config->FindB("APT::AutoRemove::RecommendsImportant",false); - follow_suggests=_config->FindB("APT::AutoRemove::SuggestsImportant", false); - - - // init the "NeverAutoRemove" variable - vector neverAutoRemoveRegexp; - Configuration::Item const *Opts; - Opts = _config->Tree("APT::NeverAutoRemove"); - if (Opts != 0 && Opts->Child != 0) - { - Opts = Opts->Child; - for (; Opts != 0; Opts = Opts->Next) - { - if (Opts->Value.empty() == true) - continue; - - regex_t *p = new regex_t; - if(regcomp(p,Opts->Value.c_str(), - REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0) - { - regfree(p); - for(unsigned int i=0;iError("Regex compilation error for APT::NeverAutoRemove"); - } - neverAutoRemoveRegexp.push_back(p); - } - } - - - // do the mark part, this is the core bit of the algorithm - for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p) - { - if( userFunc.InRootSet(p) || - pkgMarkAlwaysInclude(p, neverAutoRemoveRegexp) || - !(Cache[p].Flags & pkgCache::Flag::Auto) || - (p->Flags & pkgCache::Flag::Essential)) - - { - // the package is installed (and set to keep) - if(Cache[p].Keep() && !p.CurrentVer().end()) - pkgMarkPackage(Cache, p, p.CurrentVer(), - follow_recommends, follow_suggests); - // the package is to be installed - else if(Cache[p].Install()) - pkgMarkPackage(Cache, p, Cache[p].InstVerIter(Cache), - follow_recommends, follow_suggests); - } - } - - - // do the sweep - for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p) - { - pkgDepCache::StateCache &state=Cache[p]; - - // if it is not marked and it is installed, it's garbage - if(!state.Marked && !p.CurrentVer().end()) - { - state.Garbage=true; - if(_config->FindB("Debug::pkgAutoRemove",false)) - std::cout << "Garbage: " << p.Name() << std::endl; - -#if 0 // mvo: the below bits still needs to be ported - - // Be sure not to re-delete already deleted packages. - if(delete_unused && (!p.CurrentVer().end() || state.Install()) && - !state.Delete()) - { - bool do_delete=true; - - // If the package is being upgraded, check if we're - // losing a versioned dep. If the dependency matches - // the previous version and not the new version, keep - // the package back instead of removing it. - if(!p.CurrentVer().end() && state.Install()) - { - const char *vs=p.CurrentVer().VerStr(); - - // Check direct revdeps only. THIS ASSUMES NO - // VERSIONED PROVIDES, but Debian probably won't - // have them for ages if ever. - for(pkgCache::DepIterator revdep=p.RevDependsList(); - !revdep.end(); ++revdep) - { - pkgCache::PkgIterator depender=revdep.ParentPkg(); - // Find which version of the depending package - // will be installed. - pkgCache::VerIterator instver=(*this)[depender].InstVerIter(*this); - - // Only pay attention to strong positive - // dependencies whose parents will be installed. - if(revdep.ParentVer()==instver && - (revdep->Type==pkgCache::Dep::Depends || - revdep->Type==pkgCache::Dep::PreDepends || - (revdep->Type==pkgCache::Dep::Recommends && - follow_recommends))) - { - // If the previous version matched, cancel the - // deletion. (note that I assume that the new - // version does NOT match; otherwise it would - // not be unused!) - if(_system->VS->CheckDep(vs, - revdep->CompareOp, - revdep.TargetVer())) - { - mark_keep(p, false, false, undo); - do_delete=false; - break; - } - } - } - } - - if(do_delete) - mark_delete(p, false, true, undo); - } -#endif - } - } - - // cleanup - for(unsigned int i=0;i #include +#include #include #include #include #include - /*}}}*/ + +pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) : + cache(cache), released(false) +{ + ++cache.group_level; +} + +void pkgDepCache::ActionGroup::release() +{ + if(!released) + { + if(cache.group_level == 0) + std::cerr << "W: Unbalanced action groups, expect badness" << std::endl; + else + { + --cache.group_level; + + if(cache.group_level == 0) + cache.MarkAndSweep(); + } + + released = false; + } +} + +pkgDepCache::ActionGroup::~ActionGroup() +{ + release(); +} // DepCache::pkgDepCache - Constructors /*{{{*/ // --------------------------------------------------------------------- /* */ pkgDepCache::pkgDepCache(pkgCache *pCache,Policy *Plcy) : - Cache(pCache), PkgState(0), DepState(0) + group_level(0), Cache(pCache), PkgState(0), DepState(0) { delLocalPolicy = 0; LocalPolicy = Plcy; @@ -53,6 +82,10 @@ pkgDepCache::~pkgDepCache() /* This allocats the extension buffers and initializes them. */ bool pkgDepCache::Init(OpProgress *Prog) { + // Suppress mark updates during this operation (just in case) and + // run a mark operation when Init terminates. + ActionGroup actions(*this); + delete [] PkgState; delete [] DepState; PkgState = new StateCache[Head().PackageCount]; @@ -100,7 +133,7 @@ bool pkgDepCache::Init(OpProgress *Prog) if(Prog != 0) Prog->Done(); - + return true; } /*}}}*/ @@ -161,7 +194,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog) if(PkgState[pkg->ID].Flags & Flag::Auto) { if(_config->FindB("Debug::pkgAutoRemove",false)) - std::clog << "AutoInstal: " << pkg.Name() << std::endl; + std::clog << "AutoInstall: " << pkg.Name() << std::endl; ostr.str(string("")); ostr << "Package: " << pkg.Name() << "\nAuto-Installed: 1\n\n"; @@ -522,16 +555,16 @@ void pkgDepCache::Update(OpProgress *Prog) AddStates(I); } - readStateFile(Prog); - if (Prog != 0) Prog->Progress(Done); + + readStateFile(Prog); } /*}}}*/ // DepCache::Update - Update the deps list of a package /*{{{*/ // --------------------------------------------------------------------- /* This is a helper for update that only does the dep portion of the scan. - It is mainly ment to scan reverse dependencies. */ + It is mainly meant to scan reverse dependencies. */ void pkgDepCache::Update(DepIterator D) { // Update the reverse deps @@ -583,7 +616,7 @@ void pkgDepCache::Update(PkgIterator const &Pkg) // DepCache::MarkKeep - Put the package in the keep state /*{{{*/ // --------------------------------------------------------------------- /* */ -void pkgDepCache::MarkKeep(PkgIterator const &Pkg,bool Soft) +void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser) { // Simplifies other routines. if (Pkg.end() == true) @@ -595,6 +628,9 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg,bool Soft) Pkg.CurrentVer().Downloadable() == false) return; + /** \todo Can this be moved later in the method? */ + ActionGroup group(*this); + /* We changed the soft state all the time so the UI is a bit nicer to use */ StateCache &P = PkgState[Pkg->ID]; @@ -611,7 +647,8 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg,bool Soft) if (Pkg->VersionList == 0) return; - P.Flags &= ~Flag::Auto; + if(FromUser && !P.Marked) + P.Flags &= ~Flag::Auto; RemoveSizes(Pkg); RemoveStates(Pkg); @@ -637,6 +674,8 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge) if (Pkg.end() == true) return; + ActionGroup group(*this); + // Check that it is not already marked for delete StateCache &P = PkgState[Pkg->ID]; P.iFlags &= ~(AutoKept | Purge); @@ -659,8 +698,6 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge) else P.Mode = ModeDelete; P.InstallVer = 0; - // This was not inverted before, but I think it should be - P.Flags &= ~Flag::Auto; AddStates(Pkg); Update(Pkg); @@ -671,7 +708,7 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge) // --------------------------------------------------------------------- /* */ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, - unsigned long Depth) + unsigned long Depth, bool FromUser) { if (Depth > 100) return; @@ -680,6 +717,8 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, if (Pkg.end() == true) return; + ActionGroup group(*this); + /* Check that it is not already marked for install and that it can be installed */ StateCache &P = PkgState[Pkg->ID]; @@ -688,7 +727,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); + MarkKeep(Pkg, false, FromUser); return; } @@ -708,9 +747,20 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, P.Mode = ModeInstall; P.InstallVer = P.CandidateVer; - // invert the auto-flag only for new installs, not for upgrades - if(P.Status == 0) - P.Flags &= ~Flag::Auto; + + if(FromUser) + { + // Set it to manual if it's a new install or cancelling the + // removal of a garbage package. + if(P.Status == 2 || (!Pkg.CurrentVer().end() && !P.Marked)) + P.Flags &= ~Flag::Auto; + } + else + { + // Set it to auto if this is a new install. + if(P.Status == 2) + P.Flags |= Flag::Auto; + } if (P.CandidateVer == (Version *)Pkg.CurrentVer()) P.Mode = ModeKeep; @@ -788,13 +838,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, } if (InstPkg.end() == false) - { - MarkInstall(InstPkg,true,Depth + 1); - - // Set the autoflag, after MarkInstall because MarkInstall unsets it - if (P->CurrentVer == 0) - PkgState[InstPkg->ID].Flags |= Flag::Auto; - } + MarkInstall(InstPkg, true, Depth + 1, false); continue; } @@ -809,7 +853,6 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, PkgIterator Pkg = Ver.ParentPkg(); MarkDelete(Pkg); - PkgState[Pkg->ID].Flags |= Flag::Auto; } continue; } @@ -821,6 +864,8 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, /* */ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To) { + ActionGroup group(*this); + RemoveSizes(Pkg); RemoveStates(Pkg); @@ -839,9 +884,11 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To) /* */ void pkgDepCache::SetCandidateVersion(VerIterator TargetVer) { + ActionGroup group(*this); + pkgCache::PkgIterator Pkg = TargetVer.ParentPkg(); StateCache &P = PkgState[Pkg->ID]; - + RemoveSizes(Pkg); RemoveStates(Pkg); @@ -854,6 +901,18 @@ void pkgDepCache::SetCandidateVersion(VerIterator TargetVer) Update(Pkg); AddSizes(Pkg); } + +void pkgDepCache::MarkAuto(const PkgIterator &Pkg, bool Auto) +{ + StateCache &state = PkgState[Pkg->ID]; + + ActionGroup group(*this); + + if(Auto) + state.Flags |= Flag::Auto; + else + state.Flags &= ~Flag::Auto; +} /*}}}*/ // StateCache::Update - Compute the various static display things /*{{{*/ // --------------------------------------------------------------------- @@ -944,3 +1003,216 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep) return Dep.IsCritical(); } /*}}}*/ + +pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc() + : constructedSuccessfully(false) +{ + Configuration::Item const *Opts; + Opts = _config->Tree("APT::NeverAutoRemove"); + if (Opts != 0 && Opts->Child != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + + regex_t *p = new regex_t; + if(regcomp(p,Opts->Value.c_str(), + REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0) + { + regfree(p); + delete p; + _error->Error("Regex compilation error for APT::NeverAutoRemove"); + return; + } + + rootSetRegexp.push_back(p); + } + } + + constructedSuccessfully = true; +} + +pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc() +{ + for(unsigned int i = 0; i < rootSetRegexp.size(); i++) + { + regfree(rootSetRegexp[i]); + delete rootSetRegexp[i]; + } +} + + +bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg) +{ + for(unsigned int i = 0; i < rootSetRegexp.size(); i++) + if (regexec(rootSetRegexp[i], pkg.Name(), 0, 0, 0) == 0) + return true; + + return false; +} + +pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc() +{ + DefaultRootSetFunc *f = new DefaultRootSetFunc; + if(f->wasConstructedSuccessfully()) + return f; + else + { + delete f; + return NULL; + } +} + +bool pkgDepCache::MarkFollowsRecommends() +{ + return _config->FindB("APT::AutoRemove::RecommendsImportant", true); +} + +bool pkgDepCache::MarkFollowsSuggests() +{ + return _config->FindB("APT::AutoRemove::SuggestsImportant", false); +} + +// the main mark algorithm +bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) +{ + bool follow_recommends; + bool follow_suggests; + + // init the states + for(PkgIterator p = PkgBegin(); !p.end(); ++p) + { + PkgState[p->ID].Marked = false; + PkgState[p->ID].Garbage = false; + + // debug output + if(_config->FindB("Debug::pkgAutoRemove",false) + && PkgState[p->ID].Flags & Flag::Auto) + std::clog << "AutoDep: " << p.Name() << std::endl; + } + + // init vars + follow_recommends = MarkFollowsRecommends(); + follow_suggests = MarkFollowsSuggests(); + + + + // do the mark part, this is the core bit of the algorithm + for(PkgIterator p = PkgBegin(); !p.end(); ++p) + { + if(!(PkgState[p->ID].Flags & Flag::Auto) || + (p->Flags & Flag::Essential) || + userFunc.InRootSet(p)) + + { + // the package is installed (and set to keep) + if(PkgState[p->ID].Keep() && !p.CurrentVer().end()) + MarkPackage(p, p.CurrentVer(), + follow_recommends, follow_suggests); + // the package is to be installed + else if(PkgState[p->ID].Install()) + MarkPackage(p, PkgState[p->ID].InstVerIter(*this), + follow_recommends, follow_suggests); + } + } + + return true; +} + +// mark a single package in Mark-and-Sweep +void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg, + const pkgCache::VerIterator &ver, + bool follow_recommends, + bool follow_suggests) +{ + pkgDepCache::StateCache &state = PkgState[pkg->ID]; + VerIterator candver = state.CandidateVerIter(*this); + VerIterator instver = state.InstVerIter(*this); + +#if 0 + // If a package was garbage-collected but is now being marked, we + // should re-select it + // For cases when a pkg is set to upgrade and this trigger the + // removal of a no-longer used dependency. if the pkg is set to + // keep again later it will result in broken deps + if(state.Delete() && state.RemoveReason = Unused) + { + if(ver==candver) + mark_install(pkg, false, false, NULL); + else if(ver==pkg.CurrentVer()) + MarkKeep(pkg, false, false); + + instver=state.InstVerIter(*this); + } +#endif + + // Ignore versions other than the InstVer, and ignore packages + // that are already going to be removed or just left uninstalled. + if(!(ver == instver && !instver.end())) + return; + + // if we are marked already we are done + if(state.Marked) + return; + + //std::cout << "Setting Marked for: " << pkg.Name() << std::endl; + state.Marked=true; + + if(!ver.end()) + { + for(DepIterator d = ver.DependsList(); !d.end(); ++d) + { + if(d->Type == Dep::Depends || + d->Type == Dep::PreDepends || + (follow_recommends && + d->Type == Dep::Recommends) || + (follow_suggests && + d->Type == Dep::Suggests)) + { + // Try all versions of this package. + for(VerIterator V = d.TargetPkg().VersionList(); + !V.end(); ++V) + { + if(_system->VS->CheckDep(V.VerStr(), d->CompareOp, d.TargetVer())) + { + MarkPackage(V.ParentPkg(), V, + follow_recommends, follow_suggests); + } + } + // Now try virtual packages + for(PrvIterator prv=d.TargetPkg().ProvidesList(); + !prv.end(); ++prv) + { + if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp, + d.TargetVer())) + { + MarkPackage(prv.OwnerPkg(), prv.OwnerVer(), + follow_recommends, follow_suggests); + } + } + } + } + } +} + +bool pkgDepCache::Sweep() +{ + // do the sweep + for(PkgIterator p=PkgBegin(); !p.end(); ++p) + { + StateCache &state=PkgState[p->ID]; + + // if it is not marked and it is installed, it's garbage + if(!state.Marked && (!p.CurrentVer().end() || state.Install()) && + !state.Delete()) + { + state.Garbage=true; + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::cout << "Garbage: " << p.Name() << std::endl; + } + } + + return true; +} diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 619daf8f6..fd935c268 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -1,4 +1,4 @@ -// -*- mode: cpp; mode: fold -*- +// -*- mode: c++; mode: fold -*- // Description /*{{{*/ // $Id: depcache.h,v 1.14 2001/02/20 07:03:17 jgg Exp $ /* ###################################################################### @@ -45,9 +45,71 @@ #include #include +#include + +#include + class pkgDepCache : protected pkgCache::Namespace { public: + + /** \brief An arbitrary predicate on packages. */ + class InRootSetFunc + { + public: + virtual bool InRootSet(const pkgCache::PkgIterator &pkg) {return false;}; + virtual ~InRootSetFunc() {}; + }; + + private: + /** \brief Mark a single package and all its unmarked important + * dependencies during mark-and-sweep. + * + * Recursively invokes itself to mark all dependencies of the + * package. + * + * \param pkg The package to mark. + * + * \param ver The version of the package that is to be marked. + * + * \param follow_recommends If \b true, recommendations of the + * package will be recursively marked. + * + * \param follow_suggests If \b true, suggestions of the package + * will be recursively marked. + */ + void MarkPackage(const pkgCache::PkgIterator &pkg, + const pkgCache::VerIterator &ver, + bool follow_recommends, + bool follow_suggests); + + /** \brief Update the Marked field of all packages. + * + * Each package's StateCache::Marked field will be set to \b true + * if and only if it can be reached from the root set. By + * default, the root set consists of the set of manually installed + * or essential packages, but it can be extended using the + * parameter #rootFunc. + * + * \param rootFunc A callback that can be used to add extra + * packages to the root set. + * + * \return \b false if an error occured. + */ + bool MarkRequired(InRootSetFunc &rootFunc); + + /** \brief Set the StateCache::Garbage flag on all packages that + * should be removed. + * + * Packages that were not marked by the last call to #MarkRequired + * are tested to see whether they are actually garbage. If so, + * they are marked as such. + * + * \return \b false if an error occured. + */ + bool Sweep(); + + public: // These flags are used in DepState enum DepFlags {DepNow = (1 << 0),DepInstall = (1 << 1),DepCVer = (1 << 2), @@ -64,6 +126,83 @@ class pkgDepCache : protected pkgCache::Namespace enum VersionTypes {NowVersion, InstallVersion, CandidateVersion}; enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2}; + /** \brief Represents an active action group. + * + * An action group is a group of actions that are currently being + * performed. While an active group is active, certain routine + * clean-up actions that would normally be performed after every + * cache operation are delayed until the action group is + * completed. This is necessary primarily to avoid inefficiencies + * when modifying a large number of packages at once. + * + * This class represents an active action group. Creating an + * instance will create an action group; destroying one will + * destroy the corresponding action group. + * + * The following operations are suppressed by this class: + * + * - Keeping the Marked and Garbage flags up to date. + * + * \note This can be used in the future to easily accumulate + * atomic actions for undo or to display "what apt did anyway"; + * e.g., change the counter of how many action groups are active + * to a std::set of pointers to them and use those to store + * information about what happened in a group in the group. + */ + class ActionGroup + { + pkgDepCache &cache; + + bool released; + + /** Action groups are noncopyable. */ + ActionGroup(const ActionGroup &other); + public: + /** \brief Create a new ActionGroup. + * + * \param cache The cache that this ActionGroup should + * manipulate. + * + * As long as this object exists, no automatic cleanup + * operations will be undertaken. + */ + ActionGroup(pkgDepCache &cache); + + /** \brief Clean up the action group before it is destroyed. + * + * If it is destroyed later, no second cleanup wil be run. + */ + void release(); + + /** \brief Destroy the action group. + * + * If this is the last action group, the automatic cache + * cleanup operations will be undertaken. + */ + ~ActionGroup(); + }; + + /** \brief Returns \b true for packages matching a regular + * expression in APT::NeverAutoRemove. + */ + class DefaultRootSetFunc : public InRootSetFunc + { + std::vector rootSetRegexp; + bool constructedSuccessfully; + + public: + DefaultRootSetFunc(); + ~DefaultRootSetFunc(); + + /** \return \b true if the class initialized successfully, \b + * false otherwise. Used to avoid throwing an exception, since + * APT classes generally don't. + */ + bool wasConstructedSuccessfully() const { return constructedSuccessfully; } + + bool InRootSet(const pkgCache::PkgIterator &pkg); + }; + struct StateCache { // Epoch stripped text versions of the two version fields @@ -80,8 +219,15 @@ class pkgDepCache : protected pkgCache::Namespace unsigned short Flags; unsigned short iFlags; // Internal flags - // mark and sweep flags + /** \brief \b true if this package can be reached from the root set. */ bool Marked; + + /** \brief \b true if this package is unused and should be removed. + * + * This differs from !#Marked, because it is possible that some + * unreachable packages will be protected from becoming + * garbage. + */ bool Garbage; // Various tree indicators @@ -124,6 +270,14 @@ class pkgDepCache : protected pkgCache::Namespace virtual ~Policy() {}; }; + + private: + /** The number of open "action groups"; certain post-action + * operations are suppressed if this number is > 0. + */ + int group_level; + + friend class ActionGroup; protected: @@ -187,13 +341,61 @@ class pkgDepCache : protected pkgCache::Namespace inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];}; inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];}; - // Manipulators - void MarkKeep(PkgIterator const &Pkg,bool Soft = false); + /** \return A function identifying packages in the root set other + * than manually installed packages and essential packages, or \b + * NULL if an error occurs. + * + * \todo Is this the best place for this function? Perhaps the + * settings for mark-and-sweep should be stored in a single + * external class? + */ + virtual InRootSetFunc *GetRootSetFunc(); + + /** \return \b true if the garbage collector should follow recommendations. + */ + virtual bool MarkFollowsRecommends(); + + /** \return \b true if the garbage collector should follow suggestions. + */ + virtual bool MarkFollowsSuggests(); + + /** \brief Update the Marked and Garbage fields of all packages. + * + * This routine is implicitly invoked after all state manipulators + * and when an ActionGroup is destroyed. It invokes #MarkRequired + * and #Sweep to do its dirty work. + * + * \param rootFunc A predicate that returns \b true for packages + * that should be added to the root set. + */ + bool MarkAndSweep(InRootSetFunc &rootFunc) + { + return MarkRequired(rootFunc) && Sweep(); + } + + bool MarkAndSweep() + { + std::auto_ptr f(GetRootSetFunc()); + if(f.get() != NULL) + return MarkAndSweep(*f.get()); + else + return false; + } + + /** \name State Manipulators + */ + // @{ + void MarkKeep(PkgIterator const &Pkg, bool Soft = false, + bool FromUser = true); void MarkDelete(PkgIterator const &Pkg,bool Purge = false); void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true, - unsigned long Depth = 0); + unsigned long Depth = 0, bool FromUser = true); void SetReInstall(PkgIterator const &Pkg,bool To); void SetCandidateVersion(VerIterator TargetVer); + + /** Set the "is automatically installed" flag of Pkg. */ + void MarkAuto(const PkgIterator &Pkg, bool Auto); + // @} // This is for debuging void Update(OpProgress *Prog = 0); diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 87a21004f..05615db79 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -106,7 +106,7 @@ bool pkgPackageManager::FixMissing() // Okay, this file is missing and we need it. Mark it for keep Bad = true; - Cache.MarkKeep(I); + Cache.MarkKeep(I, false, false); } // We have to empty the list otherwise it will not have the new changes -- cgit v1.2.3 From 7a6058744badb38d2ccac0158d6ed1359cfb0239 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 8 Dec 2005 17:29:42 +0000 Subject: * merged with the current debian version Patches applied: * bubulle@debian.org--2005/apt--main--0--patch-132 Completed Simplified Chinese translation * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-94 * pkgDirStream has (slightly) better extract support now * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-95 * merge fix for #339533 * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-96 * merged with bubulle * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-97 * some more debug output * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-98 * ABI change: merged more flexible pkgAcquireFile code * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-99 * merged http download limit for apt (#146877) * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-100 * applied parts of the string speedup patch from debian #319377 (ABI change) * michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-101 * fix for #340448 --- apt-pkg/acquire-item.cc | 15 ++++++++------- apt-pkg/acquire-item.h | 5 +++-- apt-pkg/algorithms.h | 3 ++- apt-pkg/cacheiterators.h | 4 +++- apt-pkg/cdrom.cc | 3 +++ apt-pkg/deb/debsystem.cc | 7 ++++++- 6 files changed, 25 insertions(+), 12 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 09f25c0dd..88c25de43 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -142,20 +142,21 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, { Decompression = false; Erase = false; - + DestFile = _config->FindDir("Dir::State::lists") + "partial/"; DestFile += URItoFileName(URI); if(comprExt.empty()) { - // autoselect - if(FileExists("/usr/bin/bzip2")) - Desc.URI = URI + ".bz2"; - else - Desc.URI = URI + ".gz"; + // autoselect the compression method + if(FileExists("/usr/bin/bzip2")) + CompressionExtension = ".bz2"; + else + CompressionExtension = ".gz"; } else { - Desc.URI = URI + comprExt; + CompressionExtension = comprExt; } + Desc.URI = URI + CompressionExtension; Desc.Description = URIDesc; Desc.Owner = this; diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index 9e7198d8d..c34b5ef69 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -92,7 +92,8 @@ class pkgAcqIndex : public pkgAcquire::Item pkgAcquire::ItemDesc Desc; string RealURI; string ExpectedMD5; - + string CompressionExtension; + public: // Specialized action members @@ -100,7 +101,7 @@ class pkgAcqIndex : public pkgAcquire::Item virtual void Done(string Message,unsigned long Size,string Md5Hash, pkgAcquire::MethodConfig *Cnf); virtual string Custom600Headers(); - virtual string DescURI() {return RealURI + ".gz";}; + virtual string DescURI() {return RealURI + CompressionExtension;}; pkgAcqIndex(pkgAcquire *Owner,string URI,string URIDesc, string ShortDesct, string ExpectedMD5, string compressExt=""); diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 174a7f58d..b95218061 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -118,7 +118,8 @@ class pkgProblemResolver // Try to resolve problems only by using keep bool ResolveByKeep(); - + + // Install all protected packages void InstallProtect(); pkgProblemResolver(pkgDepCache *Cache); diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 7c6f43351..2b326bd65 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -222,7 +222,7 @@ class pkgCache::PrvIterator void operator ++(int) {if (Prv != Owner->ProvideP) Prv = Owner->ProvideP + (Type == PrvVer?Prv->NextPkgProv:Prv->NextProvides);}; inline void operator ++() {operator ++(0);}; - inline bool end() const {return Prv == Owner->ProvideP?true:false;}; + inline bool end() const {return Owner == 0 || Prv == Owner->ProvideP?true:false;}; // Comparison inline bool operator ==(const PrvIterator &B) const {return Prv == B.Prv;}; @@ -244,6 +244,8 @@ class pkgCache::PrvIterator inline PkgIterator OwnerPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Prv->Version].ParentPkg);}; inline unsigned long Index() const {return Prv - Owner->ProvideP;}; + inline PrvIterator() : Prv(0), Type(PrvVer), Owner(0) {}; + inline PrvIterator(pkgCache &Owner,Provides *Trg,Version *) : Prv(Trg), Type(PrvVer), Owner(&Owner) { diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc index d7ef844a2..ce1beb39b 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -422,6 +422,9 @@ bool pkgCdrom::WriteSourceList(string Name,vector &List,bool Source) { F.getline(Buffer,sizeof(Buffer)); CurLine++; + if (F.fail() && !F.eof()) + return _error->Error(_("Line %u too long in source list %s."), + CurLine,File.c_str()); _strtabexpand(Buffer,sizeof(Buffer)); _strstrip(Buffer); diff --git a/apt-pkg/deb/debsystem.cc b/apt-pkg/deb/debsystem.cc index 0b3a4f742..2d805ea6f 100644 --- a/apt-pkg/deb/debsystem.cc +++ b/apt-pkg/deb/debsystem.cc @@ -164,7 +164,12 @@ bool debSystem::Initialize(Configuration &Cnf) Cnf.CndSet("Dir::State::userstatus","status.user"); // Defunct Cnf.CndSet("Dir::State::status","/var/lib/dpkg/status"); Cnf.CndSet("Dir::Bin::dpkg","/usr/bin/dpkg"); - + + if (StatusFile) { + delete StatusFile; + StatusFile = 0; + } + return true; } /*}}}*/ -- cgit v1.2.3 From 47eb38f452c7477aab782dce56e85a0a85e22764 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 21 Feb 2006 12:23:22 +0000 Subject: * handle network failures more gracefully (default apt sources spec) apt-pkg/acquire-item.cc: - on network failures (Timeout,ResolveFailure,ConnectionRefused) move the old (known good) sigfile back and don't touch the indexfiles cmdline/apt-get.cc: - don't fail on apt-get update problems but issue a warning instead --- apt-pkg/acquire-item.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 1fa929aad..dee00c63e 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -321,8 +321,9 @@ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, DestFile = _config->FindDir("Dir::State::lists") + "partial/"; DestFile += URItoFileName(URI); - // remove any partial downloaded sig-file. it may confuse proxies - // and is too small to warrant a partial download anyway + // remove any partial downloaded sig-file in partial/. + // it may confuse proxies and is too small to warrant a + // partial download anyway unlink(DestFile.c_str()); // Create the item @@ -389,17 +390,20 @@ void pkgAcqMetaSig::Done(string Message,unsigned long Size,string MD5, /*}}}*/ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) { + string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI); // if we get a network error we fail gracefully if(LookupTag(Message,"FailReason") == "Timeout" || LookupTag(Message,"FailReason") == "TmpResolveFailure" || LookupTag(Message,"FailReason") == "ConnectionRefused") { Item::Failed(Message,Cnf); + // move the sigfile back on network failures (and re-authenticated?) + if(FileExists(DestFile)) + Rename(DestFile,Final); return; } // Delete any existing sigfile when the acquire failed - string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI); unlink(Final.c_str()); // queue a pkgAcqMetaIndex with no sigfile -- cgit v1.2.3 From a791a45008c6fb5d85061da5f7c90b9ef7d28f81 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 21 Feb 2006 13:04:57 +0000 Subject: * don't print a "can't stat " message for missing index files (DefaultSourcesSpec) --- apt-pkg/pkgcachegen.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index de854bee5..de5ba5ea6 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -571,8 +571,10 @@ static bool CheckValidity(const string &CacheFile, FileIterator Start, if ((*Start)->Exists() == false) { +#if 0 // mvo: we no longer give a message here (Default Sources spec) _error->WarningE("stat",_("Couldn't stat source package list %s"), (*Start)->Describe().c_str()); +#endif continue; } -- cgit v1.2.3 From 7e5f33eb8a0f224b938f17236f684ba5cadb9c7f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 21 Feb 2006 16:39:25 +0000 Subject: * more work for the DefaultAptSources spec apt-pkg/acquire-item.h: - add new pkgAcquire::Item::StatTransientNetworkError status apt-pkg/acquire-item.cc: - if we get a StatTransientNetworkError use old sigfile and indexfiles apt-pkg/acquire-worker.cc: - set StatTransientNetworkError on "Timeout", "TmpResolveFailure", "ConnectionRefused" cmdline/apt-get.cc: - handle a StatTransientNetworkError different than a normal error (warning instead of error) --- apt-pkg/acquire-item.cc | 10 ++++++---- apt-pkg/acquire-item.h | 3 ++- apt-pkg/acquire-worker.cc | 7 +++++++ 3 files changed, 15 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index dee00c63e..da9becc44 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -75,7 +75,7 @@ void pkgAcquire::Item::Failed(string Message,pkgAcquire::MethodConfig *Cnf) Dequeue(); return; } - + Status = StatError; Dequeue(); } @@ -393,13 +393,15 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI); // if we get a network error we fail gracefully - if(LookupTag(Message,"FailReason") == "Timeout" || - LookupTag(Message,"FailReason") == "TmpResolveFailure" || - LookupTag(Message,"FailReason") == "ConnectionRefused") { + if(Status == StatTransientNetworkError) + { Item::Failed(Message,Cnf); // move the sigfile back on network failures (and re-authenticated?) if(FileExists(DestFile)) Rename(DestFile,Final); + + // set the status back to , Item::Failed likes to reset it + Status = pkgAcquire::Item::StatTransientNetworkError; return; } diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index da1bea801..1c83f8d2e 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -48,7 +48,8 @@ class pkgAcquire::Item public: // State of the item - enum {StatIdle, StatFetching, StatDone, StatError, StatAuthError} Status; + enum {StatIdle, StatFetching, StatDone, StatError, + StatAuthError, StatTransientNetworkError} Status; string ErrorText; unsigned long FileSize; unsigned long PartialSize; diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc index d06024178..8ab67778b 100644 --- a/apt-pkg/acquire-worker.cc +++ b/apt-pkg/acquire-worker.cc @@ -307,6 +307,13 @@ bool pkgAcquire::Worker::RunMessages() pkgAcquire::Item *Owner = Itm->Owner; pkgAcquire::ItemDesc Desc = *Itm; OwnerQ->ItemDone(Itm); + + // set some status + if(LookupTag(Message,"FailReason") == "Timeout" || + LookupTag(Message,"FailReason") == "TmpResolveFailure" || + LookupTag(Message,"FailReason") == "ConnectionRefused") + Owner->Status = pkgAcquire::Item::StatTransientNetworkError; + Owner->Failed(Message,Config); ItemDone(); -- cgit v1.2.3 From 6627bdccce46a9acdae09d37e6e1444a5f7384e1 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 18 Apr 2006 13:25:13 +0200 Subject: * wording fixes (cherry picked from apt--mvo) --- apt-pkg/deb/dpkgpm.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index fe8fbca74..3b7b2238a 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -375,8 +375,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) }, // Purge operation { - {"config-files", _("Preparing for remove with config %s")}, - {"not-installed", _("Removed with config %s")}, + {"config-files", _("Preparing to completely remove %s")}, + {"not-installed", _("Completely removed %s")}, {NULL, NULL} }, }; -- cgit v1.2.3 From 60681f9354217c830943315951e6559253bfa832 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 2 May 2006 09:44:30 +0200 Subject: * depcache.cc: - added APT::Install-{Recommends,Suggests} global option * depcache.h: - added DepCache::State::InstPolicyBroken() to check if the current install state violates the policy (compated with InstBroken() that only checks for the minimal requirements) --- apt-pkg/depcache.cc | 16 +++++++++++----- apt-pkg/depcache.h | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index dd1c794c9..589fc2f7d 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -16,7 +16,7 @@ #include #include #include - +#include #include /*}}}*/ @@ -609,7 +609,8 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, installed */ StateCache &P = PkgState[Pkg->ID]; P.iFlags &= ~AutoKept; - if (P.InstBroken() == false && (P.Mode == ModeInstall || + if ((P.InstPolicyBroken() == false && P.InstBroken() == false) && + (P.Mode == ModeInstall || P.CandidateVer == (Version *)Pkg.CurrentVer())) { if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0) @@ -620,11 +621,9 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, // See if there is even any possible instalation candidate if (P.CandidateVer == 0) return; - // We dont even try to install virtual packages.. if (Pkg->VersionList == 0) return; - /* Target the candidate version and remove the autoflag. We reset the autoflag below if this was called recursively. Otherwise the user should have the ability to de-auto a package by changing its state */ @@ -864,6 +863,13 @@ pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg) /* */ bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep) { - return Dep.IsCritical(); + if(Dep.IsCritical()) + return true; + else if(Dep->Type == pkgCache::Dep::Recommends) + return _config->FindB("APT::Install-Recommends", false); + else if(Dep->Type == pkgCache::Dep::Suggests) + return _config->FindB("APT::Install-Suggests", false); + + return false; } /*}}}*/ diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 6d51920e9..3f9f67140 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -98,6 +98,7 @@ class pkgDepCache : protected pkgCache::Namespace inline bool Held() const {return Status != 0 && Keep();}; inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;}; inline bool InstBroken() const {return (DepState & DepInstMin) != DepInstMin;}; + inline bool InstPolicyBroken() const {return (DepState & DepInstPolicy) != DepInstPolicy;}; inline bool Install() const {return Mode == ModeInstall;}; inline VerIterator InstVerIter(pkgCache &Cache) {return VerIterator(Cache,InstallVer);}; -- cgit v1.2.3 From e0c4f06387ade5761e644b5b96e41284c12da23c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 6 Jun 2006 19:20:28 +0200 Subject: * apt-pkg/indexfile.cc: - add special cases for various languages like pt_BR, zh_CN etc --- apt-pkg/indexfile.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/indexfile.cc b/apt-pkg/indexfile.cc index 496e68b8b..bb2210bf6 100644 --- a/apt-pkg/indexfile.cc +++ b/apt-pkg/indexfile.cc @@ -113,11 +113,14 @@ string pkgIndexFile::LanguageCode() { string lang = std::setlocale(LC_MESSAGES,NULL); - // FIXME: this needs to be added // we have a mapping of the language codes that contains all the language // codes that need the country code as well // (like pt_BR, pt_PT, sv_SE, zh_*, en_*) - + char *need_full_langcode[] = { "pt","sv","zh","en", NULL }; + for(char **s = need_full_langcode;*s != NULL; s++) + if(lang.find(*s) == 0) + return lang.substr(0,5); + if(lang.size() > 2) return lang.substr(0,2); else -- cgit v1.2.3 From dfa8d6b21806c76df2e53555c577e8d2029186c4 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 7 Jun 2006 08:54:29 +0200 Subject: * apt-pkg/tagfile.cc: - fix merge bug --- apt-pkg/tagfile.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 2eb269418..fc020436c 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -35,7 +35,7 @@ pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long Size) : Fd(*pFd), Size(Size) { - if (Fd.IsOpen() == false || Fd.Size()) + if (Fd.IsOpen() == false || Fd.Size() == 0) { Buffer = 0; Start = End = Buffer = 0; -- cgit v1.2.3 From aac2e51078714d5130861035e9b3b5d4d6b84471 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 26 Jun 2006 06:33:22 +0200 Subject: * apt-pkg/depcache.cc: - renamed "pkgstates" file to "extended_states" --- apt-pkg/depcache.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 6eb6c1d85..4e9488121 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -142,7 +142,7 @@ bool pkgDepCache::Init(OpProgress *Prog) bool pkgDepCache::readStateFile(OpProgress *Prog) { FileFd state_file; - string state = _config->FindDir("Dir::State") + "pkgstates"; + string state = _config->FindDir("Dir::State") + "extended_states"; if(FileExists(state)) { state_file.Open(state, FileFd::ReadOnly); int file_size = state_file.Size(); @@ -181,7 +181,7 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) bool pkgDepCache::writeStateFile(OpProgress *prog) { FileFd StateFile; - string state = _config->FindDir("Dir::State") + "pkgstates"; + string state = _config->FindDir("Dir::State") + "extended_states"; if(_config->FindB("Debug::pkgAutoRemove",false)) std::clog << "pkgDepCache::writeStateFile()" << std::endl; -- cgit v1.2.3 From b1a8717ae8e07101cfae03b978d57b793884a3d9 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 26 Jun 2006 09:17:05 +0200 Subject: * cmdline/apt-mark: - very simple tool to manipulate the extended_states for autoinstall * apt-pkg/depcache.cc: - keep exisiting data in "extended_states" to make other tools happy --- apt-pkg/depcache.cc | 62 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 9 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 4e9488121..7663d3881 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -24,6 +24,7 @@ #include #include +#include #include @@ -180,28 +181,71 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) bool pkgDepCache::writeStateFile(OpProgress *prog) { - FileFd StateFile; - string state = _config->FindDir("Dir::State") + "extended_states"; - if(_config->FindB("Debug::pkgAutoRemove",false)) std::clog << "pkgDepCache::writeStateFile()" << std::endl; - if(!StateFile.Open(state, FileFd::WriteEmpty)) - return _error->Error(_("Failed to write StateFile %s"), + FileFd StateFile; + string state = _config->FindDir("Dir::State") + "extended_states"; + if(!StateFile.Open(state, FileFd::ReadOnly)) + return _error->Error(_("Failed to open StateFile %s"), state.c_str()); + FILE *OutFile; + string outfile = state + ".tmp"; + if((OutFile = fopen(outfile.c_str(),"w")) == NULL) + return _error->Error(_("Failed to write temporary StateFile %s"), + outfile.c_str()); + + // first merge with the existing sections + pkgTagFile tagfile(&StateFile); + pkgTagSection section; + std::set pkgs_seen; + const char *nullreorderlist[] = {0}; + while(tagfile.Step(section)) { + string pkgname = section.FindS("Package"); + // Silently ignore unknown packages and packages with no actual + // version. + pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname); + if(pkg.end() || pkg.VersionList().end()) + continue; + bool oldAuto = section.FindI("Auto-Installed"); + bool newAuto = (PkgState[pkg->ID].Flags & Flag::Auto); + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::clog << "Update exisiting AutoInstall info: " + << pkg.Name() << std::endl; + TFRewriteData rewrite[2]; + rewrite[0].Tag = "Auto-Installed"; + rewrite[0].Rewrite = newAuto ? "1" : "0"; + rewrite[0].NewTag = 0; + rewrite[1].Tag = 0; + TFRewrite(OutFile, section, nullreorderlist, rewrite); + fprintf(OutFile,"\n"); + pkgs_seen.insert(pkgname); + } + + // then write the ones we have not seen yet std::ostringstream ostr; - for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end();pkg++) { - + for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); pkg++) { if(PkgState[pkg->ID].Flags & Flag::Auto) { + if (pkgs_seen.find(pkg.Name()) != pkgs_seen.end()) { + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::clog << "Skipping already written " << pkg.Name() << std::endl; + continue; + } if(_config->FindB("Debug::pkgAutoRemove",false)) - std::clog << "AutoInstall: " << pkg.Name() << std::endl; + std::clog << "Writing new AutoInstall: " + << pkg.Name() << std::endl; ostr.str(string("")); ostr << "Package: " << pkg.Name() << "\nAuto-Installed: 1\n\n"; - StateFile.Write(ostr.str().c_str(), ostr.str().size()); + fprintf(OutFile,ostr.str().c_str()); + fprintf(OutFile,"\n"); } } + + // move the outfile over the real file + rename(outfile.c_str(), state.c_str()); + return true; } -- cgit v1.2.3 From 6b6afec3673bd1685e62a5c4b1803531a44add82 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 26 Jun 2006 09:28:51 +0200 Subject: * apt-pkg/init.h: - increased lib-version to 3.13 --- apt-pkg/init.h | 2 +- apt-pkg/makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/init.h b/apt-pkg/init.h index 8255b406a..6a832bddf 100644 --- a/apt-pkg/init.h +++ b/apt-pkg/init.h @@ -18,7 +18,7 @@ // See the makefile #define APT_PKG_MAJOR 3 -#define APT_PKG_MINOR 11 +#define APT_PKG_MINOR 13 #define APT_PKG_RELEASE 0 extern const char *pkgVersion; diff --git a/apt-pkg/makefile b/apt-pkg/makefile index ab0ff8005..7093d23ce 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=3.12 +MAJOR=3.13 MINOR=0 SLIBS=$(PTHREADLIB) $(INTLLIBS) APT_DOMAIN:=libapt-pkg$(MAJOR) -- cgit v1.2.3 From 9a9665f96e006602950e0e32ce80cb5ee14f5e5f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 4 Jul 2006 09:22:49 +0200 Subject: * apt-pkg/depcache.cc: - create a empty state file if none exists --- apt-pkg/depcache.cc | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 7663d3881..25a4372bf 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -186,6 +186,15 @@ bool pkgDepCache::writeStateFile(OpProgress *prog) FileFd StateFile; string state = _config->FindDir("Dir::State") + "extended_states"; + + // if it does not exist, create a empty one + if(!FileExists(state)) + { + StateFile.Open(state, FileFd::WriteEmpty); + StateFile.Close(); + } + + // open it if(!StateFile.Open(state, FileFd::ReadOnly)) return _error->Error(_("Failed to open StateFile %s"), state.c_str()); -- cgit v1.2.3 From a4decc40b3eb085ea994d2a8b31ee9cddfd570ff Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 21 Jul 2006 11:00:34 +0200 Subject: * apt-pkg/depcache.cc: - close the outfile properly (thanks to kamion) * cmdline/apt-get.cc: - unbreak dselect-upgrade by adding a ActionGroup around it --- apt-pkg/depcache.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 25a4372bf..369eae70b 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -251,6 +251,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog) fprintf(OutFile,"\n"); } } + fclose(OutFile); // move the outfile over the real file rename(outfile.c_str(), state.c_str()); -- cgit v1.2.3 From 8953292ef197b80c16d08b31830945fb7ac9ff8d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 21 Jul 2006 11:01:59 +0200 Subject: * merged changes from Kamions upload (thanks!) --- apt-pkg/depcache.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 25a4372bf..369eae70b 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -251,6 +251,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog) fprintf(OutFile,"\n"); } } + fclose(OutFile); // move the outfile over the real file rename(outfile.c_str(), state.c_str()); -- cgit v1.2.3 From fb603534bf69ae4b01f5abda4e42814450e59a31 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 25 Jul 2006 16:11:03 +0200 Subject: * apt-pkg/deb/debmetaindex.cc: - don't queue translations for deb-src entries --- apt-pkg/deb/debmetaindex.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index ea53a847e..a3fc39302 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -161,6 +161,8 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const for (vector::const_iterator I = SectionEntries.begin(); I != SectionEntries.end(); I++) { + if((*I)->IsSrc) + continue; debTranslationsIndex i = debTranslationsIndex(URI,Dist,(*I)->Section); i.GetIndexes(Owner); } -- cgit v1.2.3 From 73c460c358cfa6615ee6760a3fb8d88988a12856 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 9 Aug 2006 17:17:04 +0200 Subject: * apt-pkg/init.cc: - init "install-recommends", "install-suggests" with default "false" * debian/changelog: - updated --- apt-pkg/init.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc index b47378d4a..a26f1d01c 100644 --- a/apt-pkg/init.cc +++ b/apt-pkg/init.cc @@ -40,6 +40,8 @@ bool pkgInitConfig(Configuration &Cnf) else Cnf.Set("APT::Architecture",COMMON_OS "-" COMMON_CPU); Cnf.Set("APT::Build-Essential::", "build-essential"); + Cnf.Set("APT::Install-Recommends", false); + Cnf.Set("APT::Install-Suggests", false); Cnf.Set("Dir","/"); // State -- cgit v1.2.3 From 1b1c2224f5777956f345471b600ed56203c2d400 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 9 Aug 2006 20:01:46 +0200 Subject: * apt-pkg/depcache.cc: - find new important dependencies on upgrade and deal with them --- apt-pkg/depcache.cc | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 8560ce4fd..6296892ba 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -667,7 +667,33 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, it will be installed. Otherwise we only worry about critical deps */ if (IsImportantDep(Start) == false) continue; - if (Pkg->CurrentVer != 0 && Start.IsCritical() == false) + + /* check if any ImportantDep() (but not Critial) where added + * since we installed the thing + */ + bool isNewImportantDep = false; + if(IsImportantDep(Start) && !Start.IsCritical()) + { + bool found=false; + VerIterator instVer = Pkg.CurrentVer(); + for (DepIterator D = instVer.DependsList(); !D.end(); D++) + { + //FIXME: deal better with or-groups(?) + DepIterator LocalStart = D; + + if(IsImportantDep(Dep) && Start.TargetPkg() == D.TargetPkg()) + found=true; + } + // this is a new dep if it was not found to be already + // a important dep of the installed pacakge + isNewImportantDep = !found; + } + if(isNewImportantDep) + if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true) + std::clog << "new important dependency: " + << Start.TargetPkg().Name() << std::endl; + + if (Pkg->CurrentVer != 0 && Start.IsCritical() == false && !isNewImportantDep) continue; /* If we are in an or group locate the first or that can -- cgit v1.2.3 From 4ef9a929f1cb74f08f764b321cbea62cbfe025a2 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 11 Aug 2006 11:30:11 +0200 Subject: * cmdline/apt-get.cc: - added "--fix-policy" option to make it easy to fix any not-install recommends * apt-pkg/depcache.{cc,h} - MarkInstall() has a new "ForceImportantDeps" option (defaults to false) to fice the install of recommends even for already installed pkgs - a new PolicyBroken() function to see how much of the recommends are broken --- apt-pkg/depcache.cc | 26 ++++++++++++++++---------- apt-pkg/depcache.h | 5 ++++- 2 files changed, 20 insertions(+), 11 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 6296892ba..bfcb8e0eb 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -239,9 +239,11 @@ void pkgDepCache::AddStates(const PkgIterator &Pkg,int Add) { StateCache &State = PkgState[Pkg->ID]; - // The Package is broken + // The Package is broken (either minimal dep or policy dep) if ((State.DepState & DepInstMin) != DepInstMin) iBrokenCount += Add; + if ((State.DepState & DepInstPolicy) != DepInstPolicy) + iPolicyBrokenCount += Add; // Bad state if (Pkg.State() != PkgIterator::NeedsNothing) @@ -596,7 +598,7 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge) // --------------------------------------------------------------------- /* */ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, - unsigned long Depth) + unsigned long Depth, bool ForceImportantDeps) { if (Depth > 100) return; @@ -664,24 +666,26 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, /* Check if this dep should be consider for install. If it is a user defined important dep and we are installed a new package then - it will be installed. Otherwise we only worry about critical deps */ + it will be installed. Otherwise we only check for important + deps that have changed from the installed version + */ if (IsImportantDep(Start) == false) continue; - + /* check if any ImportantDep() (but not Critial) where added - * since we installed the thing + * since we installed the package */ bool isNewImportantDep = false; - if(IsImportantDep(Start) && !Start.IsCritical()) + if(!ForceImportantDeps && !Start.IsCritical()) { bool found=false; VerIterator instVer = Pkg.CurrentVer(); - for (DepIterator D = instVer.DependsList(); !D.end(); D++) + for (DepIterator D = instVer.DependsList(); D.end() != true; D++) { //FIXME: deal better with or-groups(?) DepIterator LocalStart = D; - if(IsImportantDep(Dep) && Start.TargetPkg() == D.TargetPkg()) + if(IsImportantDep(D) && Start.TargetPkg() == D.TargetPkg()) found=true; } // this is a new dep if it was not found to be already @@ -693,7 +697,9 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, std::clog << "new important dependency: " << Start.TargetPkg().Name() << std::endl; - if (Pkg->CurrentVer != 0 && Start.IsCritical() == false && !isNewImportantDep) + // skip important deps if the package is already installed + if (Pkg->CurrentVer != 0 && Start.IsCritical() == false + && !isNewImportantDep && !ForceImportantDeps) continue; /* If we are in an or group locate the first or that can @@ -741,7 +747,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, std::clog << "Installing " << InstPkg.Name() << " as dep of " << Pkg.Name() << std::endl; - MarkInstall(InstPkg,true,Depth + 1); + MarkInstall(InstPkg,true,Depth + 1, ForceImportantDeps); // Set the autoflag, after MarkInstall because MarkInstall unsets it if (P->CurrentVer == 0) diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 3f9f67140..042abb5cc 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -97,6 +97,7 @@ class pkgDepCache : protected pkgCache::Namespace inline bool Downgrade() const {return Status < 0 && Mode == ModeInstall;}; inline bool Held() const {return Status != 0 && Keep();}; inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;}; + inline bool NowPolicyBroken() const {return (DepState & DepNowPolicy) != DepNowPolicy;}; inline bool InstBroken() const {return (DepState & DepInstMin) != DepInstMin;}; inline bool InstPolicyBroken() const {return (DepState & DepInstPolicy) != DepInstPolicy;}; inline bool Install() const {return Mode == ModeInstall;}; @@ -134,6 +135,7 @@ class pkgDepCache : protected pkgCache::Namespace unsigned long iDelCount; unsigned long iKeepCount; unsigned long iBrokenCount; + unsigned long iPolicyBrokenCount; unsigned long iBadCount; Policy *delLocalPolicy; // For memory clean up.. @@ -187,7 +189,7 @@ class pkgDepCache : protected pkgCache::Namespace void MarkKeep(PkgIterator const &Pkg,bool Soft = false); void MarkDelete(PkgIterator const &Pkg,bool Purge = false); void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true, - unsigned long Depth = 0); + unsigned long Depth = 0, bool ForceImportantDeps = false); void SetReInstall(PkgIterator const &Pkg,bool To); void SetCandidateVersion(VerIterator TargetVer); @@ -201,6 +203,7 @@ class pkgDepCache : protected pkgCache::Namespace inline unsigned long KeepCount() {return iKeepCount;}; inline unsigned long InstCount() {return iInstCount;}; inline unsigned long BrokenCount() {return iBrokenCount;}; + inline unsigned long PolicyBrokenCount() {return iPolicyBrokenCount;}; inline unsigned long BadCount() {return iBadCount;}; bool Init(OpProgress *Prog); -- cgit v1.2.3 From 6ea086805714e0dbeecfb5e3e26d3489a624bcd4 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 11 Aug 2006 17:27:13 +0200 Subject: * apt-pkg/depcache.cc: - only work on instVer if we actually have one --- apt-pkg/depcache.cc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index bfcb8e0eb..b5b96dbcf 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -680,14 +680,15 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, { bool found=false; VerIterator instVer = Pkg.CurrentVer(); - for (DepIterator D = instVer.DependsList(); D.end() != true; D++) - { - //FIXME: deal better with or-groups(?) - DepIterator LocalStart = D; - - if(IsImportantDep(D) && Start.TargetPkg() == D.TargetPkg()) - found=true; - } + if(!instVer.end()) + for (DepIterator D = instVer.DependsList(); D.end() != true; D++) + { + //FIXME: deal better with or-groups(?) + DepIterator LocalStart = D; + + if(IsImportantDep(D) && Start.TargetPkg() == D.TargetPkg()) + found=true; + } // this is a new dep if it was not found to be already // a important dep of the installed pacakge isNewImportantDep = !found; -- cgit v1.2.3 From a498783013497735fb9fa484be60f6148289b0bb Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 15 Aug 2006 12:08:36 +0200 Subject: * apt-pkg/pkgcachegen.cc: - increased the cache limit --- apt-pkg/pkgcachegen.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index b2725a99d..8ec6a1719 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -785,7 +785,7 @@ static bool BuildCache(pkgCacheGenerator &Gen, bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, MMap **OutMap,bool AllowMem) { - unsigned long MapSize = _config->FindI("APT::Cache-Limit",12*1024*1024); + unsigned long MapSize = _config->FindI("APT::Cache-Limit",16*1024*1024); vector Files; for (vector::const_iterator i = List.begin(); @@ -932,7 +932,7 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress, /* */ bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap) { - unsigned long MapSize = _config->FindI("APT::Cache-Limit",8*1024*1024); + unsigned long MapSize = _config->FindI("APT::Cache-Limit",12*1024*1024); vector Files; unsigned long EndOfSource = Files.size(); if (_system->AddStatusFiles(Files) == false) -- cgit v1.2.3 From 857a1d4aafc7fd4cc9d1f22c7ef4d274b09c2906 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 15 Aug 2006 12:59:52 +0200 Subject: * apt-pkg/deb/dpkgpm.cc: - pass --auto-deconfigure to dpkg (-B) * debian/control: - depend on a dpkg with support for breaks --- apt-pkg/deb/dpkgpm.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index bf0434ccc..93dff390d 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -474,6 +474,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) case Item::Install: Args[n++] = "--unpack"; Size += strlen(Args[n-1]); + Args[n++] = "--auto-deconfigure"; + Size += strlen(Args[n-1]); break; } -- cgit v1.2.3 From 308c7d30ed2e937cde65e5fed8cbf717fba113c3 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 25 Aug 2006 15:39:15 +0100 Subject: initial Breaks implementation --- apt-pkg/algorithms.cc | 23 ++++++++++++++++++++++- apt-pkg/deb/deblistparser.cc | 3 +++ apt-pkg/depcache.cc | 40 ++++++++++++++++++++++++++++------------ apt-pkg/orderlist.cc | 17 ++++++++++++++++- apt-pkg/pkgcache.cc | 9 ++++++--- apt-pkg/pkgcache.h | 6 +++++- apt-pkg/tagfile.cc | 1 + 7 files changed, 81 insertions(+), 18 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index ac9d3be0b..f50c52a32 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -102,6 +102,7 @@ bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/) DepIterator End; D.GlobOr(Start,End); if (Start->Type == pkgCache::Dep::Conflicts || + Start->Type == pkgCache::Dep::DpkgBreaks || Start->Type == pkgCache::Dep::Obsoletes || End->Type == pkgCache::Dep::PreDepends) { @@ -151,6 +152,8 @@ bool pkgSimulate::Configure(PkgIterator iPkg) cout << " Obsoletes:" << D.TargetPkg().Name(); else if (D->Type == pkgCache::Dep::Conflicts) cout << " Conflicts:" << D.TargetPkg().Name(); + else if (D->Type == pkgCache::Dep::DpkgBreaks) + cout << " Breaks:" << D.TargetPkg().Name(); else cout << " Depends:" << D.TargetPkg().Name(); } @@ -651,6 +654,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) /* We let the algorithm deal with conflicts on its next iteration, it is much smarter than us */ if (Start->Type == pkgCache::Dep::Conflicts || + Start->Type == pkgCache::Dep::DpkgBreaks || Start->Type == pkgCache::Dep::Obsoletes) break; @@ -873,6 +877,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) SPtrArray VList = Start.AllTargets(); if (*VList == 0 && (Flags[I->ID] & Protected) != Protected && Start->Type != pkgCache::Dep::Conflicts && + Start->Type != pkgCache::Dep::DpkgBreaks && Start->Type != pkgCache::Dep::Obsoletes && Cache[I].NowBroken() == false) { @@ -903,6 +908,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) if (Scores[I->ID] <= Scores[Pkg->ID] || ((Cache[Start] & pkgDepCache::DepNow) == 0 && End->Type != pkgCache::Dep::Conflicts && + End->Type != pkgCache::Dep::DpkgBreaks && End->Type != pkgCache::Dep::Obsoletes)) { // Try a little harder to fix protected packages.. @@ -968,7 +974,21 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) (Start->Type == pkgCache::Dep::Conflicts || Start->Type == pkgCache::Dep::Obsoletes)) continue; - + + if (Start->Type == pkgCache::Dep::DpkgBreaks) + { + /* Would it help if we upgraded? */ + if (Cache[End] & pkgDepCache::DepGCVer) { + if (Debug) + clog << " Upgrading " << Pkg.Name() << " due to Breaks field in " << I.Name() << endl; + Cache.MarkInstall(Pkg, false, 0, false); + continue; + } + if (Debug) + clog << " Will not break " << Pkg.Name() << " as stated in Breaks field in " << I.Name() <ID] & Protected) != 0) continue; @@ -989,6 +1009,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) // Hm, nothing can possibly satisify this dep. Nuke it. if (VList[0] == 0 && Start->Type != pkgCache::Dep::Conflicts && + Start->Type != pkgCache::Dep::DpkgBreaks && Start->Type != pkgCache::Dep::Obsoletes && (Flags[I->ID] & Protected) != Protected) { diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index c2b26b5eb..074abea6d 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -105,6 +105,8 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) return false; if (ParseDepends(Ver,"Conflicts",pkgCache::Dep::Conflicts) == false) return false; + if (ParseDepends(Ver,"Breaks",pkgCache::Dep::DpkgBreaks) == false) + return false; if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Replaces) == false) return false; @@ -193,6 +195,7 @@ unsigned short debListParser::VersionHash() // "Suggests", // "Recommends", "Conflicts", + "Breaks", "Replaces",0}; unsigned long Result = INIT_FCS; char S[1024]; diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 78c929d62..4d193dc2e 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -273,7 +273,7 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res) we allow it anyhow because dpkg does. Technically it is a packaging bug. Conflicts may never self match */ if (Dep.TargetPkg() != Dep.ParentPkg() || - (Dep->Type != Dep::Conflicts && Dep->Type != Dep::Obsoletes)) + (Dep->Type != Dep::Conflicts && Dep->Type != Dep::DpkgBreaks && Dep->Type != Dep::Obsoletes)) { PkgIterator Pkg = Dep.TargetPkg(); // Check the base package @@ -303,7 +303,8 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res) { /* Provides may never be applied against the same package if it is a conflicts. See the comment above. */ - if (P.OwnerPkg() == Pkg && Dep->Type == Dep::Conflicts) + if (P.OwnerPkg() == Pkg && + (Dep->Type == Dep::Conflicts || Dep->Type == Dep::DpkgBreaks)) continue; // Check if the provides is a hit @@ -457,7 +458,9 @@ void pkgDepCache::BuildGroupOrs(VerIterator const &V) /* Invert for Conflicts. We have to do this twice to get the right sense for a conflicts group */ - if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes) + if (D->Type == Dep::Conflicts || + D->Type == Dep::DpkgBreaks || + D->Type == Dep::Obsoletes) State = ~State; // Add to the group if we are within an or.. @@ -468,7 +471,9 @@ void pkgDepCache::BuildGroupOrs(VerIterator const &V) Group = 0; // Invert for Conflicts - if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes) + if (D->Type == Dep::Conflicts || + D->Type == Dep::DpkgBreaks || + D->Type == Dep::Obsoletes) State = ~State; } } @@ -601,7 +606,9 @@ void pkgDepCache::Update(OpProgress *Prog) Group = 0; // Invert for Conflicts - if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes) + if (D->Type == Dep::Conflicts || + D->Type == Dep::DpkgBreaks || + D->Type == Dep::Obsoletes) State = ~State; } } @@ -631,7 +638,9 @@ void pkgDepCache::Update(DepIterator D) State = DependencyState(D); // Invert for Conflicts - if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes) + if (D->Type == Dep::Conflicts || + D->Type == Dep::DpkgBreaks || + D->Type == Dep::Obsoletes) State = ~State; RemoveStates(D.ParentPkg()); @@ -894,7 +903,8 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, /* This bit is for processing the possibilty of an install/upgrade fixing the problem */ SPtrArray List = Start.AllTargets(); - if ((DepState[Start->ID] & DepCVer) == DepCVer) + if (Start->Type != Dep::DpkgBreaks && + (DepState[Start->ID] & DepCVer) == DepCVer) { // Right, find the best version to install.. Version **Cur = List; @@ -939,17 +949,23 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, } continue; } - + /* For conflicts we just de-install the package and mark as auto, - Conflicts may not have or groups */ - if (Start->Type == Dep::Conflicts || Start->Type == Dep::Obsoletes) + Conflicts may not have or groups. For dpkg's Breaks we try to + upgrade the package. */ + if (Start->Type == Dep::Conflicts || Start->Type == Dep::Obsoletes || + Start->Type == Dep::DpkgBreaks) { for (Version **I = List; *I != 0; I++) { VerIterator Ver(*this,*I); PkgIterator Pkg = Ver.ParentPkg(); - - MarkDelete(Pkg); + + if (Start->Type != Dep::DpkgBreaks) + MarkDelete(Pkg); + else + if (PkgState[Pkg->ID].CandidateVer != *I) + MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps); } continue; } diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc index 8d3a97983..61d8d914e 100644 --- a/apt-pkg/orderlist.cc +++ b/apt-pkg/orderlist.cc @@ -491,11 +491,13 @@ bool pkgOrderList::VisitProvides(DepIterator D,bool Critical) continue; if (D->Type != pkgCache::Dep::Conflicts && + D->Type != pkgCache::Dep::DpkgBreaks && D->Type != pkgCache::Dep::Obsoletes && Cache[Pkg].InstallVer != *I) continue; if ((D->Type == pkgCache::Dep::Conflicts || + D->Type == pkgCache::Dep::DpkgBreaks || D->Type == pkgCache::Dep::Obsoletes) && (Version *)Pkg.CurrentVer() != *I) continue; @@ -630,6 +632,7 @@ bool pkgOrderList::DepUnPackCrit(DepIterator D) /* Forward critical dependencies MUST be correct before the package can be unpacked. */ if (D->Type != pkgCache::Dep::Conflicts && + D->Type != pkgCache::Dep::DpkgBreaks && D->Type != pkgCache::Dep::Obsoletes && D->Type != pkgCache::Dep::PreDepends) continue; @@ -668,7 +671,7 @@ bool pkgOrderList::DepUnPackCrit(DepIterator D) } return true; } - /*}}}*/ + // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/ // --------------------------------------------------------------------- /* Critical PreDepends (also configure immediate and essential) strives to @@ -803,9 +806,20 @@ bool pkgOrderList::DepUnPackDep(DepIterator D) return false; } else + { if (D->Type == pkgCache::Dep::Depends) if (VisitProvides(D,false) == false) return false; + + if (D->Type == pkgCache::Dep::DpkgBreaks) + { + if (CheckDep(D) == true) + continue; + + if (VisitNode(D.TargetPkg()) == false) + return false; + } + } } return true; } @@ -953,6 +967,7 @@ bool pkgOrderList::CheckDep(DepIterator D) /* Conflicts requires that all versions are not present, depends just needs one */ if (D->Type != pkgCache::Dep::Conflicts && + D->Type != pkgCache::Dep::DpkgBreaks && D->Type != pkgCache::Dep::Obsoletes) { /* Try to find something that does not have the after flag set diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 162ab4f27..35eb23dfa 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -228,8 +228,8 @@ const char *pkgCache::DepType(unsigned char Type) { const char *Types[] = {"",_("Depends"),_("PreDepends"),_("Suggests"), _("Recommends"),_("Conflicts"),_("Replaces"), - _("Obsoletes")}; - if (Type < 8) + _("Obsoletes"),_("Breaks")}; + if (Type < sizeof(Types)/sizeof(*Types)) return Types[Type]; return ""; } @@ -292,10 +292,11 @@ pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const // DepIterator::IsCritical - Returns true if the dep is important /*{{{*/ // --------------------------------------------------------------------- /* Currently critical deps are defined as depends, predepends and - conflicts. */ + conflicts (including dpkg's Breaks fields). */ bool pkgCache::DepIterator::IsCritical() { if (Dep->Type == pkgCache::Dep::Conflicts || + Dep->Type == pkgCache::Dep::DpkgBreaks || Dep->Type == pkgCache::Dep::Obsoletes || Dep->Type == pkgCache::Dep::Depends || Dep->Type == pkgCache::Dep::PreDepends) @@ -381,6 +382,7 @@ pkgCache::Version **pkgCache::DepIterator::AllTargets() continue; if ((Dep->Type == pkgCache::Dep::Conflicts || + Dep->Type == pkgCache::Dep::DpkgBreaks || Dep->Type == pkgCache::Dep::Obsoletes) && ParentPkg() == I.ParentPkg()) continue; @@ -397,6 +399,7 @@ pkgCache::Version **pkgCache::DepIterator::AllTargets() continue; if ((Dep->Type == pkgCache::Dep::Conflicts || + Dep->Type == pkgCache::Dep::DpkgBreaks || Dep->Type == pkgCache::Dep::Obsoletes) && ParentPkg() == I.OwnerPkg()) continue; diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index c7a3172cc..970759492 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -66,10 +66,14 @@ class pkgCache class Namespace; // These are all the constants used in the cache structures + + // WARNING - if you change these lists you must also edit + // the stringification in pkgcache.cc and also consider whether + // the cache file will become incompatible. struct Dep { enum DepType {Depends=1,PreDepends=2,Suggests=3,Recommends=4, - Conflicts=5,Replaces=6,Obsoletes=7}; + Conflicts=5,Replaces=6,Obsoletes=7,DpkgBreaks=8}; enum DepCompareOp {Or=0x10,NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3, Greater=0x4,Equals=0x5,NotEquals=0x6}; }; diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 8fcbeb23b..146829566 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -422,6 +422,7 @@ static const char *iTFRewritePackageOrder[] = { "Recommends", "Suggests", "Conflicts", + "Breaks", "Conffiles", "Filename", "Size", -- cgit v1.2.3 From d242b9e788311e7f19ceaa9dc24f5e426005ae4c Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 5 Sep 2006 19:51:17 +0100 Subject: bump cache version --- apt-pkg/pkgcache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 35eb23dfa..93ad56641 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -54,7 +54,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 = 5; + MajorVersion = 6; MinorVersion = 0; Dirty = false; -- cgit v1.2.3 From 1d7229332a7707e9abb341a7ce75ce332df54420 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 7 Sep 2006 11:48:07 +0200 Subject: * apt-pkg/depcache.cc: - added "APT::Install-Recommends-Section" option --- apt-pkg/depcache.cc | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index b5b96dbcf..422343e4a 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -681,6 +681,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, bool found=false; VerIterator instVer = Pkg.CurrentVer(); if(!instVer.end()) + { for (DepIterator D = instVer.DependsList(); D.end() != true; D++) { //FIXME: deal better with or-groups(?) @@ -689,9 +690,10 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, if(IsImportantDep(D) && Start.TargetPkg() == D.TargetPkg()) found=true; } - // this is a new dep if it was not found to be already - // a important dep of the installed pacakge - isNewImportantDep = !found; + // this is a new dep if it was not found to be already + // a important dep of the installed pacakge + isNewImportantDep = !found; + } } if(isNewImportantDep) if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true) @@ -902,8 +904,22 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep) { if(Dep.IsCritical()) return true; - else if(Dep->Type == pkgCache::Dep::Recommends) - return _config->FindB("APT::Install-Recommends", false); + else if(Dep->Type == pkgCache::Dep::Recommends) + { + if ( _config->FindB("APT::Install-Recommends", false)) + return true; + // we suport a special mode to only install-recommends for certain + // sections + // FIXME: this is a meant as a temporarly solution until the + // recommends are cleaned up + string s = _config->Find("APT::Install-Recommends-Section",""); + if(s.size() > 0) + { + const char *sec = Dep.TargetPkg().Section(); + if (sec && strcmp(sec, s.c_str()) == 0) + return true; + } + } else if(Dep->Type == pkgCache::Dep::Suggests) return _config->FindB("APT::Install-Suggests", false); -- cgit v1.2.3 From c15f569038c9d08cfb5186945d9c5095f7776768 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 8 Sep 2006 19:36:31 +0200 Subject: * apt-pkg/algorithms.cc: - bugfix in the InstallProcted() code (preserver the auto-install information) * cmdline/makefile: - install apt-mark as well --- apt-pkg/algorithms.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index ac9d3be0b..55f44fbd5 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -1229,8 +1229,13 @@ void pkgProblemResolver::InstallProtect() { if ((Flags[I->ID] & ToRemove) == ToRemove) Cache.MarkDelete(I); - else - Cache.MarkInstall(I, false, 0, false); + else + { + // preserver the information if the package was auto + // or manual installed + bool autoInst = (Cache[I].Flags & pkgCache::Flag::Auto); + Cache.MarkInstall(I, false, 0, !autoInst); + } } } } -- cgit v1.2.3 From 320854985be0fe14491385ca349783ab8a9d7797 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 21 Sep 2006 02:02:13 +0200 Subject: * apt-pkg/depcache.cc: - do not change the auto-flag in MarkKeep() to prevent side-effects in interactive package managers when a package is marked for remove first and then unmarked again. the old code removed the auto-flag, the new code will retain this information - a package can be garbage even if it is already marked for removal --- apt-pkg/depcache.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 369eae70b..2bae94026 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -701,9 +701,18 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser) // We dont even try to keep virtual packages.. if (Pkg->VersionList == 0) return; - + +#if 0 // reseting the autoflag here means we lose the + // auto-mark information if a user selects a package for removal + // but changes his mind then and sets it for keep again + // - this makes sense as default when all Garbage dependencies + // are automatically marked for removal (as aptitude does). + // setting a package for keep then makes it no longer autoinstalled + // for all other use-case this action is rather suprising if(FromUser && !P.Marked) P.Flags &= ~Flag::Auto; +#endif + RemoveSizes(Pkg); RemoveStates(Pkg); @@ -1265,8 +1274,7 @@ bool pkgDepCache::Sweep() StateCache &state=PkgState[p->ID]; // if it is not marked and it is installed, it's garbage - if(!state.Marked && (!p.CurrentVer().end() || state.Install()) && - !state.Delete()) + if(!state.Marked && (!p.CurrentVer().end() || state.Install())) { state.Garbage=true; if(_config->FindB("Debug::pkgAutoRemove",false)) -- cgit v1.2.3 From 1350057372b095f718c0073a704f2c1960c04c81 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 2 Oct 2006 16:16:54 +0200 Subject: * removed the pragma mess --- apt-pkg/acquire-item.h | 3 --- apt-pkg/acquire-method.h | 3 --- apt-pkg/acquire-worker.h | 3 --- apt-pkg/acquire.h | 3 --- apt-pkg/algorithms.h | 3 --- apt-pkg/cachefile.h | 3 --- apt-pkg/cacheiterators.h | 3 --- apt-pkg/cdrom.h | 3 --- apt-pkg/clean.h | 3 --- apt-pkg/contrib/cdromutl.h | 4 ---- apt-pkg/contrib/cmndline.h | 4 +--- apt-pkg/contrib/configuration.h | 4 +--- apt-pkg/contrib/crc-16.h | 4 ---- apt-pkg/contrib/error.h | 4 +--- apt-pkg/contrib/fileutl.h | 1 - apt-pkg/contrib/hashes.h | 1 - apt-pkg/contrib/md5.h | 3 --- apt-pkg/contrib/mmap.h | 1 - apt-pkg/contrib/progress.h | 1 - apt-pkg/contrib/sha1.h | 4 ---- apt-pkg/contrib/sha256.h | 4 ---- apt-pkg/contrib/strutl.h | 4 +--- apt-pkg/deb/debindexfile.h | 4 +--- apt-pkg/deb/debmetaindex.h | 4 ---- apt-pkg/deb/debrecords.h | 4 ---- apt-pkg/deb/debsrcrecords.h | 3 --- apt-pkg/deb/debsystem.h | 4 ---- apt-pkg/deb/debversion.h | 4 +--- apt-pkg/deb/dpkgpm.h | 4 ---- apt-pkg/depcache.cc | 3 --- apt-pkg/depcache.h | 3 --- apt-pkg/indexfile.h | 3 --- apt-pkg/indexrecords.h | 1 - apt-pkg/metaindex.h | 3 --- apt-pkg/orderlist.h | 3 --- apt-pkg/packagemanager.h | 3 --- apt-pkg/pkgcache.cc | 5 ----- apt-pkg/pkgcache.h | 3 --- apt-pkg/pkgcachegen.h | 3 --- apt-pkg/pkgrecords.h | 3 --- apt-pkg/pkgsystem.h | 3 --- apt-pkg/policy.h | 3 --- apt-pkg/sourcelist.h | 3 --- apt-pkg/srcrecords.h | 3 --- apt-pkg/tagfile.h | 3 --- apt-pkg/vendor.h | 3 --- apt-pkg/vendorlist.h | 3 --- apt-pkg/version.h | 3 --- apt-pkg/versionmatch.h | 3 --- 49 files changed, 6 insertions(+), 147 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index da1bea801..b47e198d8 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -27,9 +27,6 @@ #include #include -#ifdef __GNUG__ -#pragma interface "apt-pkg/acquire-item.h" -#endif // Item to acquire class pkgAcquire::Item diff --git a/apt-pkg/acquire-method.h b/apt-pkg/acquire-method.h index f46209d12..1c0b9f67c 100644 --- a/apt-pkg/acquire-method.h +++ b/apt-pkg/acquire-method.h @@ -16,9 +16,6 @@ #include #include -#ifdef __GNUG__ -#pragma interface "apt-pkg/acquire-method.h" -#endif class Hashes; class pkgAcqMethod diff --git a/apt-pkg/acquire-worker.h b/apt-pkg/acquire-worker.h index 6e1952202..d5f8c63d2 100644 --- a/apt-pkg/acquire-worker.h +++ b/apt-pkg/acquire-worker.h @@ -14,9 +14,6 @@ #include -#ifdef __GNUG__ -#pragma interface "apt-pkg/acquire-worker.h" -#endif // Interfacing to the method process class pkgAcquire::Worker diff --git a/apt-pkg/acquire.h b/apt-pkg/acquire.h index 27bb3d363..6e836ac49 100644 --- a/apt-pkg/acquire.h +++ b/apt-pkg/acquire.h @@ -38,9 +38,6 @@ using std::vector; using std::string; -#ifdef __GNUG__ -#pragma interface "apt-pkg/acquire.h" -#endif #include #include diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index b95218061..b72874d8e 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -30,9 +30,6 @@ #ifndef PKGLIB_ALGORITHMS_H #define PKGLIB_ALGORITHMS_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/algorithms.h" -#endif #include #include diff --git a/apt-pkg/cachefile.h b/apt-pkg/cachefile.h index a128c29ab..d23841e5e 100644 --- a/apt-pkg/cachefile.h +++ b/apt-pkg/cachefile.h @@ -17,9 +17,6 @@ #ifndef PKGLIB_CACHEFILE_H #define PKGLIB_CACHEFILE_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/cachefile.h" -#endif #include diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 2b326bd65..c412eaa97 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -31,9 +31,6 @@ #ifndef PKGLIB_CACHEITERATORS_H #define PKGLIB_CACHEITERATORS_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/cacheiterators.h" -#endif // Package Iterator class pkgCache::PkgIterator diff --git a/apt-pkg/cdrom.h b/apt-pkg/cdrom.h index 085eb64e2..b8b208c30 100644 --- a/apt-pkg/cdrom.h +++ b/apt-pkg/cdrom.h @@ -5,9 +5,6 @@ #include #include -#ifdef __GNUG__ -#pragma interface "apt-pkg/cdrom.h" -#endif using namespace std; diff --git a/apt-pkg/clean.h b/apt-pkg/clean.h index 43164e250..2aee2bf54 100644 --- a/apt-pkg/clean.h +++ b/apt-pkg/clean.h @@ -10,9 +10,6 @@ #ifndef APTPKG_CLEAN_H #define APTPKG_CLEAN_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/clean.h" -#endif #include diff --git a/apt-pkg/contrib/cdromutl.h b/apt-pkg/contrib/cdromutl.h index 3180a03c7..1264982a8 100644 --- a/apt-pkg/contrib/cdromutl.h +++ b/apt-pkg/contrib/cdromutl.h @@ -14,10 +14,6 @@ using std::string; -#ifdef __GNUG__ -#pragma interface "apt-pkg/cdromutl.h" -#endif - bool MountCdrom(string Path); bool UnmountCdrom(string Path); bool IdentCdrom(string CD,string &Res,unsigned int Version = 2); diff --git a/apt-pkg/contrib/cmndline.h b/apt-pkg/contrib/cmndline.h index 8f461296f..fad6d1da9 100644 --- a/apt-pkg/contrib/cmndline.h +++ b/apt-pkg/contrib/cmndline.h @@ -44,9 +44,7 @@ #ifndef PKGLIB_CMNDLINE_H #define PKGLIB_CMNDLINE_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/cmndline.h" -#endif + #include diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h index 0d4078dab..2534692a3 100644 --- a/apt-pkg/contrib/configuration.h +++ b/apt-pkg/contrib/configuration.h @@ -28,9 +28,7 @@ #ifndef PKGLIB_CONFIGURATION_H #define PKGLIB_CONFIGURATION_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/configuration.h" -#endif + #include #include diff --git a/apt-pkg/contrib/crc-16.h b/apt-pkg/contrib/crc-16.h index 757104c54..f30678bac 100644 --- a/apt-pkg/contrib/crc-16.h +++ b/apt-pkg/contrib/crc-16.h @@ -10,10 +10,6 @@ #ifndef APTPKG_CRC16_H #define APTPKG_CRC16_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/crc-16.h" -#endif - #define INIT_FCS 0xffff unsigned short AddCRC16(unsigned short fcs, void const *buf, unsigned long len); diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h index a5fc1a223..a3be6a575 100644 --- a/apt-pkg/contrib/error.h +++ b/apt-pkg/contrib/error.h @@ -40,9 +40,7 @@ #ifndef PKGLIB_ERROR_H #define PKGLIB_ERROR_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/error.h" -#endif + #ifdef __GNUG__ // Methods have a hidden this parameter that is visible to this attribute diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 041aa3309..fcb26938f 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -22,7 +22,6 @@ #define PKGLIB_FILEUTL_H #ifdef __GNUG__ -#pragma interface "apt-pkg/fileutl.h" #endif #include diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h index eefa7bf41..263854054 100644 --- a/apt-pkg/contrib/hashes.h +++ b/apt-pkg/contrib/hashes.h @@ -14,7 +14,6 @@ #define APTPKG_HASHES_H #ifdef __GNUG__ -#pragma interface "apt-pkg/hashes.h" #endif #include diff --git a/apt-pkg/contrib/md5.h b/apt-pkg/contrib/md5.h index e280d714e..247b3fab9 100644 --- a/apt-pkg/contrib/md5.h +++ b/apt-pkg/contrib/md5.h @@ -23,9 +23,6 @@ #ifndef APTPKG_MD5_H #define APTPKG_MD5_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/md5.h" -#endif #include #include diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h index e329b167a..46a3f2990 100644 --- a/apt-pkg/contrib/mmap.h +++ b/apt-pkg/contrib/mmap.h @@ -26,7 +26,6 @@ #define PKGLIB_MMAP_H #ifdef __GNUG__ -#pragma interface "apt-pkg/mmap.h" #endif #include diff --git a/apt-pkg/contrib/progress.h b/apt-pkg/contrib/progress.h index 20caf4cdf..3f87f4d3a 100644 --- a/apt-pkg/contrib/progress.h +++ b/apt-pkg/contrib/progress.h @@ -22,7 +22,6 @@ #define PKGLIB_PROGRESS_H #ifdef __GNUG__ -#pragma interface "apt-pkg/progress.h" #endif #include diff --git a/apt-pkg/contrib/sha1.h b/apt-pkg/contrib/sha1.h index db8ca7893..010ef802e 100644 --- a/apt-pkg/contrib/sha1.h +++ b/apt-pkg/contrib/sha1.h @@ -14,10 +14,6 @@ #ifndef APTPKG_SHA1_H #define APTPKG_SHA1_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/sha1.h" -#endif - #include #include diff --git a/apt-pkg/contrib/sha256.h b/apt-pkg/contrib/sha256.h index 9e88f5ece..01b638d56 100644 --- a/apt-pkg/contrib/sha256.h +++ b/apt-pkg/contrib/sha256.h @@ -14,10 +14,6 @@ #ifndef APTPKG_SHA256_H #define APTPKG_SHA256_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/sha256.h" -#endif - #include #include #include diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index 6ec2b7811..b8553ab58 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -16,9 +16,7 @@ #ifndef STRUTL_H #define STRUTL_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/strutl.h" -#endif + #include #include diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h index a1b9583a4..2bc963567 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@ -16,9 +16,7 @@ #ifndef PKGLIB_DEBINDEXFILE_H #define PKGLIB_DEBINDEXFILE_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/debindexfile.h" -#endif + #include diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h index 2b9922987..c021a1b5a 100644 --- a/apt-pkg/deb/debmetaindex.h +++ b/apt-pkg/deb/debmetaindex.h @@ -2,10 +2,6 @@ #ifndef PKGLIB_DEBMETAINDEX_H #define PKGLIB_DEBMETAINDEX_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/debmetaindex.h" -#endif - #include #include diff --git a/apt-pkg/deb/debrecords.h b/apt-pkg/deb/debrecords.h index efef2e588..3f1956164 100644 --- a/apt-pkg/deb/debrecords.h +++ b/apt-pkg/deb/debrecords.h @@ -14,10 +14,6 @@ #ifndef PKGLIB_DEBRECORDS_H #define PKGLIB_DEBRECORDS_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/debrecords.h" -#endif - #include #include diff --git a/apt-pkg/deb/debsrcrecords.h b/apt-pkg/deb/debsrcrecords.h index f899993df..51e063812 100644 --- a/apt-pkg/deb/debsrcrecords.h +++ b/apt-pkg/deb/debsrcrecords.h @@ -11,9 +11,6 @@ #ifndef PKGLIB_DEBSRCRECORDS_H #define PKGLIB_DEBSRCRECORDS_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/debsrcrecords.h" -#endif #include #include diff --git a/apt-pkg/deb/debsystem.h b/apt-pkg/deb/debsystem.h index 84e57e74a..5f9995e5d 100644 --- a/apt-pkg/deb/debsystem.h +++ b/apt-pkg/deb/debsystem.h @@ -10,10 +10,6 @@ #ifndef PKGLIB_DEBSYSTEM_H #define PKGLIB_DEBSYSTEM_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/debsystem.h" -#endif - #include class debStatusIndex; diff --git a/apt-pkg/deb/debversion.h b/apt-pkg/deb/debversion.h index 00a8832a8..56fb67887 100644 --- a/apt-pkg/deb/debversion.h +++ b/apt-pkg/deb/debversion.h @@ -12,9 +12,7 @@ #ifndef PKGLIB_DEBVERSION_H #define PKGLIB_DEBVERSION_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/debversion.h" -#endif + #include diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 2ff8a9ac7..45eb6b15b 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -10,10 +10,6 @@ #ifndef PKGLIB_DPKGPM_H #define PKGLIB_DPKGPM_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/dpkgpm.h" -#endif - #include #include #include diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 58d1d25e5..70bc9f086 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -8,9 +8,6 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#ifdef __GNUG__ -#pragma implementation "apt-pkg/depcache.h" -#endif #include #include #include diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 6d51920e9..929fe93c9 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -38,9 +38,6 @@ #ifndef PKGLIB_DEPCACHE_H #define PKGLIB_DEPCACHE_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/depcache.h" -#endif #include #include diff --git a/apt-pkg/indexfile.h b/apt-pkg/indexfile.h index 61049f4bd..f1c0268b8 100644 --- a/apt-pkg/indexfile.h +++ b/apt-pkg/indexfile.h @@ -21,9 +21,6 @@ #ifndef PKGLIB_INDEXFILE_H #define PKGLIB_INDEXFILE_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/indexfile.h" -#endif #include #include diff --git a/apt-pkg/indexrecords.h b/apt-pkg/indexrecords.h index 414faceaa..73c8b4c02 100644 --- a/apt-pkg/indexrecords.h +++ b/apt-pkg/indexrecords.h @@ -6,7 +6,6 @@ #define PKGLIB_INDEXRECORDS_H #ifdef __GNUG__ -#pragma interface "apt-pkg/indexrecords.h" #endif #include #include diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h index 8ebf23541..2b87d7da9 100644 --- a/apt-pkg/metaindex.h +++ b/apt-pkg/metaindex.h @@ -1,9 +1,6 @@ #ifndef PKGLIB_METAINDEX_H #define PKGLIB_METAINDEX_H -/* #ifdef __GNUG__ */ -/* #pragma interface "apt-pkg/metaindex.h" */ -/* #endif */ #include #include diff --git a/apt-pkg/orderlist.h b/apt-pkg/orderlist.h index d13301bcf..bbceb3879 100644 --- a/apt-pkg/orderlist.h +++ b/apt-pkg/orderlist.h @@ -16,9 +16,6 @@ #ifndef PKGLIB_ORDERLIST_H #define PKGLIB_ORDERLIST_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/orderlist.h" -#endif #include diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index f64637d03..35cdca913 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -23,9 +23,6 @@ #ifndef PKGLIB_PACKAGEMANAGER_H #define PKGLIB_PACKAGEMANAGER_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/packagemanager.h" -#endif #include #include diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 9926befe9..5672e60a4 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -20,11 +20,6 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#ifdef __GNUG__ -#pragma implementation "apt-pkg/pkgcache.h" -#pragma implementation "apt-pkg/cacheiterators.h" -#endif - #include #include #include diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 587d97534..8e7fc252c 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -19,9 +19,6 @@ #ifndef PKGLIB_PKGCACHE_H #define PKGLIB_PKGCACHE_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/pkgcache.h" -#endif #include #include diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index 9a729eea4..70616c0a8 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -19,9 +19,6 @@ #ifndef PKGLIB_PKGCACHEGEN_H #define PKGLIB_PKGCACHEGEN_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/pkgcachegen.h" -#endif #include diff --git a/apt-pkg/pkgrecords.h b/apt-pkg/pkgrecords.h index 08f004414..d431101fe 100644 --- a/apt-pkg/pkgrecords.h +++ b/apt-pkg/pkgrecords.h @@ -17,9 +17,6 @@ #ifndef PKGLIB_PKGRECORDS_H #define PKGLIB_PKGRECORDS_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/pkgrecords.h" -#endif #include #include diff --git a/apt-pkg/pkgsystem.h b/apt-pkg/pkgsystem.h index a7d555140..246762e0b 100644 --- a/apt-pkg/pkgsystem.h +++ b/apt-pkg/pkgsystem.h @@ -37,9 +37,6 @@ #ifndef PKGLIB_PKGSYSTEM_H #define PKGLIB_PKGSYSTEM_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/pkgsystem.h" -#endif #include #include diff --git a/apt-pkg/policy.h b/apt-pkg/policy.h index 40ebd3f70..d5f3b2f75 100644 --- a/apt-pkg/policy.h +++ b/apt-pkg/policy.h @@ -33,9 +33,6 @@ #ifndef PKGLIB_POLICY_H #define PKGLIB_POLICY_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/policy.h" -#endif #include #include diff --git a/apt-pkg/sourcelist.h b/apt-pkg/sourcelist.h index 123ae6984..b9e4389ed 100644 --- a/apt-pkg/sourcelist.h +++ b/apt-pkg/sourcelist.h @@ -35,9 +35,6 @@ using std::string; using std::vector; -#ifdef __GNUG__ -#pragma interface "apt-pkg/sourcelist.h" -#endif class pkgAquire; class pkgSourceList diff --git a/apt-pkg/srcrecords.h b/apt-pkg/srcrecords.h index 3e2112549..99cbc6060 100644 --- a/apt-pkg/srcrecords.h +++ b/apt-pkg/srcrecords.h @@ -13,9 +13,6 @@ #ifndef PKGLIB_SRCRECORDS_H #define PKGLIB_SRCRECORDS_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/srcrecords.h" -#endif #include #include diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h index 70381ad13..05c6aa701 100644 --- a/apt-pkg/tagfile.h +++ b/apt-pkg/tagfile.h @@ -20,9 +20,6 @@ #ifndef PKGLIB_TAGFILE_H #define PKGLIB_TAGFILE_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/tagfile.h" -#endif #include #include diff --git a/apt-pkg/vendor.h b/apt-pkg/vendor.h index 033bb96e8..2d39fd15f 100644 --- a/apt-pkg/vendor.h +++ b/apt-pkg/vendor.h @@ -4,9 +4,6 @@ #include #include -#ifdef __GNUG__ -#pragma interface "apt-pkg/vendor.h" -#endif using std::string; diff --git a/apt-pkg/vendorlist.h b/apt-pkg/vendorlist.h index 7f96fc766..ff2f4ed5d 100644 --- a/apt-pkg/vendorlist.h +++ b/apt-pkg/vendorlist.h @@ -21,9 +21,6 @@ using std::string; using std::vector; -#ifdef __GNUG__ -#pragma interface "apt-pkg/vendorlist.h" -#endif class pkgVendorList { diff --git a/apt-pkg/version.h b/apt-pkg/version.h index 071dba3e2..49c53a93a 100644 --- a/apt-pkg/version.h +++ b/apt-pkg/version.h @@ -20,9 +20,6 @@ #ifndef PKGLIB_VERSION_H #define PKGLIB_VERSION_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/version.h" -#endif #include #include diff --git a/apt-pkg/versionmatch.h b/apt-pkg/versionmatch.h index 7ca39cbe8..fe264aa46 100644 --- a/apt-pkg/versionmatch.h +++ b/apt-pkg/versionmatch.h @@ -31,9 +31,6 @@ #ifndef PKGLIB_VERSIONMATCH_H #define PKGLIB_VERSIONMATCH_H -#ifdef __GNUG__ -#pragma interface "apt-pkg/versionmatch.h" -#endif #include #include -- cgit v1.2.3 From be009af27add7c49dfbb585a4d238a72d0318be0 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 2 Oct 2006 16:19:30 +0200 Subject: * remove the remaining #ifdef __GNUG__ bits --- apt-pkg/contrib/hashes.h | 2 -- apt-pkg/contrib/mmap.h | 2 -- apt-pkg/indexrecords.h | 3 +-- 3 files changed, 1 insertion(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h index 263854054..b09ea9f6b 100644 --- a/apt-pkg/contrib/hashes.h +++ b/apt-pkg/contrib/hashes.h @@ -13,8 +13,6 @@ #ifndef APTPKG_HASHES_H #define APTPKG_HASHES_H -#ifdef __GNUG__ -#endif #include #include diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h index 46a3f2990..19cf7582d 100644 --- a/apt-pkg/contrib/mmap.h +++ b/apt-pkg/contrib/mmap.h @@ -25,8 +25,6 @@ #ifndef PKGLIB_MMAP_H #define PKGLIB_MMAP_H -#ifdef __GNUG__ -#endif #include #include diff --git a/apt-pkg/indexrecords.h b/apt-pkg/indexrecords.h index 73c8b4c02..ac0df470c 100644 --- a/apt-pkg/indexrecords.h +++ b/apt-pkg/indexrecords.h @@ -5,8 +5,7 @@ #ifndef PKGLIB_INDEXRECORDS_H #define PKGLIB_INDEXRECORDS_H -#ifdef __GNUG__ -#endif + #include #include -- cgit v1.2.3 From ca17f356866363d22d3263201f22cb0c45a46623 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 2 Oct 2006 16:47:38 +0200 Subject: * removed the remaining #ifdef __GNUG__ that are no longer required --- apt-pkg/contrib/fileutl.h | 2 -- apt-pkg/contrib/progress.h | 2 -- 2 files changed, 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index fcb26938f..48bd95537 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -21,8 +21,6 @@ #ifndef PKGLIB_FILEUTL_H #define PKGLIB_FILEUTL_H -#ifdef __GNUG__ -#endif #include diff --git a/apt-pkg/contrib/progress.h b/apt-pkg/contrib/progress.h index 3f87f4d3a..7dd004f7e 100644 --- a/apt-pkg/contrib/progress.h +++ b/apt-pkg/contrib/progress.h @@ -21,8 +21,6 @@ #ifndef PKGLIB_PROGRESS_H #define PKGLIB_PROGRESS_H -#ifdef __GNUG__ -#endif #include #include -- cgit v1.2.3 From 19ec5723caa6ea6ab196a9e960c769ded4ee0d28 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 1 Dec 2006 17:03:43 +0100 Subject: * apt-pkg/deb/debsrcrecords.{cc,h}: - cast correct --- apt-pkg/deb/debsrcrecords.cc | 2 +- apt-pkg/deb/debsrcrecords.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc index e1c6427e8..7d5dab747 100644 --- a/apt-pkg/deb/debsrcrecords.cc +++ b/apt-pkg/deb/debsrcrecords.cc @@ -40,7 +40,7 @@ const char **debSrcRecordParser::Binaries() { delete [] Buffer; // allocate new size based on buffer (but never smaller than 4000) - BufSize = max((unsigned long)4000, max(Bins.length()+1,2*BufSize)); + BufSize = max((unsigned int)4000, max((unsigned int)Bins.length()+1,2*BufSize)); Buffer = new char[BufSize]; } diff --git a/apt-pkg/deb/debsrcrecords.h b/apt-pkg/deb/debsrcrecords.h index f4e2cb46c..7645dc564 100644 --- a/apt-pkg/deb/debsrcrecords.h +++ b/apt-pkg/deb/debsrcrecords.h @@ -27,7 +27,7 @@ class debSrcRecordParser : public pkgSrcRecords::Parser char *StaticBinList[400]; unsigned long iOffset; char *Buffer; - unsigned long BufSize; + unsigned int BufSize; public: -- cgit v1.2.3 From 7106240056767caad5a55fe9c542842065cb5829 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 7 Dec 2006 11:10:32 +0100 Subject: * apt-pkg/acquire-item.cc: - merged the NMU pdiff fix and make the code a bit more readable --- apt-pkg/acquire-item.cc | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index a51b6f12d..6831abd54 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -270,15 +270,8 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) } } - // no information how to get the patches, bail out - if(!found) - { - if(Debug) - std::clog << "Can't find a patch in the index file" << std::endl; - // Failed will queue a big package file - Failed("", NULL); - } - else + // we have something, queue the next diff + if(found) { // queue the diffs new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc, @@ -290,6 +283,11 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) } } + // Nothing found, report and return false + // Failing here is ok, if we return false later, the full + // IndexFile is queued + if(Debug) + std::clog << "Can't find a patch in the index file" << std::endl; return false; } -- cgit v1.2.3 From 14443594b5fdd5a99cb94434bddfbae098e83ecd Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 7 Dec 2006 14:42:57 +0100 Subject: * apt-pkg/acquire-item.cc - more usefull description of the downloaded patches --- apt-pkg/acquire-item.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 46c9d6c2c..0419f5ffd 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -274,6 +274,9 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) if(found) { // queue the diffs + int last_space = Description.rfind(" "); + if(last_space != string::npos) + Description.erase(last_space, Description.size()-last_space); new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc, ExpectedMD5, available_patches); Complete = false; @@ -354,7 +357,7 @@ pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner, Debug = _config->FindB("Debug::pkgAcquire::Diffs",false); - Desc.Description = URIDesc; + Description = URIDesc; Desc.Owner = this; Desc.ShortDesc = ShortDesc; @@ -463,7 +466,7 @@ bool pkgAcqIndexDiffs::QueueNextDiff() // queue the right diff Desc.URI = string(RealURI) + ".diff/" + available_patches[0].file + ".gz"; - Desc.Description = available_patches[0].file + string(".pdiff"); + Desc.Description = Description + " " + available_patches[0].file + string(".pdiff"); DestFile = _config->FindDir("Dir::State::lists") + "partial/"; DestFile += URItoFileName(RealURI + ".diff/" + available_patches[0].file); -- cgit v1.2.3 From 07494f6580dd689c1d82d8dc2f7dbbcfedaf6e52 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 8 Dec 2006 18:21:59 +0000 Subject: 0.6.46.3ubuntu2 change as uploaded: fix dist-upgrade --- apt-pkg/algorithms.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index f50c52a32..723c8ea3a 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -986,6 +986,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) } if (Debug) clog << " Will not break " << Pkg.Name() << " as stated in Breaks field in " << I.Name() < Date: Mon, 18 Dec 2006 11:55:43 +0100 Subject: * apt-pkg/depcache.cc: - never mark required packages as garbage --- apt-pkg/depcache.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 2bae94026..3dc9bda35 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1273,6 +1273,11 @@ bool pkgDepCache::Sweep() { StateCache &state=PkgState[p->ID]; + // skip required packages + if (!p.CurrentVer().end() && + (p.CurrentVer()->Priority == pkgCache::State::Required)) + continue; + // if it is not marked and it is installed, it's garbage if(!state.Marked && (!p.CurrentVer().end() || state.Install())) { -- cgit v1.2.3 From e6756cdefaad7818f4a3bb95e7a935bc6cf8ed2e Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 13 Mar 2007 13:38:12 +0100 Subject: * apt-pkg/packagemanager.cc: - use ActionGroup() to protect FixMissing() --- apt-pkg/packagemanager.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index b0dd43629..1e57d6455 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -95,9 +95,10 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, be downloaded. */ bool pkgPackageManager::FixMissing() { + pkgDepCache::ActionGroup group(Cache); pkgProblemResolver Resolve(&Cache); List->SetFileList(FileNames); - + bool Bad = false; for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { -- cgit v1.2.3 From 92b9551f03035f5a875a44588a318773f652da6a Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 14 Mar 2007 11:45:33 +0100 Subject: * apt-pkg/depcache.cc: - added APT::Never-MarkAuto-Section variable - that will consider dependencies of packages in this section manual --- apt-pkg/depcache.cc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 3dc9bda35..f5673dd5d 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -907,7 +907,22 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, std::clog << "Installing " << InstPkg.Name() << " as dep of " << Pkg.Name() << std::endl; - MarkInstall(InstPkg, true, Depth + 1, false); + // now check if we should consider it a automatic dependency or not + string sec = _config->Find("APT::Never-MarkAuto-Section",""); + if(Pkg.Section() && (string(Pkg.Section()) == sec)) + { + if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true) + std::clog << "Setting NOT as auto-installed because its a direct dep of a package in section " << sec << std::endl; + MarkInstall(InstPkg,true,Depth + 1, true); + } + else + { + // mark automatic dependency + MarkInstall(InstPkg,true,Depth + 1, false); + // Set the autoflag, after MarkInstall because MarkInstall unsets it + if (P->CurrentVer == 0) + PkgState[InstPkg->ID].Flags |= Flag::Auto; + } } continue; } -- cgit v1.2.3