qsort(List,Count,sizeof(*List),PrioComp);
}
/*}}}*/
- if(Cache[p].InstallReason==pkgDepCache::Manual ||
+
+
+// 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);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+bool pkgMarkUsed(pkgDepCache &Cache)
+{
+ bool follow_recommends;
+ bool follow_suggests;
+
+ // init the states
+ for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p)
+ {
+ Cache[p].Marked=false;
+ Cache[p].Garbage=false;
+ }
+
+ // init vars
+ follow_recommends=_config->FindB("APT::AutoRemove::RecommendsImportant",false);
+ follow_suggests=_config->FindB("APT::AutoRemove::SuggestsImportend", 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(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);
+ }
+ }
+
+
+ // 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;
+}
// Find the proper cache slot
StateCache &State = PkgState[I->ID];
State.iFlags = 0;
- State.InstallReason = Manual;
-
+
// Figure out the install version
State.CandidateVer = GetCandidateVer(I);
State.InstallVer = I.CurrentVer();
}
/*}}}*/
- short reason = section.FindI("Install-Reason",pkgDepCache::Manual);
- PkgState[pkg->ID].InstallReason = (ChangedReason)reason;
+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 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()) {
- // clear out no longer installed pkg
- if(PkgState[pkg->ID].Delete() || pkg.CurrentVer() == NULL)
- PkgState[pkg->ID].InstallReason = Manual;
-
- // check if we have new information
++ short reason = section.FindI("Install-Reason", 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;
+ amt+=section.size();
+ Prog->OverallProgress(amt, file_size, 1,
+ _("Reading state information"));
+ }
+ Prog->OverallProgress(file_size, file_size, 1,
+ _("Reading state information"));
+ }
+ }
+
+ return true;
+}
+
+bool pkgDepCache::writeStateFile(OpProgress *prog)
+{
+ FileFd StateFile;
+ string state = _config->FindDir("Dir::State") + "pkgstates";
+
++ 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"),
+ state.c_str());
+
+ std::ostringstream ostr;
+ for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end();pkg++) {
+
- if(_config->FindI("Debug::pkgAutoRemove",false))
- std::clog << "pkg: " << pkg.Name() << " is auto-dep" << std::endl;
- PkgState[pkg->ID].InstallReason = Libapt;
- }
-
- if(PkgState[pkg->ID].InstallReason != Manual) {
+ if(PkgState[pkg->ID].Flags & pkgCache::Flag::Auto) {
- << "\nInstall-Reason: "
- << (int)(PkgState[pkg->ID].InstallReason) << "\n\n";
++ if(_config->FindB("Debug::pkgAutoRemove",false))
++ std::clog << "AutoInstal: " << pkg.Name() << std::endl;
+ ostr.str(string(""));
+ ostr << "Package: " << pkg.Name()
++ << "\nInstall-Reason: 1\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
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
unsigned short Flags;
unsigned short iFlags; // Internal flags
- ChangedReason InstallReason;
- #if 0
- ChangedReason RemoveReason;
- #endif
+ // mark and sweep flags
+ bool Marked;
+ bool Garbage;
+
// Various tree indicators
signed char Status; // -1,0,1,2
unsigned char Mode; // ModeList
#endif
#include <string>
++#include <iostream>
#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/depcache.h>
using std::string;
// 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)
++ if(Res == Completed) {
+ Cache.writeStateFile(NULL);
-
++ }
+ return Res;
+ };
+
bool FixMissing();
pkgPackageManager(pkgDepCache *Cache);
- apt (0.6.38ubuntu1mvo1) unstable; urgency=low
-apt (0.6.39ubuntu1) breezy; urgency=low
++apt (0.6.39ubuntu1mvo1) unstable; urgency=low
+
+ * Michael Vogt
+ - Change debian/bugscript to use #!/bin/bash (Closes: #313402)
+ - Fix a incorrect example in the man-page (closes: #282918)
+ - Support architecture-specific extra overrides
+ (closes: #225947). Thanks to Anthony Towns for idea and
+ the patch, thanks to Colin Watson for testing it.
+ - better report network timeouts from the methods to the acuire code,
+ only timeout once per sources.list line
++ - support for automatic removal of unused dependencies added
+
- -- Matt Zimmerman <mdz@ubuntu.com> Tue, 28 Jun 2005 11:52:24 -0700
++ --
+
+ apt (0.6.39) unstable; urgency=low
* Welsh translation update: daf@muse.19inch.net--2005/apt--main--0--patch-6
* Merge mvo's changes from 0.6.36ubuntu1:
(closes ubuntu #9935)
-- Matt Zimmerman <mdz@debian.org> Sat, 25 Jun 2005 09:51:00 -0700
-=======
- -- Matt Zimmerman <mdz@ubuntu.com> Tue, 28 Jun 2005 11:51:09 -0700
->>>>>>> MERGE-SOURCE
--apt (0.6.38) unstable; urgency=low
--
-- * Merge michael.vogt@ubuntu.com--2005/apt--fixes--0--patch-6, a workaround
-- for the French man pages' failure to build
-- * Branch Debian and Ubuntu
-- - apt.postinst, apt-key: use the appropriate keyring
-- - debian/rules: install all keyrings
-- * Add the current Debian archive signing key (4F368D5D) to
-- debian-archive.gpg
-- * make pinning on the "component" work again (using the section of the
-- archive, we don't use per-section Release files anymore with apt-0.6)
-- (closes ubuntu #9935)
--
-- -- Matt Zimmerman <mdz@debian.org> Sat, 25 Jun 2005 09:51:00 -0700
--
-->>>>>>> MERGE-SOURCE
apt (0.6.37) breezy; urgency=low
* Merge bubulle@debian.org--2005/apt--main--0 up to patch-81