diff options
Diffstat (limited to 'apt-pkg/depcache.cc')
-rw-r--r-- | apt-pkg/depcache.cc | 99 |
1 files changed, 96 insertions, 3 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index dd1c794c9..e30baa4b2 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -16,7 +16,13 @@ #include <apt-pkg/error.h> #include <apt-pkg/sptr.h> #include <apt-pkg/algorithms.h> - + +#include <apt-pkg/fileutl.h> +#include <apt-pkg/configuration.h> +#include <apt-pkg/tagfile.h> + +#include <iostream> +#include <sstream> #include <apti18n.h> /*}}}*/ @@ -72,7 +78,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(); @@ -99,6 +108,78 @@ 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) +{ + // 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"; + + 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++) { + + // 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) { + if(_config->FindI("Debug::pkgAutoRemove",false)) + std::clog << "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() + << "\nRemove-Reason: " + << (int)(PkgState[pkg->ID].AutomaticRemove) << "\n\n"; + StateFile.Write(ostr.str().c_str(), ostr.str().size()); + } + } + return true; +} + // DepCache::CheckDep - Checks a single dependency /*{{{*/ // --------------------------------------------------------------------- /* This first checks the dependency against the main target package and @@ -450,6 +531,8 @@ void pkgDepCache::Update(OpProgress *Prog) AddStates(I); } + readStateFile(Prog); + if (Prog != 0) Prog->Progress(Done); } @@ -585,7 +668,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); @@ -757,6 +841,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 /*{{{*/ // --------------------------------------------------------------------- /* */ |