summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <kalnischkies@gmail.com>2010-02-27 17:01:12 +0100
committerDavid Kalnischkies <kalnischkies@gmail.com>2010-02-27 17:01:12 +0100
commite0b94b97b179812e5a0b3b72ea9fcae106d545c5 (patch)
tree27c422432386b089e85853c3b97f45ece9152239
parent75ce206243e409b170d06723430eb85a4a747882 (diff)
Enable the AutoRemover to talk "Multi-Arch" by marking all pseudo
packages in a group if one is marked. The auto-installed flag is from now on Architecture bound: A section without an architecture tag will be treated as applying to all architectures - the next write operation will take care of this by creating separate sections for the architectures.
-rw-r--r--apt-pkg/depcache.cc170
-rw-r--r--apt-pkg/depcache.h4
2 files changed, 109 insertions, 65 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index eeb74a434..45c614c6f 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -165,34 +165,46 @@ bool pkgDepCache::Init(OpProgress *Prog)
bool pkgDepCache::readStateFile(OpProgress *Prog) /*{{{*/
{
FileFd state_file;
- string state = _config->FindDir("Dir::State") + "extended_states";
+ string const state = _config->FindDir("Dir::State") + "extended_states";
if(FileExists(state)) {
state_file.Open(state, FileFd::ReadOnly);
- int file_size = state_file.Size();
+ int const file_size = state_file.Size();
if(Prog != NULL)
Prog->OverallProgress(0, file_size, 1,
_("Reading state information"));
pkgTagFile tagfile(&state_file);
pkgTagSection section;
- int amt=0;
- bool debug_autoremove=_config->FindB("Debug::pkgAutoRemove",false);
+ int amt = 0;
+ bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
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("Auto-Installed", 0);
- if(reason > 0)
- PkgState[pkg->ID].Flags |= Flag::Auto;
- if(debug_autoremove)
- std::cout << "Auto-Installed : " << pkgname << std::endl;
- amt+=section.size();
- if(Prog != NULL)
- Prog->OverallProgress(amt, file_size, 1,
- _("Reading state information"));
+ string const pkgname = section.FindS("Package");
+ string pkgarch = section.FindS("Architecture");
+ if (pkgarch.empty() == true)
+ pkgarch = "any";
+ pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch);
+ // Silently ignore unknown packages and packages with no actual version.
+ if(pkg.end() == true || pkg->VersionList == 0)
+ continue;
+
+ short const reason = section.FindI("Auto-Installed", 0);
+ if(reason > 0)
+ {
+ PkgState[pkg->ID].Flags |= Flag::Auto;
+ if (unlikely(debug_autoremove))
+ std::cout << "Auto-Installed : " << pkg.FullName() << std::endl;
+ if (pkgarch == "any")
+ {
+ pkgCache::GrpIterator G = pkg.Group();
+ for (pkg = G.NextPkg(pkg); pkg.end() != true; pkg = G.NextPkg(pkg))
+ if (pkg->VersionList != 0)
+ PkgState[pkg->ID].Flags |= Flag::Auto;
+ }
}
+ amt += section.size();
+ if(Prog != NULL)
+ Prog->OverallProgress(amt, file_size, 1,
+ _("Reading state information"));
}
if(Prog != NULL)
Prog->OverallProgress(file_size, file_size, 1,
@@ -204,13 +216,13 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) /*{{{*/
/*}}}*/
bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/
{
- bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
+ bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
if(debug_autoremove)
std::clog << "pkgDepCache::writeStateFile()" << std::endl;
FileFd StateFile;
- string state = _config->FindDir("Dir::State") + "extended_states";
+ string const state = _config->FindDir("Dir::State") + "extended_states";
// if it does not exist, create a empty one
if(!FileExists(state))
@@ -225,7 +237,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/
state.c_str());
FILE *OutFile;
- string outfile = state + ".tmp";
+ string const outfile = state + ".tmp";
if((OutFile = fopen(outfile.c_str(),"w")) == NULL)
return _error->Error(_("Failed to write temporary StateFile %s"),
outfile.c_str());
@@ -236,46 +248,54 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/
std::set<string> pkgs_seen;
const char *nullreorderlist[] = {0};
while(tagfile.Step(section)) {
- string pkgname = section.FindS("Package");
+ string const pkgname = section.FindS("Package");
+ string pkgarch = section.FindS("Architecture");
+ if (pkgarch.empty() == true)
+ pkgarch = "native";
// Silently ignore unknown packages and packages with no actual
// version.
- pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname);
+ pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch);
if(pkg.end() || pkg.VersionList().end())
continue;
- bool newAuto = (PkgState[pkg->ID].Flags & Flag::Auto);
+ bool const newAuto = (PkgState[pkg->ID].Flags & Flag::Auto);
if(_config->FindB("Debug::pkgAutoRemove",false))
std::clog << "Update existing AutoInstall info: "
- << pkg.Name() << std::endl;
- TFRewriteData rewrite[2];
- rewrite[0].Tag = "Auto-Installed";
- rewrite[0].Rewrite = newAuto ? "1" : "0";
+ << pkg.FullName() << std::endl;
+ TFRewriteData rewrite[3];
+ rewrite[0].Tag = "Architecture";
+ rewrite[0].Rewrite = pkg.Arch();
rewrite[0].NewTag = 0;
- rewrite[1].Tag = 0;
+ rewrite[1].Tag = "Auto-Installed";
+ rewrite[1].Rewrite = newAuto ? "1" : "0";
+ rewrite[1].NewTag = 0;
+ rewrite[2].Tag = 0;
TFRewrite(OutFile, section, nullreorderlist, rewrite);
fprintf(OutFile,"\n");
- pkgs_seen.insert(pkgname);
+ pkgs_seen.insert(pkg.FullName());
}
// then write the ones we have not seen yet
std::ostringstream ostr;
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 (pkgs_seen.find(pkg.FullName()) != pkgs_seen.end()) {
if(debug_autoremove)
- std::clog << "Skipping already written " << pkg.Name() << std::endl;
+ std::clog << "Skipping already written " << pkg.FullName() << std::endl;
continue;
}
- // skip not installed ones if requested
- if(InstalledOnly && pkg->CurrentVer == 0)
- continue;
+ // skip not installed ones if requested
+ if(InstalledOnly && pkg->CurrentVer == 0)
+ continue;
+ const char* const pkgarch = pkg.Arch();
+ if (strcmp(pkgarch, "all") == 0)
+ continue;
if(debug_autoremove)
- std::clog << "Writing new AutoInstall: "
- << pkg.Name() << std::endl;
+ std::clog << "Writing new AutoInstall: " << pkg.FullName() << std::endl;
ostr.str(string(""));
- ostr << "Package: " << pkg.Name()
+ ostr << "Package: " << pkg.Name()
+ << "\nArchitecture: " << pkgarch
<< "\nAuto-Installed: 1\n\n";
fprintf(OutFile,"%s",ostr.str().c_str());
- fprintf(OutFile,"\n");
}
}
fclose(OutFile);
@@ -1426,7 +1446,7 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
// debug output
if(debug_autoremove && PkgState[p->ID].Flags & Flag::Auto)
- std::clog << "AutoDep: " << p.Name() << std::endl;
+ std::clog << "AutoDep: " << p.FullName() << std::endl;
}
// init vars
@@ -1460,13 +1480,18 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
// MarkPackage - 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)
+ bool const &follow_recommends,
+ bool const &follow_suggests)
{
pkgDepCache::StateCache &state = PkgState[pkg->ID];
- VerIterator currver = pkg.CurrentVer();
- VerIterator candver = state.CandidateVerIter(*this);
- VerIterator instver = state.InstVerIter(*this);
+
+ // if we are marked already we are done
+ if(state.Marked)
+ return;
+
+ VerIterator const currver = pkg.CurrentVer();
+ VerIterator const candver = state.CandidateVerIter(*this);
+ VerIterator const instver = state.InstVerIter(*this);
#if 0
// If a package was garbage-collected but is now being marked, we
@@ -1492,15 +1517,11 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
!(ver == currver && instver.end() && !ver.end()))
return;
- // if we are marked already we are done
- if(state.Marked)
- return;
+ bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove", false);
- bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove", false);
-
if(debug_autoremove)
{
- std::clog << "Marking: " << pkg.Name();
+ std::clog << "Marking: " << pkg.FullName();
if(!ver.end())
std::clog << " " << ver.VerStr();
if(!currver.end())
@@ -1512,8 +1533,34 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
state.Marked=true;
- if(!ver.end())
+ if(ver.end() == true)
+ return;
+
+ // If the version belongs to a Multi-Arch all package
+ // we will mark all others in this Group with this version also
+ // Beware: We compare versions here the lazy way: string comparision
+ // this is bad if multiple repositories provide different versions
+ // of the package with an identical version number - but even in this
+ // case the dependencies are likely the same.
+ if (ver->MultiArch == pkgCache::Version::All &&
+ strcmp(ver.Arch(true), "all") == 0)
{
+ GrpIterator G = pkg.Group();
+ const char* const VerStr = ver.VerStr();
+ for (PkgIterator P = G.FindPkg("any");
+ P.end() != true; P = G.NextPkg(P))
+ {
+ for (VerIterator V = P.VersionList();
+ V.end() != true; ++V)
+ {
+ if (strcmp(VerStr, V.VerStr()) != 0)
+ continue;
+ MarkPackage(P, V, follow_recommends, follow_suggests);
+ break;
+ }
+ }
+ }
+
for(DepIterator d = ver.DependsList(); !d.end(); ++d)
{
if(d->Type == Dep::Depends ||
@@ -1531,10 +1578,9 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
{
if(debug_autoremove)
{
- std::clog << "Following dep: " << d.ParentPkg().Name()
+ std::clog << "Following dep: " << d.ParentPkg().FullName()
<< " " << d.ParentVer().VerStr() << " "
- << d.DepType() << " "
- << d.TargetPkg().Name();
+ << d.DepType() << " " << d.TargetPkg().FullName();
if((d->CompareOp & ~pkgCache::Dep::Or) != pkgCache::Dep::NoOp)
{
std::clog << " (" << d.CompType() << " "
@@ -1542,7 +1588,7 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
}
std::clog << std::endl;
}
- MarkPackage(V.ParentPkg(), V,
+ MarkPackage(V.ParentPkg(), V,
follow_recommends, follow_suggests);
}
}
@@ -1555,17 +1601,16 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
{
if(debug_autoremove)
{
- std::clog << "Following dep: " << d.ParentPkg().Name()
- << " " << d.ParentVer().VerStr() << " "
- << d.DepType() << " "
- << d.TargetPkg().Name();
+ std::clog << "Following dep: " << d.ParentPkg().FullName() << " "
+ << d.ParentVer().VerStr() << " "
+ << d.DepType() << " " << d.TargetPkg().FullName() << " ";
if((d->CompareOp & ~pkgCache::Dep::Or) != pkgCache::Dep::NoOp)
{
std::clog << " (" << d.CompType() << " "
<< d.TargetVer() << ")";
}
std::clog << ", provided by "
- << prv.OwnerPkg().Name() << " "
+ << prv.OwnerPkg().FullName() << " "
<< prv.OwnerVer().VerStr()
<< std::endl;
}
@@ -1576,7 +1621,6 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
}
}
}
- }
}
/*}}}*/
bool pkgDepCache::Sweep() /*{{{*/
@@ -1598,7 +1642,7 @@ bool pkgDepCache::Sweep() /*{{{*/
{
state.Garbage=true;
if(debug_autoremove)
- std::cout << "Garbage: " << p.Name() << std::endl;
+ std::cout << "Garbage: " << p.FullName() << std::endl;
}
}
diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h
index ab1021a44..23b29cc13 100644
--- a/apt-pkg/depcache.h
+++ b/apt-pkg/depcache.h
@@ -79,8 +79,8 @@ class pkgDepCache : protected pkgCache::Namespace
*/
void MarkPackage(const pkgCache::PkgIterator &pkg,
const pkgCache::VerIterator &ver,
- bool follow_recommends,
- bool follow_suggests);
+ bool const &follow_recommends,
+ bool const &follow_suggests);
/** \brief Update the Marked field of all packages.
*