diff options
author | Michael Vogt <michael.vogt@ubuntu.com> | 2010-09-03 14:04:50 +0200 |
---|---|---|
committer | Michael Vogt <michael.vogt@ubuntu.com> | 2010-09-03 14:04:50 +0200 |
commit | 0205540433440a9ff4ad4ea4cce44c700a4b401c (patch) | |
tree | 97809e2e38482d3d7f124b30552a0936adf4d405 /cmdline | |
parent | 24baab5c477bf1e57a0b169a7bac1d2e9ab0c974 (diff) | |
parent | 2c6baa5a1f935eb3b8d4eb9fdef62e696416e27a (diff) |
merged from lp:~donkult/apt/sid
Diffstat (limited to 'cmdline')
-rw-r--r-- | cmdline/apt-cache.cc | 1016 | ||||
-rw-r--r-- | cmdline/apt-cdrom.cc | 16 | ||||
-rw-r--r-- | cmdline/apt-extracttemplates.cc | 3 | ||||
-rw-r--r-- | cmdline/apt-get.cc | 1094 | ||||
-rwxr-xr-x | cmdline/apt-key | 1 | ||||
-rwxr-xr-x | cmdline/apt-mark | 29 | ||||
-rwxr-xr-x | cmdline/apt-report-mirror-failure | 29 | ||||
-rw-r--r-- | cmdline/makefile | 6 |
8 files changed, 1141 insertions, 1053 deletions
diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 286f306cd..ba4ad1943 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -14,7 +14,10 @@ /*}}}*/ // Include Files /*{{{*/ #include <apt-pkg/error.h> +#include <cassert> #include <apt-pkg/pkgcachegen.h> +#include <apt-pkg/cachefile.h> +#include <apt-pkg/cacheset.h> #include <apt-pkg/init.h> #include <apt-pkg/progress.h> #include <apt-pkg/sourcelist.h> @@ -43,9 +46,29 @@ using namespace std; -pkgCache *GCache = 0; -pkgSourceList *SrcList = 0; +// CacheSetHelper saving virtual packages /*{{{*/ +class CacheSetHelperVirtuals: public APT::CacheSetHelper { +public: + APT::PackageSet virtualPkgs; + virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { + virtualPkgs.insert(Pkg); + return CacheSetHelper::canNotFindCandidateVer(Cache, Pkg); + } + + virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { + virtualPkgs.insert(Pkg); + return CacheSetHelper::canNotFindNewestVer(Cache, Pkg); + } + + virtual APT::VersionSet canNotFindAllVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { + virtualPkgs.insert(Pkg); + return CacheSetHelper::canNotFindAllVer(Cache, Pkg); + } + + CacheSetHelperVirtuals(bool const &ShowErrors = true, GlobalError::MsgType const &ErrorType = GlobalError::NOTICE) : CacheSetHelper(ShowErrors, ErrorType) {} +}; + /*}}}*/ // LocalitySort - Sort a version list by package file locality /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -81,15 +104,8 @@ void LocalitySort(pkgCache::DescFile **begin, // UnMet - Show unmet dependencies /*{{{*/ // --------------------------------------------------------------------- /* */ -bool UnMet(CommandLine &CmdL) +bool ShowUnMet(pkgCache::VerIterator const &V, bool const &Important) { - pkgCache &Cache = *GCache; - bool Important = _config->FindB("APT::Cache::Important",false); - - for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++) - { - for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++) - { bool Header = false; for (pkgCache::DepIterator D = V.DependsList(); D.end() == false;) { @@ -97,20 +113,19 @@ bool UnMet(CommandLine &CmdL) pkgCache::DepIterator Start; pkgCache::DepIterator End; D.GlobOr(Start,End); - - // Skip conflicts and replaces - if (End->Type != pkgCache::Dep::PreDepends && - End->Type != pkgCache::Dep::Depends && - End->Type != pkgCache::Dep::Suggests && - End->Type != pkgCache::Dep::Recommends) - continue; // Important deps only if (Important == true) if (End->Type != pkgCache::Dep::PreDepends && End->Type != pkgCache::Dep::Depends) continue; - + + // Skip conflicts and replaces + if (End->Type == pkgCache::Dep::DpkgBreaks || + End->Type == pkgCache::Dep::Replaces || + End->Type == pkgCache::Dep::Conflicts) + continue; + // Verify the or group bool OK = false; pkgCache::DepIterator RealStart = Start; @@ -139,7 +154,7 @@ bool UnMet(CommandLine &CmdL) // Oops, it failed.. if (Header == false) ioprintf(cout,_("Package %s version %s has an unmet dep:\n"), - P.Name(),V.VerStr()); + V.ParentPkg().FullName(true).c_str(),V.VerStr()); Header = true; // Print out the dep type @@ -149,7 +164,7 @@ bool UnMet(CommandLine &CmdL) Start = RealStart; do { - cout << Start.TargetPkg().Name(); + cout << Start.TargetPkg().FullName(true); if (Start.TargetVer() != 0) cout << " (" << Start.CompType() << " " << Start.TargetVer() << ")"; @@ -161,9 +176,33 @@ bool UnMet(CommandLine &CmdL) while (1); cout << endl; - } - } - } + } + return true; +} +bool UnMet(CommandLine &CmdL) +{ + bool const Important = _config->FindB("APT::Cache::Important",false); + + pkgCacheFile CacheFile; + if (unlikely(CacheFile.GetPkgCache() == NULL)) + return false; + + if (CmdL.FileSize() <= 1) + { + for (pkgCache::PkgIterator P = CacheFile.GetPkgCache()->PkgBegin(); P.end() == false; P++) + for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V) + if (ShowUnMet(V, Important) == false) + return false; + } + else + { + CacheSetHelperVirtuals helper(true, GlobalError::NOTICE); + APT::VersionSet verset = APT::VersionSet::FromCommandLine(CacheFile, CmdL.FileList + 1, + APT::VersionSet::CANDIDATE, helper); + for (APT::VersionSet::iterator V = verset.begin(); V != verset.end(); ++V) + if (ShowUnMet(V, Important) == false) + return false; + } return true; } /*}}}*/ @@ -171,18 +210,14 @@ bool UnMet(CommandLine &CmdL) // --------------------------------------------------------------------- /* */ bool DumpPackage(CommandLine &CmdL) -{ - pkgCache &Cache = *GCache; - for (const char **I = CmdL.FileList + 1; *I != 0; I++) - { - pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); - if (Pkg.end() == true) - { - _error->Warning(_("Unable to locate package %s"),*I); - continue; - } +{ + pkgCacheFile CacheFile; + APT::CacheSetHelper helper(true, GlobalError::NOTICE); + APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1, helper); - cout << "Package: " << Pkg.Name() << endl; + for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) + { + cout << "Package: " << Pkg.FullName(true) << endl; cout << "Versions: " << endl; for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++) { @@ -204,7 +239,7 @@ bool DumpPackage(CommandLine &CmdL) cout << "Reverse Depends: " << endl; for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() != true; D++) { - cout << " " << D.ParentPkg().Name() << ',' << D.TargetPkg().Name(); + cout << " " << D.ParentPkg().FullName(true) << ',' << D.TargetPkg().FullName(true); if (D->Version != 0) cout << ' ' << DeNull(D.TargetVer()) << endl; else @@ -216,7 +251,7 @@ bool DumpPackage(CommandLine &CmdL) { cout << Cur.VerStr() << " - "; for (pkgCache::DepIterator Dep = Cur.DependsList(); Dep.end() != true; Dep++) - cout << Dep.TargetPkg().Name() << " (" << (int)Dep->CompareOp << " " << DeNull(Dep.TargetVer()) << ") "; + cout << Dep.TargetPkg().FullName(true) << " (" << (int)Dep->CompareOp << " " << DeNull(Dep.TargetVer()) << ") "; cout << endl; } @@ -225,12 +260,12 @@ bool DumpPackage(CommandLine &CmdL) { cout << Cur.VerStr() << " - "; for (pkgCache::PrvIterator Prv = Cur.ProvidesList(); Prv.end() != true; Prv++) - cout << Prv.ParentPkg().Name() << " "; + cout << Prv.ParentPkg().FullName(true) << " "; cout << endl; } cout << "Reverse Provides: " << endl; for (pkgCache::PrvIterator Prv = Pkg.ProvidesList(); Prv.end() != true; Prv++) - cout << Prv.OwnerPkg().Name() << " " << Prv.OwnerVer().VerStr() << endl; + cout << Prv.OwnerPkg().FullName(true) << " " << Prv.OwnerVer().VerStr() << endl; } return true; @@ -241,16 +276,22 @@ bool DumpPackage(CommandLine &CmdL) /* */ bool Stats(CommandLine &Cmd) { - pkgCache &Cache = *GCache; - cout << _("Total package names: ") << Cache.Head().PackageCount << " (" << - SizeToStr(Cache.Head().PackageCount*Cache.Head().PackageSz) << ')' << endl; + pkgCacheFile CacheFile; + pkgCache *Cache = CacheFile.GetPkgCache(); + if (unlikely(Cache == NULL)) + return false; + + cout << _("Total package names: ") << Cache->Head().GroupCount << " (" << + SizeToStr(Cache->Head().GroupCount*Cache->Head().GroupSz) << ')' << endl + << _("Total package structures: ") << Cache->Head().PackageCount << " (" << + SizeToStr(Cache->Head().PackageCount*Cache->Head().PackageSz) << ')' << endl; int Normal = 0; int Virtual = 0; int NVirt = 0; int DVirt = 0; int Missing = 0; - pkgCache::PkgIterator I = Cache.PkgBegin(); + pkgCache::PkgIterator I = Cache->PkgBegin(); for (;I.end() != true; I++) { if (I->VersionList != 0 && I->ProvidesList == 0) @@ -288,33 +329,33 @@ bool Stats(CommandLine &Cmd) cout << _(" Mixed virtual packages: ") << NVirt << endl; cout << _(" Missing: ") << Missing << endl; - cout << _("Total distinct versions: ") << Cache.Head().VersionCount << " (" << - SizeToStr(Cache.Head().VersionCount*Cache.Head().VersionSz) << ')' << endl; - cout << _("Total distinct descriptions: ") << Cache.Head().DescriptionCount << " (" << - SizeToStr(Cache.Head().DescriptionCount*Cache.Head().DescriptionSz) << ')' << endl; - cout << _("Total dependencies: ") << Cache.Head().DependsCount << " (" << - SizeToStr(Cache.Head().DependsCount*Cache.Head().DependencySz) << ')' << endl; + cout << _("Total distinct versions: ") << Cache->Head().VersionCount << " (" << + SizeToStr(Cache->Head().VersionCount*Cache->Head().VersionSz) << ')' << endl; + cout << _("Total distinct descriptions: ") << Cache->Head().DescriptionCount << " (" << + SizeToStr(Cache->Head().DescriptionCount*Cache->Head().DescriptionSz) << ')' << endl; + cout << _("Total dependencies: ") << Cache->Head().DependsCount << " (" << + SizeToStr(Cache->Head().DependsCount*Cache->Head().DependencySz) << ')' << endl; - cout << _("Total ver/file relations: ") << Cache.Head().VerFileCount << " (" << - SizeToStr(Cache.Head().VerFileCount*Cache.Head().VerFileSz) << ')' << endl; - cout << _("Total Desc/File relations: ") << Cache.Head().DescFileCount << " (" << - SizeToStr(Cache.Head().DescFileCount*Cache.Head().DescFileSz) << ')' << endl; - cout << _("Total Provides mappings: ") << Cache.Head().ProvidesCount << " (" << - SizeToStr(Cache.Head().ProvidesCount*Cache.Head().ProvidesSz) << ')' << endl; + cout << _("Total ver/file relations: ") << Cache->Head().VerFileCount << " (" << + SizeToStr(Cache->Head().VerFileCount*Cache->Head().VerFileSz) << ')' << endl; + cout << _("Total Desc/File relations: ") << Cache->Head().DescFileCount << " (" << + SizeToStr(Cache->Head().DescFileCount*Cache->Head().DescFileSz) << ')' << endl; + cout << _("Total Provides mappings: ") << Cache->Head().ProvidesCount << " (" << + SizeToStr(Cache->Head().ProvidesCount*Cache->Head().ProvidesSz) << ')' << endl; // String list stats unsigned long Size = 0; unsigned long Count = 0; - for (pkgCache::StringItem *I = Cache.StringItemP + Cache.Head().StringList; - I!= Cache.StringItemP; I = Cache.StringItemP + I->NextItem) + for (pkgCache::StringItem *I = Cache->StringItemP + Cache->Head().StringList; + I!= Cache->StringItemP; I = Cache->StringItemP + I->NextItem) { Count++; - Size += strlen(Cache.StrP + I->String) + 1; + Size += strlen(Cache->StrP + I->String) + 1; } cout << _("Total globbed strings: ") << Count << " (" << SizeToStr(Size) << ')' << endl; unsigned long DepVerSize = 0; - for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++) + for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; P++) { for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++) { @@ -329,15 +370,15 @@ bool Stats(CommandLine &Cmd) unsigned long Slack = 0; for (int I = 0; I != 7; I++) - Slack += Cache.Head().Pools[I].ItemSize*Cache.Head().Pools[I].Count; + Slack += Cache->Head().Pools[I].ItemSize*Cache->Head().Pools[I].Count; cout << _("Total slack space: ") << SizeToStr(Slack) << endl; unsigned long Total = 0; - Total = Slack + Size + Cache.Head().DependsCount*Cache.Head().DependencySz + - Cache.Head().VersionCount*Cache.Head().VersionSz + - Cache.Head().PackageCount*Cache.Head().PackageSz + - Cache.Head().VerFileCount*Cache.Head().VerFileSz + - Cache.Head().ProvidesCount*Cache.Head().ProvidesSz; + Total = Slack + Size + Cache->Head().DependsCount*Cache->Head().DependencySz + + Cache->Head().VersionCount*Cache->Head().VersionSz + + Cache->Head().PackageCount*Cache->Head().PackageSz + + Cache->Head().VerFileCount*Cache->Head().VerFileSz + + Cache->Head().ProvidesCount*Cache->Head().ProvidesSz; cout << _("Total space accounted for: ") << SizeToStr(Total) << endl; return true; @@ -348,18 +389,22 @@ bool Stats(CommandLine &Cmd) /* This is worthless except fer debugging things */ bool Dump(CommandLine &Cmd) { - pkgCache &Cache = *GCache; - cout << "Using Versioning System: " << Cache.VS->Label << endl; + pkgCacheFile CacheFile; + pkgCache *Cache = CacheFile.GetPkgCache(); + if (unlikely(Cache == NULL)) + return false; + + cout << "Using Versioning System: " << Cache->VS->Label << endl; - for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++) + for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; P++) { - cout << "Package: " << P.Name() << endl; + cout << "Package: " << P.FullName(true) << endl; for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++) { cout << " Version: " << V.VerStr() << endl; cout << " File: " << V.FileList().File().FileName() << endl; for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++) - cout << " Depends: " << D.TargetPkg().Name() << ' ' << + cout << " Depends: " << D.TargetPkg().FullName(true) << ' ' << DeNull(D.TargetVer()) << endl; for (pkgCache::DescIterator D = V.DescriptionList(); D.end() == false; D++) { @@ -370,7 +415,7 @@ bool Dump(CommandLine &Cmd) } } - for (pkgCache::PkgFileIterator F = Cache.FileBegin(); F.end() == false; F++) + for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F.end() == false; F++) { cout << "File: " << F.FileName() << endl; cout << " Type: " << F.IndexType() << endl; @@ -396,18 +441,17 @@ bool Dump(CommandLine &Cmd) make this run really fast, perhaps I went a little overboard.. */ bool DumpAvail(CommandLine &Cmd) { - pkgCache &Cache = *GCache; - - pkgPolicy Plcy(&Cache); - if (ReadPinFile(Plcy) == false || ReadPinDir(Plcy) == false) + pkgCacheFile CacheFile; + pkgCache *Cache = CacheFile.GetPkgCache(); + if (unlikely(Cache == NULL || CacheFile.BuildPolicy() == false)) return false; - - unsigned long Count = Cache.HeaderP->PackageCount+1; + + unsigned long Count = Cache->HeaderP->PackageCount+1; pkgCache::VerFile **VFList = new pkgCache::VerFile *[Count]; memset(VFList,0,sizeof(*VFList)*Count); // Map versions that we want to write out onto the VerList array. - for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++) + for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; P++) { if (P->VersionList == 0) continue; @@ -415,7 +459,7 @@ bool DumpAvail(CommandLine &Cmd) /* Find the proper version to use. If the policy says there are no possible selections we return the installed version, if available.. This prevents dselect from making it obsolete. */ - pkgCache::VerIterator V = Plcy.GetCandidateVer(P); + pkgCache::VerIterator V = CacheFile.GetPolicy()->GetCandidateVer(P); if (V.end() == true) { if (P->CurrentVer == 0) @@ -460,10 +504,10 @@ bool DumpAvail(CommandLine &Cmd) LocalitySort(VFList,Count,sizeof(*VFList)); // Iterate over all the package files and write them out. - char *Buffer = new char[Cache.HeaderP->MaxVerFileSize+10]; + char *Buffer = new char[Cache->HeaderP->MaxVerFileSize+10]; for (pkgCache::VerFile **J = VFList; *J != 0;) { - pkgCache::PkgFileIterator File(Cache,(*J)->File + Cache.PkgFileP); + pkgCache::PkgFileIterator File(*Cache,(*J)->File + Cache->PkgFileP); if (File.IsOk() == false) { _error->Error(_("Package file %s is out of sync."),File.FileName()); @@ -482,7 +526,7 @@ bool DumpAvail(CommandLine &Cmd) unsigned long Pos = 0; for (; *J != 0; J++) { - if ((*J)->File + Cache.PkgFileP != File) + if ((*J)->File + Cache->PkgFileP != File) break; const pkgCache::VerFile &VF = **J; @@ -533,186 +577,129 @@ bool DumpAvail(CommandLine &Cmd) return !_error->PendingError(); } /*}}}*/ -// Depends - Print out a dependency tree /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool Depends(CommandLine &CmdL) +// ShowDepends - Helper for printing out a dependency tree /*{{{*/ +bool ShowDepends(CommandLine &CmdL, bool const RevDepends) { - pkgCache &Cache = *GCache; - SPtrArray<unsigned> Colours = new unsigned[Cache.Head().PackageCount]; - memset(Colours,0,sizeof(*Colours)*Cache.Head().PackageCount); - - for (const char **I = CmdL.FileList + 1; *I != 0; I++) - { - pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); - if (Pkg.end() == true) - { - _error->Warning(_("Unable to locate package %s"),*I); - continue; - } - Colours[Pkg->ID] = 1; - } - - bool Recurse = _config->FindB("APT::Cache::RecurseDepends",false); - bool Installed = _config->FindB("APT::Cache::Installed",false); - bool Important = _config->FindB("APT::Cache::Important",false); - bool DidSomething; - do + pkgCacheFile CacheFile; + pkgCache *Cache = CacheFile.GetPkgCache(); + if (unlikely(Cache == NULL)) + return false; + + CacheSetHelperVirtuals helper(false); + APT::VersionSet verset = APT::VersionSet::FromCommandLine(CacheFile, CmdL.FileList + 1, APT::VersionSet::CANDIDATE, helper); + if (verset.empty() == true && helper.virtualPkgs.empty() == true) + return false; + std::vector<bool> Shown(Cache->Head().PackageCount); + + bool const Recurse = _config->FindB("APT::Cache::RecurseDepends", false); + bool const Installed = _config->FindB("APT::Cache::Installed", false); + bool const Important = _config->FindB("APT::Cache::Important", false); + bool const ShowDepType = _config->FindB("APT::Cache::ShowDependencyType", RevDepends == false); + bool const ShowPreDepends = _config->FindB("APT::Cache::ShowPre-Depends", true); + bool const ShowDepends = _config->FindB("APT::Cache::ShowDepends", true); + bool const ShowRecommends = _config->FindB("APT::Cache::ShowRecommends", Important == false); + bool const ShowSuggests = _config->FindB("APT::Cache::ShowSuggests", Important == false); + bool const ShowReplaces = _config->FindB("APT::Cache::ShowReplaces", Important == false); + bool const ShowConflicts = _config->FindB("APT::Cache::ShowConflicts", Important == false); + bool const ShowBreaks = _config->FindB("APT::Cache::ShowBreaks", Important == false); + bool const ShowEnhances = _config->FindB("APT::Cache::ShowEnhances", Important == false); + bool const ShowOnlyFirstOr = _config->FindB("APT::Cache::ShowOnlyFirstOr", false); + + while (verset.empty() != true) { - DidSomething = false; - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) - { - if (Colours[Pkg->ID] != 1) - continue; - Colours[Pkg->ID] = 2; - DidSomething = true; - - pkgCache::VerIterator Ver = Pkg.VersionList(); - if (Ver.end() == true) - { - cout << '<' << Pkg.Name() << '>' << endl; - continue; - } - - cout << Pkg.Name() << endl; - - for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++) + pkgCache::VerIterator Ver = *verset.begin(); + verset.erase(verset.begin()); + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + Shown[Pkg->ID] = true; + + cout << Pkg.FullName(true) << endl; + + if (RevDepends == true) + cout << "Reverse Depends:" << endl; + for (pkgCache::DepIterator D = RevDepends ? Pkg.RevDependsList() : Ver.DependsList(); + D.end() == false; D++) { - // Important deps only - if (Important == true) - if (D->Type != pkgCache::Dep::PreDepends && - D->Type != pkgCache::Dep::Depends) - continue; - - pkgCache::PkgIterator Trg = D.TargetPkg(); + switch (D->Type) { + case pkgCache::Dep::PreDepends: if (!ShowPreDepends) continue; break; + case pkgCache::Dep::Depends: if (!ShowDepends) continue; break; + case pkgCache::Dep::Recommends: if (!ShowRecommends) continue; break; + case pkgCache::Dep::Suggests: if (!ShowSuggests) continue; break; + case pkgCache::Dep::Replaces: if (!ShowReplaces) continue; break; + case pkgCache::Dep::Conflicts: if (!ShowConflicts) continue; break; + case pkgCache::Dep::DpkgBreaks: if (!ShowBreaks) continue; break; + case pkgCache::Dep::Enhances: if (!ShowEnhances) continue; break; + } + + pkgCache::PkgIterator Trg = RevDepends ? D.ParentPkg() : D.TargetPkg(); if((Installed && Trg->CurrentVer != 0) || !Installed) { - if ((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) + if ((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or && ShowOnlyFirstOr == false) cout << " |"; else cout << " "; // Show the package + if (ShowDepType == true) + cout << D.DepType() << ": "; if (Trg->VersionList == 0) - cout << D.DepType() << ": <" << Trg.Name() << ">" << endl; + cout << "<" << Trg.FullName(true) << ">" << endl; else - cout << D.DepType() << ": " << Trg.Name() << endl; + cout << Trg.FullName(true) << endl; - if (Recurse == true) - Colours[D.TargetPkg()->ID]++; + if (Recurse == true && Shown[Trg->ID] == false) + { + Shown[Trg->ID] = true; + verset.insert(APT::VersionSet::FromPackage(CacheFile, Trg, APT::VersionSet::CANDIDATE, helper)); + } } // Display all solutions SPtrArray<pkgCache::Version *> List = D.AllTargets(); - pkgPrioSortList(Cache,List); + pkgPrioSortList(*Cache,List); for (pkgCache::Version **I = List; *I != 0; I++) { - pkgCache::VerIterator V(Cache,*I); - if (V != Cache.VerP + V.ParentPkg()->VersionList || + pkgCache::VerIterator V(*Cache,*I); + if (V != Cache->VerP + V.ParentPkg()->VersionList || V->ParentPkg == D->Package) continue; - cout << " " << V.ParentPkg().Name() << endl; - - if (Recurse == true) - Colours[D.ParentPkg()->ID]++; + cout << " " << V.ParentPkg().FullName(true) << endl; + + if (Recurse == true && Shown[V.ParentPkg()->ID] == false) + { + Shown[V.ParentPkg()->ID] = true; + verset.insert(APT::VersionSet::FromPackage(CacheFile, V.ParentPkg(), APT::VersionSet::CANDIDATE, helper)); + } } + + if (ShowOnlyFirstOr == true) + while ((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) ++D; } - } - } - while (DidSomething == true); - + } + + for (APT::PackageSet::const_iterator Pkg = helper.virtualPkgs.begin(); + Pkg != helper.virtualPkgs.end(); ++Pkg) + cout << '<' << Pkg.FullName(true) << '>' << endl; + return true; } /*}}}*/ -// RDepends - Print out a reverse dependency tree - mbc /*{{{*/ +// Depends - Print out a dependency tree /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool Depends(CommandLine &CmdL) +{ + return ShowDepends(CmdL, false); +} + /*}}}*/ +// RDepends - Print out a reverse dependency tree /*{{{*/ // --------------------------------------------------------------------- /* */ bool RDepends(CommandLine &CmdL) { - pkgCache &Cache = *GCache; - SPtrArray<unsigned> Colours = new unsigned[Cache.Head().PackageCount]; - memset(Colours,0,sizeof(*Colours)*Cache.Head().PackageCount); - - for (const char **I = CmdL.FileList + 1; *I != 0; I++) - { - pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); - if (Pkg.end() == true) - { - _error->Warning(_("Unable to locate package %s"),*I); - continue; - } - Colours[Pkg->ID] = 1; - } - - bool Recurse = _config->FindB("APT::Cache::RecurseDepends",false); - bool Installed = _config->FindB("APT::Cache::Installed",false); - bool DidSomething; - do - { - DidSomething = false; - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) - { - if (Colours[Pkg->ID] != 1) - continue; - Colours[Pkg->ID] = 2; - DidSomething = true; - - pkgCache::VerIterator Ver = Pkg.VersionList(); - if (Ver.end() == true) - { - cout << '<' << Pkg.Name() << '>' << endl; - continue; - } - - cout << Pkg.Name() << endl; - - cout << "Reverse Depends:" << endl; - for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() == false; D++) - { - // Show the package - pkgCache::PkgIterator Trg = D.ParentPkg(); - - if((Installed && Trg->CurrentVer != 0) || !Installed) - { - - if ((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) - cout << " |"; - else - cout << " "; - - if (Trg->VersionList == 0) - cout << D.DepType() << ": <" << Trg.Name() << ">" << endl; - else - cout << Trg.Name() << endl; - - if (Recurse == true) - Colours[D.ParentPkg()->ID]++; - - } - - // Display all solutions - SPtrArray<pkgCache::Version *> List = D.AllTargets(); - pkgPrioSortList(Cache,List); - for (pkgCache::Version **I = List; *I != 0; I++) - { - pkgCache::VerIterator V(Cache,*I); - if (V != Cache.VerP + V.ParentPkg()->VersionList || - V->ParentPkg == D->Package) - continue; - cout << " " << V.ParentPkg().Name() << endl; - - if (Recurse == true) - Colours[D.ParentPkg()->ID]++; - } - } - } - } - while (DidSomething == true); - - return true; + return ShowDepends(CmdL, true); } /*}}}*/ // xvcg - Generate a graph for xvcg /*{{{*/ @@ -721,7 +708,11 @@ bool RDepends(CommandLine &CmdL) bool XVcg(CommandLine &CmdL) { - pkgCache &Cache = *GCache; + pkgCacheFile CacheFile; + pkgCache *Cache = CacheFile.GetPkgCache(); + if (unlikely(Cache == NULL)) + return false; + bool GivenOnly = _config->FindB("APT::Cache::GivenOnly",false); /* Normal packages are boxes @@ -738,21 +729,21 @@ bool XVcg(CommandLine &CmdL) 0 = None */ enum States {None=0, ToShow, ToShowNR, DoneNR, Done}; enum TheFlags {ForceNR=(1<<0)}; - unsigned char *Show = new unsigned char[Cache.Head().PackageCount]; - unsigned char *Flags = new unsigned char[Cache.Head().PackageCount]; - unsigned char *ShapeMap = new unsigned char[Cache.Head().PackageCount]; + unsigned char *Show = new unsigned char[Cache->Head().PackageCount]; + unsigned char *Flags = new unsigned char[Cache->Head().PackageCount]; + unsigned char *ShapeMap = new unsigned char[Cache->Head().PackageCount]; // Show everything if no arguments given if (CmdL.FileList[1] == 0) - for (unsigned long I = 0; I != Cache.Head().PackageCount; I++) + for (unsigned long I = 0; I != Cache->Head().PackageCount; I++) Show[I] = ToShow; else - for (unsigned long I = 0; I != Cache.Head().PackageCount; I++) + for (unsigned long I = 0; I != Cache->Head().PackageCount; I++) Show[I] = None; - memset(Flags,0,sizeof(*Flags)*Cache.Head().PackageCount); + memset(Flags,0,sizeof(*Flags)*Cache->Head().PackageCount); // Map the shapes - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) + for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++) { if (Pkg->VersionList == 0) { @@ -771,38 +762,25 @@ bool XVcg(CommandLine &CmdL) ShapeMap[Pkg->ID] = 3; } } - + // Load the list of packages from the command line into the show list - for (const char **I = CmdL.FileList + 1; *I != 0; I++) + APT::CacheSetHelper helper(true, GlobalError::NOTICE); + std::list<APT::PackageSet::Modifier> mods; + mods.push_back(APT::PackageSet::Modifier(0, ",", APT::PackageSet::Modifier::POSTFIX)); + mods.push_back(APT::PackageSet::Modifier(1, "^", APT::PackageSet::Modifier::POSTFIX)); + std::map<unsigned short, APT::PackageSet> pkgsets = + APT::PackageSet::GroupedFromCommandLine(CacheFile, CmdL.FileList + 1, mods, 0, helper); + + for (APT::PackageSet::const_iterator Pkg = pkgsets[0].begin(); + Pkg != pkgsets[0].end(); ++Pkg) + Show[Pkg->ID] = ToShow; + for (APT::PackageSet::const_iterator Pkg = pkgsets[1].begin(); + Pkg != pkgsets[1].end(); ++Pkg) { - // Process per-package flags - string P = *I; - bool Force = false; - if (P.length() > 3) - { - if (P.end()[-1] == '^') - { - Force = true; - P.erase(P.end()-1); - } - - if (P.end()[-1] == ',') - P.erase(P.end()-1); - } - - // Locate the package - pkgCache::PkgIterator Pkg = Cache.FindPkg(P); - if (Pkg.end() == true) - { - _error->Warning(_("Unable to locate package %s"),*I); - continue; - } Show[Pkg->ID] = ToShow; - - if (Force == true) - Flags[Pkg->ID] |= ForceNR; + Flags[Pkg->ID] |= ForceNR; } - + // Little header cout << "graph: { title: \"packages\"" << endl << "xmax: 700 ymax: 700 x: 30 y: 30" << endl << @@ -812,7 +790,7 @@ bool XVcg(CommandLine &CmdL) while (Act == true) { Act = false; - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) + for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++) { // See we need to show this package if (Show[Pkg->ID] == None || Show[Pkg->ID] >= DoneNR) @@ -847,7 +825,7 @@ bool XVcg(CommandLine &CmdL) for (pkgCache::VerIterator I = DPkg.VersionList(); I.end() == false && Hit == false; I++) { - if (Cache.VS->CheckDep(I.VerStr(),D->CompareOp,D.TargetVer()) == true) + if (Cache->VS->CheckDep(I.VerStr(),D->CompareOp,D.TargetVer()) == true) Hit = true; } @@ -855,7 +833,7 @@ bool XVcg(CommandLine &CmdL) for (pkgCache::PrvIterator I = DPkg.ProvidesList(); I.end() == false && Hit == false; I++) { - if (Cache.VS->CheckDep(I.ProvideVersion(),D->CompareOp,D.TargetVer()) == false) + if (Cache->VS->CheckDep(I.ProvideVersion(),D->CompareOp,D.TargetVer()) == false) Hit = true; } @@ -863,7 +841,7 @@ bool XVcg(CommandLine &CmdL) // Only graph critical deps if (D.IsCritical() == true) { - printf ("edge: { sourcename: \"%s\" targetname: \"%s\" class: 2 ",Pkg.Name(), D.TargetPkg().Name() ); + printf ("edge: { sourcename: \"%s\" targetname: \"%s\" class: 2 ",Pkg.FullName(true).c_str(), D.TargetPkg().FullName(true).c_str() ); // Colour the node for recursion if (Show[D.TargetPkg()->ID] <= DoneNR) @@ -916,16 +894,16 @@ bool XVcg(CommandLine &CmdL) /* Draw the box colours after the fact since we can not tell what colour they should be until everything is finished drawing */ - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) + for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++) { if (Show[Pkg->ID] < DoneNR) continue; if (Show[Pkg->ID] == DoneNR) - printf("node: { title: \"%s\" label: \"%s\" color: orange shape: %s }\n", Pkg.Name(), Pkg.Name(), + printf("node: { title: \"%s\" label: \"%s\" color: orange shape: %s }\n", Pkg.FullName(true).c_str(), Pkg.FullName(true).c_str(), Shapes[ShapeMap[Pkg->ID]]); else - printf("node: { title: \"%s\" label: \"%s\" shape: %s }\n", Pkg.Name(), Pkg.Name(), + printf("node: { title: \"%s\" label: \"%s\" shape: %s }\n", Pkg.FullName(true).c_str(), Pkg.FullName(true).c_str(), Shapes[ShapeMap[Pkg->ID]]); } @@ -945,7 +923,11 @@ bool XVcg(CommandLine &CmdL) http://www.research.att.com/sw/tools/graphviz/ */ bool Dotty(CommandLine &CmdL) { - pkgCache &Cache = *GCache; + pkgCacheFile CacheFile; + pkgCache *Cache = CacheFile.GetPkgCache(); + if (unlikely(Cache == NULL)) + return false; + bool GivenOnly = _config->FindB("APT::Cache::GivenOnly",false); /* Normal packages are boxes @@ -962,21 +944,21 @@ bool Dotty(CommandLine &CmdL) 0 = None */ enum States {None=0, ToShow, ToShowNR, DoneNR, Done}; enum TheFlags {ForceNR=(1<<0)}; - unsigned char *Show = new unsigned char[Cache.Head().PackageCount]; - unsigned char *Flags = new unsigned char[Cache.Head().PackageCount]; - unsigned char *ShapeMap = new unsigned char[Cache.Head().PackageCount]; + unsigned char *Show = new unsigned char[Cache->Head().PackageCount]; + unsigned char *Flags = new unsigned char[Cache->Head().PackageCount]; + unsigned char *ShapeMap = new unsigned char[Cache->Head().PackageCount]; // Show everything if no arguments given if (CmdL.FileList[1] == 0) - for (unsigned long I = 0; I != Cache.Head().PackageCount; I++) + for (unsigned long I = 0; I != Cache->Head().PackageCount; I++) Show[I] = ToShow; else - for (unsigned long I = 0; I != Cache.Head().PackageCount; I++) + for (unsigned long I = 0; I != Cache->Head().PackageCount; I++) Show[I] = None; - memset(Flags,0,sizeof(*Flags)*Cache.Head().PackageCount); + memset(Flags,0,sizeof(*Flags)*Cache->Head().PackageCount); // Map the shapes - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) + for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++) { if (Pkg->VersionList == 0) { @@ -995,38 +977,25 @@ bool Dotty(CommandLine &CmdL) ShapeMap[Pkg->ID] = 3; } } - + // Load the list of packages from the command line into the show list - for (const char **I = CmdL.FileList + 1; *I != 0; I++) + APT::CacheSetHelper helper(true, GlobalError::NOTICE); + std::list<APT::PackageSet::Modifier> mods; + mods.push_back(APT::PackageSet::Modifier(0, ",", APT::PackageSet::Modifier::POSTFIX)); + mods.push_back(APT::PackageSet::Modifier(1, "^", APT::PackageSet::Modifier::POSTFIX)); + std::map<unsigned short, APT::PackageSet> pkgsets = + APT::PackageSet::GroupedFromCommandLine(CacheFile, CmdL.FileList + 1, mods, 0, helper); + + for (APT::PackageSet::const_iterator Pkg = pkgsets[0].begin(); + Pkg != pkgsets[0].end(); ++Pkg) + Show[Pkg->ID] = ToShow; + for (APT::PackageSet::const_iterator Pkg = pkgsets[1].begin(); + Pkg != pkgsets[1].end(); ++Pkg) { - // Process per-package flags - string P = *I; - bool Force = false; - if (P.length() > 3) - { - if (P.end()[-1] == '^') - { - Force = true; - P.erase(P.end()-1); - } - - if (P.end()[-1] == ',') - P.erase(P.end()-1); - } - - // Locate the package - pkgCache::PkgIterator Pkg = Cache.FindPkg(P); - if (Pkg.end() == true) - { - _error->Warning(_("Unable to locate package %s"),*I); - continue; - } Show[Pkg->ID] = ToShow; - - if (Force == true) - Flags[Pkg->ID] |= ForceNR; + Flags[Pkg->ID] |= ForceNR; } - + // Little header printf("digraph packages {\n"); printf("concentrate=true;\n"); @@ -1036,7 +1005,7 @@ bool Dotty(CommandLine &CmdL) while (Act == true) { Act = false; - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) + for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++) { // See we need to show this package if (Show[Pkg->ID] == None || Show[Pkg->ID] >= DoneNR) @@ -1069,7 +1038,7 @@ bool Dotty(CommandLine &CmdL) for (pkgCache::VerIterator I = DPkg.VersionList(); I.end() == false && Hit == false; I++) { - if (Cache.VS->CheckDep(I.VerStr(),D->CompareOp,D.TargetVer()) == true) + if (Cache->VS->CheckDep(I.VerStr(),D->CompareOp,D.TargetVer()) == true) Hit = true; } @@ -1077,14 +1046,14 @@ bool Dotty(CommandLine &CmdL) for (pkgCache::PrvIterator I = DPkg.ProvidesList(); I.end() == false && Hit == false; I++) { - if (Cache.VS->CheckDep(I.ProvideVersion(),D->CompareOp,D.TargetVer()) == false) + if (Cache->VS->CheckDep(I.ProvideVersion(),D->CompareOp,D.TargetVer()) == false) Hit = true; } // Only graph critical deps if (D.IsCritical() == true) { - printf("\"%s\" -> \"%s\"",Pkg.Name(),D.TargetPkg().Name()); + printf("\"%s\" -> \"%s\"",Pkg.FullName(true).c_str(),D.TargetPkg().FullName(true).c_str()); // Colour the node for recursion if (Show[D.TargetPkg()->ID] <= DoneNR) @@ -1131,17 +1100,17 @@ bool Dotty(CommandLine &CmdL) /* Draw the box colours after the fact since we can not tell what colour they should be until everything is finished drawing */ - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) + for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++) { if (Show[Pkg->ID] < DoneNR) continue; // Orange box for early recursion stoppage if (Show[Pkg->ID] == DoneNR) - printf("\"%s\" [color=orange,shape=%s];\n",Pkg.Name(), + printf("\"%s\" [color=orange,shape=%s];\n",Pkg.FullName(true).c_str(), Shapes[ShapeMap[Pkg->ID]]); else - printf("\"%s\" [shape=%s];\n",Pkg.Name(), + printf("\"%s\" [shape=%s];\n",Pkg.FullName(true).c_str(), Shapes[ShapeMap[Pkg->ID]]); } @@ -1205,8 +1174,12 @@ bool DoAdd(CommandLine &CmdL) // --------------------------------------------------------------------- /* This displays the package record from the proper package index file. It is not used by DumpAvail for performance reasons. */ -bool DisplayRecord(pkgCache::VerIterator V) +bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V) { + pkgCache *Cache = CacheFile.GetPkgCache(); + if (unlikely(Cache == NULL)) + return false; + // Find an appropriate file pkgCache::VerFileIterator Vf = V.FileList(); for (; Vf.end() == false; Vf++) @@ -1219,13 +1192,13 @@ bool DisplayRecord(pkgCache::VerIterator V) pkgCache::PkgFileIterator I = Vf.File(); if (I.IsOk() == false) return _error->Error(_("Package file %s is out of sync."),I.FileName()); - - FileFd PkgF(I.FileName(),FileFd::ReadOnly); - if (_error->PendingError() == true) + + FileFd PkgF; + if (PkgF.Open(I.FileName(), FileFd::ReadOnlyGzip) == false) return false; - + // Read the record - unsigned char *Buffer = new unsigned char[GCache->HeaderP->MaxVerFileSize+1]; + unsigned char *Buffer = new unsigned char[Cache->HeaderP->MaxVerFileSize+1]; Buffer[V.FileList()->Size] = '\n'; if (PkgF.Seek(V.FileList()->Offset) == false || PkgF.Read(Buffer,V.FileList()->Size) == false) @@ -1245,7 +1218,7 @@ bool DisplayRecord(pkgCache::VerIterator V) } // Show the right description - pkgRecords Recs(*GCache); + pkgRecords Recs(*Cache); pkgCache::DescIterator Desc = V.TranslatedDescription(); pkgRecords::Parser &P = Recs.Lookup(Desc.FileList()); cout << "Description" << ( (strcmp(Desc.LanguageCode(),"") != 0) ? "-" : "" ) << Desc.LanguageCode() << ": " << P.LongDesc(); @@ -1285,16 +1258,19 @@ struct ExDescFile /* This searches the package names and package descriptions for a pattern */ bool Search(CommandLine &CmdL) { - pkgCache &Cache = *GCache; - bool ShowFull = _config->FindB("APT::Cache::ShowFull",false); - bool NamesOnly = _config->FindB("APT::Cache::NamesOnly",false); - unsigned NumPatterns = CmdL.FileSize() -1; - - pkgDepCache::Policy Plcy; - + bool const ShowFull = _config->FindB("APT::Cache::ShowFull",false); + bool const NamesOnly = _config->FindB("APT::Cache::NamesOnly",false); + unsigned int const NumPatterns = CmdL.FileSize() -1; + + pkgCacheFile CacheFile; + pkgCache *Cache = CacheFile.GetPkgCache(); + pkgDepCache::Policy *Plcy = CacheFile.GetPolicy(); + if (unlikely(Cache == NULL || Plcy == NULL)) + return false; + // Make sure there is at least one argument if (NumPatterns < 1) - return _error->Error(_("You must give exactly one pattern")); + return _error->Error(_("You must give at least one search pattern")); // Compile the regex pattern regex_t *Patterns = new regex_t[NumPatterns]; @@ -1310,8 +1286,6 @@ bool Search(CommandLine &CmdL) } } - // Create the text record parser - pkgRecords Recs(Cache); if (_error->PendingError() == true) { for (unsigned I = 0; I != NumPatterns; I++) @@ -1319,70 +1293,75 @@ bool Search(CommandLine &CmdL) return false; } - ExDescFile *DFList = new ExDescFile[Cache.HeaderP->PackageCount+1]; - memset(DFList,0,sizeof(*DFList)*Cache.HeaderP->PackageCount+1); + ExDescFile *DFList = new ExDescFile[Cache->HeaderP->GroupCount+1]; + memset(DFList,0,sizeof(*DFList)*Cache->HeaderP->GroupCount+1); // Map versions that we want to write out onto the VerList array. - for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++) + for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() == false; ++G) { - DFList[P->ID].NameMatch = NumPatterns != 0; + if (DFList[G->ID].NameMatch == true) + continue; + + DFList[G->ID].NameMatch = true; for (unsigned I = 0; I != NumPatterns; I++) { - if (regexec(&Patterns[I],P.Name(),0,0,0) == 0) - DFList[P->ID].NameMatch &= true; - else - DFList[P->ID].NameMatch = false; + if (regexec(&Patterns[I],G.Name(),0,0,0) == 0) + continue; + DFList[G->ID].NameMatch = false; + break; } // Doing names only, drop any that dont match.. - if (NamesOnly == true && DFList[P->ID].NameMatch == false) + if (NamesOnly == true && DFList[G->ID].NameMatch == false) continue; - // Find the proper version to use. - pkgCache::VerIterator V = Plcy.GetCandidateVer(P); + // Find the proper version to use + pkgCache::PkgIterator P = G.FindPreferredPkg(); + if (P.end() == true) + continue; + pkgCache::VerIterator V = Plcy->GetCandidateVer(P); if (V.end() == false) - DFList[P->ID].Df = V.DescriptionList().FileList(); - } - - // Include all the packages that provide matching names too - for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++) - { - if (DFList[P->ID].NameMatch == false) + DFList[G->ID].Df = V.DescriptionList().FileList(); + + if (DFList[G->ID].NameMatch == false) continue; + // Include all the packages that provide matching names too for (pkgCache::PrvIterator Prv = P.ProvidesList() ; Prv.end() == false; Prv++) { - pkgCache::VerIterator V = Plcy.GetCandidateVer(Prv.OwnerPkg()); - if (V.end() == false) - { - DFList[Prv.OwnerPkg()->ID].Df = V.DescriptionList().FileList(); - DFList[Prv.OwnerPkg()->ID].NameMatch = true; - } + pkgCache::VerIterator V = Plcy->GetCandidateVer(Prv.OwnerPkg()); + if (V.end() == true) + continue; + + unsigned long id = Prv.OwnerPkg().Group()->ID; + DFList[id].Df = V.DescriptionList().FileList(); + DFList[id].NameMatch = true; } } - LocalitySort(&DFList->Df,Cache.HeaderP->PackageCount,sizeof(*DFList)); + LocalitySort(&DFList->Df,Cache->HeaderP->GroupCount,sizeof(*DFList)); + // Create the text record parser + pkgRecords Recs(*Cache); // Iterate over all the version records and check them for (ExDescFile *J = DFList; J->Df != 0; J++) { - pkgRecords::Parser &P = Recs.Lookup(pkgCache::DescFileIterator(Cache,J->Df)); + pkgRecords::Parser &P = Recs.Lookup(pkgCache::DescFileIterator(*Cache,J->Df)); - bool Match = true; - if (J->NameMatch == false) + if (J->NameMatch == false && NamesOnly == false) { - string LongDesc = P.LongDesc(); - Match = NumPatterns != 0; + string const LongDesc = P.LongDesc(); + J->NameMatch = true; for (unsigned I = 0; I != NumPatterns; I++) { if (regexec(&Patterns[I],LongDesc.c_str(),0,0,0) == 0) - Match &= true; - else - Match = false; + continue; + J->NameMatch = false; + break; } } - if (Match == true) + if (J->NameMatch == true) { if (ShowFull == true) { @@ -1404,51 +1383,54 @@ bool Search(CommandLine &CmdL) return _error->Error("Write to stdout failed"); return true; } + + +/* show automatically installed packages (sorted) */ +bool ShowAuto(CommandLine &CmdL) +{ + pkgCacheFile CacheFile; + pkgCache *Cache = CacheFile.GetPkgCache(); + pkgDepCache *DepCache = CacheFile.GetDepCache(); + if (unlikely(Cache == NULL || DepCache == NULL)) + return false; + + std::vector<string> packages; + packages.reserve(Cache->HeaderP->PackageCount / 3); + + for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; P++) + if ((*DepCache)[P].Flags & pkgCache::Flag::Auto) + packages.push_back(P.Name()); + + std::sort(packages.begin(), packages.end()); + + for (vector<string>::iterator I = packages.begin(); I != packages.end(); I++) + cout << *I << "\n"; + + return true; +} /*}}}*/ // ShowPackage - Dump the package record to the screen /*{{{*/ // --------------------------------------------------------------------- /* */ bool ShowPackage(CommandLine &CmdL) -{ - pkgCache &Cache = *GCache; - pkgDepCache::Policy Plcy; - - unsigned found = 0; - - for (const char **I = CmdL.FileList + 1; *I != 0; I++) +{ + pkgCacheFile CacheFile; + CacheSetHelperVirtuals helper(true, GlobalError::NOTICE); + APT::VersionSet::Version const select = _config->FindB("APT::Cache::AllVersions", true) ? + APT::VersionSet::ALL : APT::VersionSet::CANDIDATE; + APT::VersionSet const verset = APT::VersionSet::FromCommandLine(CacheFile, CmdL.FileList + 1, select, helper); + for (APT::VersionSet::const_iterator Ver = verset.begin(); Ver != verset.end(); ++Ver) + if (DisplayRecord(CacheFile, Ver) == false) + return false; + + if (verset.empty() == true) { - pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); - if (Pkg.end() == true) - { - _error->Warning(_("Unable to locate package %s"),*I); - continue; - } - - ++found; - - // Find the proper version to use. - if (_config->FindB("APT::Cache::AllVersions","true") == true) - { - pkgCache::VerIterator V; - for (V = Pkg.VersionList(); V.end() == false; V++) - { - if (DisplayRecord(V) == false) - return false; - } - } + if (helper.virtualPkgs.empty() == true) + return _error->Error(_("No packages found")); else - { - pkgCache::VerIterator V = Plcy.GetCandidateVer(Pkg); - if (V.end() == true || V.FileList().end() == true) - continue; - if (DisplayRecord(V) == false) - return false; - } + _error->Notice(_("No packages found")); } - - if (found > 0) - return true; - return _error->Error(_("No packages found")); + return true; } /*}}}*/ // ShowPkgNames - Show package names /*{{{*/ @@ -1456,17 +1438,20 @@ bool ShowPackage(CommandLine &CmdL) /* This does a prefix match on the first argument */ bool ShowPkgNames(CommandLine &CmdL) { - pkgCache &Cache = *GCache; - pkgCache::PkgIterator I = Cache.PkgBegin(); - bool All = _config->FindB("APT::Cache::AllNames","false"); - + pkgCacheFile CacheFile; + if (unlikely(CacheFile.BuildCaches(NULL, false) == false)) + return false; + pkgCache::GrpIterator I = CacheFile.GetPkgCache()->GrpBegin(); + bool const All = _config->FindB("APT::Cache::AllNames","false"); + if (CmdL.FileList[1] != 0) { for (;I.end() != true; I++) { - if (All == false && I->VersionList == 0) + if (All == false && I->FirstPackage == 0) + continue; + if (I.FindPkg("any")->VersionList == 0) continue; - if (strncmp(I.Name(),CmdL.FileList[1],strlen(CmdL.FileList[1])) == 0) cout << I.Name() << endl; } @@ -1477,7 +1462,9 @@ bool ShowPkgNames(CommandLine &CmdL) // Show all pkgs for (;I.end() != true; I++) { - if (All == false && I->VersionList == 0) + if (All == false && I->FirstPackage == 0) + continue; + if (I.FindPkg("any")->VersionList == 0) continue; cout << I.Name() << endl; } @@ -1490,22 +1477,35 @@ bool ShowPkgNames(CommandLine &CmdL) /* */ bool ShowSrcPackage(CommandLine &CmdL) { - pkgSourceList List; - List.ReadMainList(); - + pkgCacheFile CacheFile; + pkgSourceList *List = CacheFile.GetSourceList(); + if (unlikely(List == NULL)) + return false; + // Create the text record parsers - pkgSrcRecords SrcRecs(List); + pkgSrcRecords SrcRecs(*List); if (_error->PendingError() == true) return false; + unsigned found = 0; for (const char **I = CmdL.FileList + 1; *I != 0; I++) { SrcRecs.Restart(); pkgSrcRecords::Parser *Parse; - while ((Parse = SrcRecs.Find(*I,false)) != 0) - cout << Parse->AsStr() << endl;; - } + unsigned found_this = 0; + while ((Parse = SrcRecs.Find(*I,false)) != 0) { + cout << Parse->AsStr() << endl;; + found++; + found_this++; + } + if (found_this == 0) { + _error->Warning(_("Unable to locate package %s"),*I); + continue; + } + } + if (found == 0) + _error->Notice(_("No packages found")); return true; } /*}}}*/ @@ -1514,19 +1514,24 @@ bool ShowSrcPackage(CommandLine &CmdL) /* */ bool Policy(CommandLine &CmdL) { - if (SrcList == 0) - return _error->Error("Generate must be enabled for this function"); - - pkgCache &Cache = *GCache; - pkgPolicy Plcy(&Cache); - if (ReadPinFile(Plcy) == false || ReadPinDir(Plcy) == false) + pkgCacheFile CacheFile; + pkgCache *Cache = CacheFile.GetPkgCache(); + pkgPolicy *Plcy = CacheFile.GetPolicy(); + pkgSourceList *SrcList = CacheFile.GetSourceList(); + if (unlikely(Cache == NULL || Plcy == NULL || SrcList == NULL)) return false; - + + /* Should the MultiArchKiller be run to see which pseudo packages for an + arch all package are currently installed? Activating it gives a speed + penality for no real gain beside enhanced debugging, so in general no. */ + if (_config->FindB("APT::Cache::Policy::DepCache", false) == true) + CacheFile.GetDepCache(); + // Print out all of the package files if (CmdL.FileList[1] == 0) { cout << _("Package files:") << endl; - for (pkgCache::PkgFileIterator F = Cache.FileBegin(); F.end() == false; F++) + for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F.end() == false; F++) { // Locate the associated index files so we can derive a description pkgIndexFile *Indx; @@ -1535,7 +1540,7 @@ bool Policy(CommandLine &CmdL) return _error->Error(_("Cache is out of sync, can't x-ref a package file")); printf("%4i %s\n", - Plcy.GetPriority(F),Indx->Describe(true).c_str()); + Plcy->GetPriority(F),Indx->Describe(true).c_str()); // Print the reference information for the package string Str = F.RelStr(); @@ -1547,16 +1552,16 @@ bool Policy(CommandLine &CmdL) // Show any packages have explicit pins cout << _("Pinned packages:") << endl; - pkgCache::PkgIterator I = Cache.PkgBegin(); + pkgCache::PkgIterator I = Cache->PkgBegin(); for (;I.end() != true; I++) { - if (Plcy.GetPriority(I) == 0) + if (Plcy->GetPriority(I) == 0) continue; // Print the package name and the version we are forcing to - cout << " " << I.Name() << " -> "; + cout << " " << I.FullName(true) << " -> "; - pkgCache::VerIterator V = Plcy.GetMatch(I); + pkgCache::VerIterator V = Plcy->GetMatch(I); if (V.end() == true) cout << _("(not found)") << endl; else @@ -1565,39 +1570,50 @@ bool Policy(CommandLine &CmdL) return true; } - + + string const myArch = _config->Find("APT::Architecture"); + char const * const msgInstalled = _(" Installed: "); + char const * const msgCandidate = _(" Candidate: "); + short const InstalledLessCandidate = + mbstowcs(NULL, msgInstalled, 0) - mbstowcs(NULL, msgCandidate, 0); + short const deepInstalled = + (InstalledLessCandidate < 0 ? (InstalledLessCandidate*-1) : 0) - 1; + short const deepCandidate = + (InstalledLessCandidate > 0 ? (InstalledLessCandidate) : 0) - 1; + // Print out detailed information for each package - for (const char **I = CmdL.FileList + 1; *I != 0; I++) + APT::CacheSetHelper helper(true, GlobalError::NOTICE); + APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1, helper); + for (APT::PackageSet::const_iterator I = pkgset.begin(); I != pkgset.end(); ++I) { - pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); - if (Pkg.end() == true) - { - _error->Warning(_("Unable to locate package %s"),*I); + pkgCache::PkgIterator Pkg = I.Group().FindPkg("any"); + + for (; Pkg.end() != true; Pkg = I.Group().NextPkg(Pkg)) { + if (strcmp(Pkg.Arch(),"all") == 0) continue; - } - - cout << Pkg.Name() << ":" << endl; - + + cout << Pkg.FullName(true) << ":" << endl; + // Installed version - cout << _(" Installed: "); + cout << msgInstalled << OutputInDepth(deepInstalled, " "); if (Pkg->CurrentVer == 0) cout << _("(none)") << endl; else cout << Pkg.CurrentVer().VerStr() << endl; // Candidate Version - cout << _(" Candidate: "); - pkgCache::VerIterator V = Plcy.GetCandidateVer(Pkg); + cout << msgCandidate << OutputInDepth(deepCandidate, " "); + pkgCache::VerIterator V = Plcy->GetCandidateVer(Pkg); if (V.end() == true) cout << _("(none)") << endl; else cout << V.VerStr() << endl; // Pinned version - if (Plcy.GetPriority(Pkg) != 0) + if (Plcy->GetPriority(Pkg) != 0) { cout << _(" Package pin: "); - V = Plcy.GetMatch(Pkg); + V = Plcy->GetMatch(Pkg); if (V.end() == true) cout << _("(not found)") << endl; else @@ -1612,7 +1628,7 @@ bool Policy(CommandLine &CmdL) cout << " *** " << V.VerStr(); else cout << " " << V.VerStr(); - cout << " " << Plcy.GetPriority(Pkg) << endl; + cout << " " << Plcy->GetPriority(Pkg) << endl; for (pkgCache::VerFileIterator VF = V.FileList(); VF.end() == false; VF++) { // Locate the associated index files so we can derive a description @@ -1620,10 +1636,11 @@ bool Policy(CommandLine &CmdL) if (SrcList->FindIndex(VF.File(),Indx) == false && _system->FindIndex(VF.File(),Indx) == false) return _error->Error(_("Cache is out of sync, can't x-ref a package file")); - printf(" %4i %s\n",Plcy.GetPriority(VF.File()), + printf(" %4i %s\n",Plcy->GetPriority(VF.File()), Indx->Describe(true).c_str()); - } - } + } + } + } } return true; @@ -1634,12 +1651,11 @@ bool Policy(CommandLine &CmdL) /* */ bool Madison(CommandLine &CmdL) { - if (SrcList == 0) - return _error->Error("Generate must be enabled for this function"); + pkgCacheFile CacheFile; + pkgSourceList *SrcList = CacheFile.GetSourceList(); - SrcList->ReadMainList(); - - pkgCache &Cache = *GCache; + if (SrcList == 0) + return false; // Create the src text record parsers and ignore errors about missing // deb-src lines that are generated from pkgSrcRecords::pkgSrcRecords @@ -1647,11 +1663,12 @@ bool Madison(CommandLine &CmdL) if (_error->PendingError() == true) _error->Discard(); + APT::CacheSetHelper helper(true, GlobalError::NOTICE); for (const char **I = CmdL.FileList + 1; *I != 0; I++) { - pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); - - if (Pkg.end() == false) + _error->PushToStack(); + APT::PackageSet pkgset = APT::PackageSet::FromString(CacheFile, *I, helper); + for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) { for (pkgCache::VerIterator V = Pkg.VersionList(); V.end() == false; V++) { @@ -1673,7 +1690,7 @@ bool Madison(CommandLine &CmdL) { if ((*IF)->FindInCache(*(VF.File().Cache())) == VF.File()) { - cout << setw(10) << Pkg.Name() << " | " << setw(10) << V.VerStr() << " | " + cout << setw(10) << Pkg.FullName(true) << " | " << setw(10) << V.VerStr() << " | " << (*IF)->Describe(true) << endl; } } @@ -1682,16 +1699,21 @@ bool Madison(CommandLine &CmdL) } } - SrcRecs.Restart(); pkgSrcRecords::Parser *SrcParser; - while ((SrcParser = SrcRecs.Find(*I,false)) != 0) + bool foundSomething = false; + while ((SrcParser = SrcRecs.Find(*I, false)) != 0) { + foundSomething = true; // Maybe support Release info here too eventually cout << setw(10) << SrcParser->Package() << " | " << setw(10) << SrcParser->Version() << " | " << SrcParser->Index().Describe(true) << endl; } + if (foundSomething == true) + _error->RevertToStack(); + else + _error->MergeWithStack(); } return true; @@ -1703,11 +1725,9 @@ bool Madison(CommandLine &CmdL) bool GenCaches(CommandLine &Cmd) { OpTextProgress Progress(*_config); - - pkgSourceList List; - if (List.ReadMainList() == false) - return false; - return pkgMakeStatusCache(List,Progress); + + pkgCacheFile CacheFile; + return CacheFile.BuildCaches(&Progress, true); } /*}}}*/ // ShowHelp - Show a help screen /*{{{*/ @@ -1741,6 +1761,7 @@ bool ShowHelp(CommandLine &Cmd) " unmet - Show unmet dependencies\n" " search - Search the package list for a regex pattern\n" " show - Show a readable record for the package\n" + " showauto - Display a list of automatically installed packages\n" " depends - Show raw dependency information for a package\n" " rdepends - Show reverse dependency information for a package\n" " pkgnames - List the names of all packages in the system\n" @@ -1760,15 +1781,6 @@ bool ShowHelp(CommandLine &Cmd) return true; } /*}}}*/ -// CacheInitialize - Initialize things for apt-cache /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void CacheInitialize() -{ - _config->Set("quiet",0); - _config->Set("help",false); -} - /*}}}*/ int main(int argc,const char *argv[]) /*{{{*/ { CommandLine::Args Args[] = { @@ -1784,9 +1796,19 @@ int main(int argc,const char *argv[]) /*{{{*/ {'n',"names-only","APT::Cache::NamesOnly",0}, {0,"all-names","APT::Cache::AllNames",0}, {0,"recurse","APT::Cache::RecurseDepends",0}, + {'t',"target-release","APT::Default-Release",CommandLine::HasArg}, + {'t',"default-release","APT::Default-Release",CommandLine::HasArg}, {'c',"config-file",0,CommandLine::ConfigFile}, {'o',"option",0,CommandLine::ArbItem}, {0,"installed","APT::Cache::Installed",0}, + {0,"pre-depends","APT::Cache::ShowPreDepends",0}, + {0,"depends","APT::Cache::ShowDepends",0}, + {0,"recommends","APT::Cache::ShowRecommends",0}, + {0,"suggests","APT::Cache::ShowSuggests",0}, + {0,"replaces","APT::Cache::ShowReplaces",0}, + {0,"breaks","APT::Cache::ShowBreaks",0}, + {0,"conflicts","APT::Cache::ShowConflicts",0}, + {0,"enhances","APT::Cache::ShowEnhances",0}, {0,0,0,0}}; CommandLine::Dispatch CmdsA[] = {{"help",&ShowHelp}, {"add",&DoAdd}, @@ -1805,12 +1827,11 @@ int main(int argc,const char *argv[]) /*{{{*/ {"xvcg",&XVcg}, {"show",&ShowPackage}, {"pkgnames",&ShowPkgNames}, + {"showauto",&ShowAuto}, {"policy",&Policy}, {"madison",&Madison}, {0,0}}; - CacheInitialize(); - // Set up gettext support setlocale(LC_ALL,""); textdomain(PACKAGE); @@ -1834,46 +1855,21 @@ int main(int argc,const char *argv[]) /*{{{*/ } // Deal with stdout not being a tty - if (isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1) + if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) _config->Set("quiet","1"); + if (_config->Exists("APT::Cache::Generate") == true) + _config->Set("pkgCacheFile::Generate", _config->FindB("APT::Cache::Generate", true)); + if (CmdL.DispatchArg(CmdsA,false) == false && _error->PendingError() == false) - { - MMap *Map = 0; - if (_config->FindB("APT::Cache::Generate",true) == false) - { - Map = new MMap(*new FileFd(_config->FindFile("Dir::Cache::pkgcache"), - FileFd::ReadOnly),MMap::Public|MMap::ReadOnly); - } - else - { - // Open the cache file - SrcList = new pkgSourceList; - SrcList->ReadMainList(); + CmdL.DispatchArg(CmdsB); - // Generate it and map it - OpProgress Prog; - pkgMakeStatusCache(*SrcList,Prog,&Map,true); - } - - if (_error->PendingError() == false) - { - pkgCache Cache(Map); - GCache = &Cache; - if (_error->PendingError() == false) - CmdL.DispatchArg(CmdsB); - } - delete Map; - } - // Print any errors or warnings found during parsing - if (_error->empty() == false) - { - bool Errors = _error->PendingError(); + bool const Errors = _error->PendingError(); + if (_config->FindI("quiet",0) > 0) _error->DumpErrors(); - return Errors == true?100:0; - } - - return 0; + else + _error->DumpErrors(GlobalError::DEBUG); + return Errors == true ? 100 : 0; } /*}}}*/ diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc index 0c9aab28c..d1268edf9 100644 --- a/cmdline/apt-cdrom.cc +++ b/cmdline/apt-cdrom.cc @@ -147,7 +147,7 @@ bool DoAdd(CommandLine &) pkgCdrom cdrom; bool res = true; - bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect"); + bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect", true); unsigned int count = 0; if (AutoDetect && UdevCdroms.Dlopen()) @@ -266,20 +266,18 @@ int main(int argc,const char *argv[]) /*{{{*/ return ShowHelp(); // Deal with stdout not being a tty - if (isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1) + if (isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) _config->Set("quiet","1"); // Match the operation CmdL.DispatchArg(Cmds); // Print any errors or warnings found during parsing - if (_error->empty() == false) - { - bool Errors = _error->PendingError(); + bool const Errors = _error->PendingError(); + if (_config->FindI("quiet",0) > 0) _error->DumpErrors(); - return Errors == true?100:0; - } - - return 0; + else + _error->DumpErrors(GlobalError::DEBUG); + return Errors == true ? 100 : 0; } /*}}}*/ diff --git a/cmdline/apt-extracttemplates.cc b/cmdline/apt-extracttemplates.cc index 21ef1a050..07bc0c25d 100644 --- a/cmdline/apt-extracttemplates.cc +++ b/cmdline/apt-extracttemplates.cc @@ -296,8 +296,7 @@ bool Go(CommandLine &CmdL) MMap *Map = 0; pkgSourceList List; List.ReadMainList(); - OpProgress Prog; - pkgMakeStatusCache(List,Prog,&Map,true); + pkgCacheGenerator::MakeStatusCache(List,NULL,&Map,true); if (Map == 0) return false; DebFile::Cache = new pkgCache(Map); diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index d4fefa9c7..d1c010e49 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -25,6 +25,10 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE + +#include <apt-pkg/aptconfiguration.h> #include <apt-pkg/error.h> #include <apt-pkg/cmndline.h> #include <apt-pkg/init.h> @@ -37,10 +41,11 @@ #include <apt-pkg/srcrecords.h> #include <apt-pkg/version.h> #include <apt-pkg/cachefile.h> +#include <apt-pkg/cacheset.h> #include <apt-pkg/sptr.h> #include <apt-pkg/md5.h> #include <apt-pkg/versionmatch.h> - + #include <config.h> #include <apti18n.h> @@ -62,6 +67,9 @@ #include <regex.h> #include <sys/wait.h> #include <sstream> + +#define statfs statfs64 +#define statvfs statvfs64 /*}}}*/ #define RAMFS_MAGIC 0x858458f6 @@ -90,14 +98,14 @@ class CacheFile : public pkgCacheFile bool BuildCaches(bool WithLock = true) { OpTextProgress Prog(*_config); - if (pkgCacheFile::BuildCaches(Prog,WithLock) == false) + if (pkgCacheFile::BuildCaches(&Prog,WithLock) == false) return false; return true; } bool Open(bool WithLock = true) { OpTextProgress Prog(*_config); - if (pkgCacheFile::Open(Prog,WithLock) == false) + if (pkgCacheFile::Open(&Prog,WithLock) == false) return false; Sort(); @@ -258,8 +266,8 @@ void ShowBroken(ostream &out,CacheFile &Cache,bool Now) } // Print out each package and the failed dependencies - out <<" " << I.Name() << ":"; - unsigned Indent = strlen(I.Name()) + 3; + out << " " << I.FullName(true) << " :"; + unsigned const Indent = I.FullName(true).size() + 3; bool First = true; pkgCache::VerIterator Ver; @@ -312,7 +320,7 @@ void ShowBroken(ostream &out,CacheFile &Cache,bool Now) out << ' ' << End.DepType() << ": "; FirstOr = false; - out << Start.TargetPkg().Name(); + out << Start.TargetPkg().FullName(true); // Show a quick summary of the version requirements if (Start.TargetVer() != 0) @@ -374,7 +382,9 @@ void ShowNew(ostream &out,CacheFile &Cache) { pkgCache::PkgIterator I(Cache,Cache.List[J]); if (Cache[I].NewInstall() == true) { - List += string(I.Name()) + " "; + if (Cache[I].CandidateVerIter(Cache).Pseudo() == true) + continue; + List += I.FullName(true) + " "; VersionsList += string(Cache[I].CandVersion) + "\n"; } } @@ -396,10 +406,12 @@ void ShowDel(ostream &out,CacheFile &Cache) pkgCache::PkgIterator I(Cache,Cache.List[J]); if (Cache[I].Delete() == true) { + if (Cache[I].CandidateVerIter(Cache).Pseudo() == true) + continue; if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge) - List += string(I.Name()) + "* "; + List += I.FullName(true) + "* "; else - List += string(I.Name()) + " "; + List += I.FullName(true) + " "; VersionsList += string(Cache[I].CandVersion)+ "\n"; } @@ -424,7 +436,7 @@ void ShowKept(ostream &out,CacheFile &Cache) I->CurrentVer == 0 || Cache[I].Delete() == true) continue; - List += string(I.Name()) + " "; + List += I.FullName(true) + " "; VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; } ShowList(out,_("The following packages have been kept back:"),List,VersionsList); @@ -444,8 +456,10 @@ void ShowUpgraded(ostream &out,CacheFile &Cache) // Not interesting if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true) continue; - - List += string(I.Name()) + " "; + if (Cache[I].CandidateVerIter(Cache).Pseudo() == true) + continue; + + List += I.FullName(true) + " "; VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; } ShowList(out,_("The following packages will be upgraded:"),List,VersionsList); @@ -465,8 +479,10 @@ bool ShowDowngraded(ostream &out,CacheFile &Cache) // Not interesting if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true) continue; - - List += string(I.Name()) + " "; + if (Cache[I].CandidateVerIter(Cache).Pseudo() == true) + continue; + + List += I.FullName(true) + " "; VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; } return ShowList(out,_("The following packages will be DOWNGRADED:"),List,VersionsList); @@ -484,7 +500,7 @@ bool ShowHold(ostream &out,CacheFile &Cache) pkgCache::PkgIterator I(Cache,Cache.List[J]); if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() && I->SelectedState == pkgCache::State::Hold) { - List += string(I.Name()) + " "; + List += I.FullName(true) + " "; VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; } } @@ -518,7 +534,7 @@ bool ShowEssential(ostream &out,CacheFile &Cache) if (Added[I->ID] == false) { Added[I->ID] = true; - List += string(I.Name()) + " "; + List += I.FullName(true) + " "; //VersionsList += string(Cache[I].CurVersion) + "\n"; ??? } } @@ -542,7 +558,7 @@ bool ShowEssential(ostream &out,CacheFile &Cache) Added[P->ID] = true; char S[300]; - snprintf(S,sizeof(S),_("%s (due to %s) "),P.Name(),I.Name()); + snprintf(S,sizeof(S),_("%s (due to %s) "),P.FullName(true).c_str(),I.FullName(true).c_str()); List += S; //VersionsList += "\n"; ??? } @@ -566,6 +582,9 @@ void Stats(ostream &out,pkgDepCache &Dep) unsigned long ReInstall = 0; for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++) { + if (pkgCache::VerIterator(Dep, Dep[I].CandidateVer).Pseudo() == true) + continue; + if (Dep[I].NewInstall() == true) Install++; else @@ -597,6 +616,256 @@ void Stats(ostream &out,pkgDepCache &Dep) Dep.BadCount()); } /*}}}*/ +// CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/ +class CacheSetHelperAPTGet : public APT::CacheSetHelper { + /** \brief stream message should be printed to */ + std::ostream &out; + /** \brief were things like Task or RegEx used to select packages? */ + bool explicitlyNamed; + + APT::PackageSet virtualPkgs; + +public: + CacheSetHelperAPTGet(std::ostream &out) : APT::CacheSetHelper(true), out(out) { + explicitlyNamed = true; + } + + virtual void showTaskSelection(APT::PackageSet const &pkgset, string const &pattern) { + for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) + ioprintf(out, _("Note, selecting '%s' for task '%s'\n"), + Pkg.FullName(true).c_str(), pattern.c_str()); + explicitlyNamed = false; + } + virtual void showRegExSelection(APT::PackageSet const &pkgset, string const &pattern) { + for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) + ioprintf(out, _("Note, selecting '%s' for regex '%s'\n"), + Pkg.FullName(true).c_str(), pattern.c_str()); + explicitlyNamed = false; + } + virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver, + string const &ver, bool const &verIsRel) { + if (ver != Ver.VerStr()) + ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), + Ver.VerStr(), Ver.RelStr().c_str(), Pkg.FullName(true).c_str()); + } + + bool showVirtualPackageErrors(pkgCacheFile &Cache) { + if (virtualPkgs.empty() == true) + return true; + for (APT::PackageSet::const_iterator Pkg = virtualPkgs.begin(); + Pkg != virtualPkgs.end(); ++Pkg) { + if (Pkg->ProvidesList != 0) { + ioprintf(c1out,_("Package %s is a virtual package provided by:\n"), + Pkg.FullName(true).c_str()); + + pkgCache::PrvIterator I = Pkg.ProvidesList(); + unsigned short provider = 0; + for (; I.end() == false; ++I) { + pkgCache::PkgIterator Pkg = I.OwnerPkg(); + + if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer()) { + out << " " << Pkg.FullName(true) << " " << I.OwnerVer().VerStr(); + if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false) + out << _(" [Installed]"); + out << endl; + ++provider; + } + } + // if we found no candidate which provide this package, show non-candidates + if (provider == 0) + for (I = Pkg.ProvidesList(); I.end() == false; I++) + out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr() + << _(" [Not candidate version]") << endl; + else + out << _("You should explicitly select one to install.") << endl; + } else { + ioprintf(out, + _("Package %s is not available, but is referred to by another package.\n" + "This may mean that the package is missing, has been obsoleted, or\n" + "is only available from another source\n"),Pkg.FullName(true).c_str()); + + string List; + string VersionsList; + SPtrArray<bool> Seen = new bool[Cache.GetPkgCache()->Head().PackageCount]; + memset(Seen,0,Cache.GetPkgCache()->Head().PackageCount*sizeof(*Seen)); + for (pkgCache::DepIterator Dep = Pkg.RevDependsList(); + Dep.end() == false; Dep++) { + if (Dep->Type != pkgCache::Dep::Replaces) + continue; + if (Seen[Dep.ParentPkg()->ID] == true) + continue; + Seen[Dep.ParentPkg()->ID] = true; + List += Dep.ParentPkg().FullName(true) + " "; + //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ??? + } + ShowList(out,_("However the following packages replace it:"),List,VersionsList); + } + out << std::endl; + } + return false; + } + + virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { + APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDIDATE); + if (verset.empty() == false) + return *(verset.begin()); + if (ShowError == true) { + _error->Error(_("Package '%s' has no installation candidate"),Pkg.FullName(true).c_str()); + virtualPkgs.insert(Pkg); + } + return pkgCache::VerIterator(Cache, 0); + } + + virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { + APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST); + if (verset.empty() == false) + return *(verset.begin()); + if (ShowError == true) + ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str()); + return pkgCache::VerIterator(Cache, 0); + } + + APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, + APT::VersionSet::Version const &select) { + /* This is a pure virtual package and there is a single available + candidate providing it. */ + if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0) + return APT::VersionSet(); + + pkgCache::PkgIterator Prov; + bool found_one = false; + for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; ++P) { + pkgCache::VerIterator const PVer = P.OwnerVer(); + pkgCache::PkgIterator const PPkg = PVer.ParentPkg(); + + /* Ignore versions that are not a candidate. */ + if (Cache[PPkg].CandidateVer != PVer) + continue; + + if (found_one == false) { + Prov = PPkg; + found_one = true; + } else if (PPkg != Prov) { + found_one = false; // we found at least two + break; + } + } + + if (found_one == true) { + ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"), + Prov.FullName(true).c_str(), Pkg.FullName(true).c_str()); + return APT::VersionSet::FromPackage(Cache, Prov, select, *this); + } + return APT::VersionSet(); + } + + inline bool allPkgNamedExplicitly() const { return explicitlyNamed; } + +}; + /*}}}*/ +// TryToInstall - Mark a package for installation /*{{{*/ +struct TryToInstall { + pkgCacheFile* Cache; + pkgProblemResolver* Fix; + bool FixBroken; + unsigned long AutoMarkChanged; + APT::PackageSet doAutoInstallLater; + + TryToInstall(pkgCacheFile &Cache, pkgProblemResolver &PM, bool const &FixBroken) : Cache(&Cache), Fix(&PM), + FixBroken(FixBroken), AutoMarkChanged(0) {}; + + void operator() (pkgCache::VerIterator const &Ver) { + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + + Cache->GetDepCache()->SetCandidateVersion(Ver); + pkgDepCache::StateCache &State = (*Cache)[Pkg]; + + // Handle the no-upgrade case + if (_config->FindB("APT::Get::upgrade",true) == false && Pkg->CurrentVer != 0) + ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"), + Pkg.FullName(true).c_str()); + // Ignore request for install if package would be new + else if (_config->FindB("APT::Get::Only-Upgrade", false) == true && Pkg->CurrentVer == 0) + ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"), + Pkg.FullName(true).c_str()); + else { + Fix->Clear(Pkg); + Fix->Protect(Pkg); + Cache->GetDepCache()->MarkInstall(Pkg,false); + + if (State.Install() == false) { + if (_config->FindB("APT::Get::ReInstall",false) == true) { + if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false) + ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"), + Pkg.FullName(true).c_str()); + else + Cache->GetDepCache()->SetReInstall(Pkg, true); + } else + ioprintf(c1out,_("%s is already the newest version.\n"), + Pkg.FullName(true).c_str()); + } + + // Install it with autoinstalling enabled (if we not respect the minial + // required deps or the policy) + if (FixBroken == false) + doAutoInstallLater.insert(Pkg); + } + + // see if we need to fix the auto-mark flag + // e.g. apt-get install foo + // where foo is marked automatic + if (State.Install() == false && + (State.Flags & pkgCache::Flag::Auto) && + _config->FindB("APT::Get::ReInstall",false) == false && + _config->FindB("APT::Get::Only-Upgrade",false) == false && + _config->FindB("APT::Get::Download-Only",false) == false) + { + ioprintf(c1out,_("%s set to manually installed.\n"), + Pkg.FullName(true).c_str()); + Cache->GetDepCache()->MarkAuto(Pkg,false); + AutoMarkChanged++; + } + } + + void doAutoInstall() { + for (APT::PackageSet::const_iterator P = doAutoInstallLater.begin(); + P != doAutoInstallLater.end(); ++P) { + pkgDepCache::StateCache &State = (*Cache)[P]; + if (State.InstBroken() == false && State.InstPolicyBroken() == false) + continue; + Cache->GetDepCache()->MarkInstall(P, true); + } + doAutoInstallLater.clear(); + } +}; + /*}}}*/ +// TryToRemove - Mark a package for removal /*{{{*/ +struct TryToRemove { + pkgCacheFile* Cache; + pkgProblemResolver* Fix; + bool FixBroken; + bool PurgePkgs; + unsigned long AutoMarkChanged; + + TryToRemove(pkgCacheFile &Cache, pkgProblemResolver &PM) : Cache(&Cache), Fix(&PM), + PurgePkgs(_config->FindB("APT::Get::Purge", false)) {}; + + void operator() (pkgCache::VerIterator const &Ver) + { + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + + Fix->Clear(Pkg); + Fix->Protect(Pkg); + Fix->Remove(Pkg); + + if ((Pkg->CurrentVer == 0 && PurgePkgs == false) || + (PurgePkgs == true && Pkg->CurrentState == pkgCache::State::NotInstalled)) + ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.FullName(true).c_str()); + else + Cache->GetDepCache()->MarkDelete(Pkg, PurgePkgs); + } +}; + /*}}}*/ // CacheFile::NameComp - QSort compare by name /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -681,7 +950,7 @@ bool CacheFile::CheckDeps(bool AllowBroken) } else { - c1out << _("You might want to run `apt-get -f install' to correct these.") << endl; + c1out << _("You might want to run 'apt-get -f install' to correct these.") << endl; ShowBroken(c1out,*this,true); return _error->Error(_("Unmet dependencies. Try using -f.")); @@ -800,36 +1069,35 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, pkgRecords Recs(Cache); if (_error->PendingError() == true) return false; - - // Lock the archive directory - FileFd Lock; - if (_config->FindB("Debug::NoLocking",false) == false && - _config->FindB("APT::Get::Print-URIs") == false) - { - Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock")); - if (_error->PendingError() == true) - return _error->Error(_("Unable to lock the download directory")); - } - + // Create the download object + pkgAcquire Fetcher; AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); - pkgAcquire Fetcher(&Stat); + if (_config->FindB("APT::Get::Print-URIs", false) == true) + { + // force a hashsum for compatibility reasons + _config->CndSet("Acquire::ForceHash", "md5sum"); + if (Fetcher.Setup(&Stat, "") == false) + return false; + } + else if (Fetcher.Setup(&Stat, _config->FindDir("Dir::Cache::Archives")) == false) + return false; // Read the source list - pkgSourceList List; - if (List.ReadMainList() == false) - return _error->Error(_("The list of sources could not be read.")); + if (Cache.BuildSourceList() == false) + return false; + pkgSourceList *List = Cache.GetSourceList(); // Create the package manager and prepare to download SPtr<pkgPackageManager> PM= _system->CreatePM(Cache); - if (PM->GetArchives(&Fetcher,&List,&Recs) == false || + if (PM->GetArchives(&Fetcher,List,&Recs) == false || _error->PendingError() == true) return false; // Display statistics - double FetchBytes = Fetcher.FetchNeeded(); - double FetchPBytes = Fetcher.PartialPresent(); - double DebBytes = Fetcher.TotalNeeded(); + unsigned long long FetchBytes = Fetcher.FetchNeeded(); + unsigned long long FetchPBytes = Fetcher.PartialPresent(); + unsigned long long DebBytes = Fetcher.TotalNeeded(); if (DebBytes != Cache->DebSize()) { c0out << DebBytes << ',' << Cache->DebSize() << endl; @@ -1034,212 +1302,67 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, if (Res == pkgPackageManager::Failed || _error->PendingError() == true) return false; if (Res == pkgPackageManager::Completed) - return true; + break; // Reload the fetcher object and loop again for media swapping Fetcher.Shutdown(); - if (PM->GetArchives(&Fetcher,&List,&Recs) == false) + if (PM->GetArchives(&Fetcher,List,&Recs) == false) return false; _system->Lock(); - } + } + + std::set<std::string> const disappearedPkgs = PM->GetDisappearedPackages(); + if (disappearedPkgs.empty() == true) + return true; + + string disappear; + for (std::set<std::string>::const_iterator d = disappearedPkgs.begin(); + d != disappearedPkgs.end(); ++d) + disappear.append(*d).append(" "); + + ShowList(c1out, P_("The following package disappeared from your system as\n" + "all files have been overwritten by other packages:", + "The following packages disappeared from your system as\n" + "all files have been overwritten by other packages:", disappearedPkgs.size()), disappear, ""); + c0out << _("Note: This is done automatic and on purpose by dpkg.") << std::endl; + + return true; } /*}}}*/ -// TryToInstall - Try to install a single package /*{{{*/ +// TryToInstallBuildDep - Try to install a single package /*{{{*/ // --------------------------------------------------------------------- /* This used to be inlined in DoInstall, but with the advent of regex package name matching it was split out.. */ -bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, +bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, pkgProblemResolver &Fix,bool Remove,bool BrokenFix, - unsigned int &ExpectedInst,bool AllowFail = true) + bool AllowFail = true) { - /* This is a pure virtual package and there is a single available - candidate providing it. */ if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0) { - pkgCache::PkgIterator Prov; - bool found_one = false; - - for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; P++) - { - pkgCache::VerIterator const PVer = P.OwnerVer(); - pkgCache::PkgIterator const PPkg = PVer.ParentPkg(); - - /* Ignore versions that are not a candidate. */ - if (Cache[PPkg].CandidateVer != PVer) - continue; - - if (found_one == false) - { - Prov = PPkg; - found_one = true; - } - else if (PPkg != Prov) - { - found_one = false; // we found at least two - break; - } - } - - if (found_one == true) - { - ioprintf(c1out,_("Note, selecting %s instead of %s\n"), - Prov.Name(),Pkg.Name()); - Pkg = Prov; - } + CacheSetHelperAPTGet helper(c1out); + helper.showErrors(AllowFail == false); + pkgCache::VerIterator Ver = helper.canNotFindNewestVer(Cache, Pkg); + if (Ver.end() == false) + Pkg = Ver.ParentPkg(); + else if (helper.showVirtualPackageErrors(Cache) == false) + return AllowFail; } - // Handle the no-upgrade case - if (_config->FindB("APT::Get::upgrade",true) == false && - Pkg->CurrentVer != 0) - { - if (AllowFail == true) - ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"), - Pkg.Name()); - return true; - } - - // Check if there is something at all to install - pkgDepCache::StateCache &State = Cache[Pkg]; - if (Remove == true && Pkg->CurrentVer == 0) - { - Fix.Clear(Pkg); - Fix.Protect(Pkg); - Fix.Remove(Pkg); - - /* We want to continue searching for regex hits, so we return false here - otherwise this is not really an error. */ - if (AllowFail == false) - return false; - - ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.Name()); - return true; - } - - if (State.CandidateVer == 0 && Remove == false) - { - if (AllowFail == false) - return false; - - if (Pkg->ProvidesList != 0) - { - ioprintf(c1out,_("Package %s is a virtual package provided by:\n"), - Pkg.Name()); - - pkgCache::PrvIterator I = Pkg.ProvidesList(); - for (; I.end() == false; I++) - { - pkgCache::PkgIterator Pkg = I.OwnerPkg(); - - if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer()) - { - if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false) - c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << - _(" [Installed]") << endl; - else - c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl; - } - } - c1out << _("You should explicitly select one to install.") << endl; - } - else - { - ioprintf(c1out, - _("Package %s is not available, but is referred to by another package.\n" - "This may mean that the package is missing, has been obsoleted, or\n" - "is only available from another source\n"),Pkg.Name()); - - string List; - string VersionsList; - SPtrArray<bool> Seen = new bool[Cache.Head().PackageCount]; - memset(Seen,0,Cache.Head().PackageCount*sizeof(*Seen)); - pkgCache::DepIterator Dep = Pkg.RevDependsList(); - for (; Dep.end() == false; Dep++) - { - if (Dep->Type != pkgCache::Dep::Replaces) - continue; - if (Seen[Dep.ParentPkg()->ID] == true) - continue; - Seen[Dep.ParentPkg()->ID] = true; - List += string(Dep.ParentPkg().Name()) + " "; - //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ??? - } - ShowList(c1out,_("However the following packages replace it:"),List,VersionsList); - } - - _error->Error(_("Package %s has no installation candidate"),Pkg.Name()); - return false; - } - - Fix.Clear(Pkg); - Fix.Protect(Pkg); if (Remove == true) { - Fix.Remove(Pkg); - Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false)); - return true; - } - - // Install it - Cache.MarkInstall(Pkg,false); - if (State.Install() == false) - { - if (_config->FindB("APT::Get::ReInstall",false) == true) - { - if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false) - ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"), - Pkg.Name()); - else - Cache.SetReInstall(Pkg,true); - } - else - { - if (AllowFail == true) - ioprintf(c1out,_("%s is already the newest version.\n"), - Pkg.Name()); - } - } - else - ExpectedInst++; - - // Install it with autoinstalling enabled (if we not respect the minial - // required deps or the policy) - if ((State.InstBroken() == true || State.InstPolicyBroken() == true) && BrokenFix == false) - Cache.MarkInstall(Pkg,true); + TryToRemove RemoveAction(Cache, Fix); + RemoveAction(Pkg.VersionList()); + } else if (Cache[Pkg].CandidateVer != 0) { + TryToInstall InstallAction(Cache, Fix, BrokenFix); + InstallAction(Cache[Pkg].CandidateVerIter(Cache)); + InstallAction.doAutoInstall(); + } else + return AllowFail; return true; } /*}}}*/ -// TryToChangeVer - Try to change a candidate version /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool TryToChangeVer(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, - const char *VerTag,bool IsRel) -{ - pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release : - pkgVersionMatch::Version)); - - pkgCache::VerIterator Ver = Match.Find(Pkg); - - if (Ver.end() == true) - { - if (IsRel == true) - return _error->Error(_("Release '%s' for '%s' was not found"), - VerTag,Pkg.Name()); - return _error->Error(_("Version '%s' for '%s' was not found"), - VerTag,Pkg.Name()); - } - - if (strcmp(VerTag,Ver.VerStr()) != 0) - { - ioprintf(c1out,_("Selected version %s (%s) for %s\n"), - Ver.VerStr(),Ver.RelStr().c_str(),Pkg.Name()); - } - - Cache.SetCandidateVersion(Ver); - return true; -} - /*}}}*/ // FindSrc - Find a source record /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -1270,12 +1393,30 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, { if(VerTag.empty() == false || DefRel.empty() == false) { + bool fuzzy = false; // we have a default release, try to locate the pkg. we do it like // this because GetCandidateVer() will not "downgrade", that means // "apt-get source -t stable apt" won't work on a unstable system - for (pkgCache::VerIterator Ver = Pkg.VersionList(); - Ver.end() == false; Ver++) + for (pkgCache::VerIterator Ver = Pkg.VersionList();; Ver++) { + // try first only exact matches, later fuzzy matches + if (Ver.end() == true) + { + if (fuzzy == true) + break; + fuzzy = true; + Ver = Pkg.VersionList(); + // exit right away from the Pkg.VersionList() loop if we + // don't have any versions + if (Ver.end() == true) + break; + } + // We match against a concrete version (or a part of this version) + if (VerTag.empty() == false && + (fuzzy == true || Cache.VS().CmpVersion(VerTag, Ver.VerStr()) != 0) && // exact match + (fuzzy == false || strncmp(VerTag.c_str(), Ver.VerStr(), VerTag.size()) != 0)) // fuzzy match + continue; + for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false; VF++) { @@ -1288,10 +1429,6 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgCache::Flag::NotSource && Pkg.CurrentVer() != Ver) continue; - // We match against a concrete version (or a part of this version) - if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.VerStr(), VerTag.size()) != 0) - continue; - // or we match against a release if(VerTag.empty() == false || (VF.File().Archive() != 0 && VF.File().Archive() == DefRel) || @@ -1302,10 +1439,9 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, // no SourcePkg name, so it is the "binary" name if (Src.empty() == true) Src = TmpSrc; - // no Version, so we try the Version of the SourcePkg - - // and after that the version of the binary package - if (VerTag.empty() == true) - VerTag = Parse.SourceVer(); + // the Version we have is possibly fuzzy or includes binUploads, + // so we use the Version of the SourcePkg (empty if same as package) + VerTag = Parse.SourceVer(); if (VerTag.empty() == true) VerTag = Ver.VerStr(); break; @@ -1371,7 +1507,8 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, const string Ver = Parse->Version(); // Ignore all versions which doesn't fit - if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.c_str(), VerTag.size()) != 0) + if (VerTag.empty() == false && + Cache.VS().CmpVersion(VerTag, Ver) != 0) // exact match continue; // Newer version or an exact match? Save the hit @@ -1405,33 +1542,31 @@ bool DoUpdate(CommandLine &CmdL) { if (CmdL.FileSize() != 1) return _error->Error(_("The update command takes no arguments")); - + + CacheFile Cache; + // Get the source list - pkgSourceList List; - if (List.ReadMainList() == false) + if (Cache.BuildSourceList() == false) return false; + pkgSourceList *List = Cache.GetSourceList(); - // Lock the list directory - FileFd Lock; - if (_config->FindB("Debug::NoLocking",false) == false) - { - Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock")); - if (_error->PendingError() == true) - return _error->Error(_("Unable to lock the list directory")); - } - // Create the progress AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); // Just print out the uris an exit if the --print-uris flag was used if (_config->FindB("APT::Get::Print-URIs") == true) { + // force a hashsum for compatibility reasons + _config->CndSet("Acquire::ForceHash", "md5sum"); + // get a fetcher - pkgAcquire Fetcher(&Stat); + pkgAcquire Fetcher; + if (Fetcher.Setup(&Stat) == false) + return false; // Populate it with the source selection and get all Indexes // (GetAll=true) - if (List.GetIndexes(&Fetcher,true) == false) + if (List->GetIndexes(&Fetcher,true) == false) return false; pkgAcquire::UriIterator I = Fetcher.UriBegin(); @@ -1442,9 +1577,8 @@ bool DoUpdate(CommandLine &CmdL) } // do the work - CacheFile Cache; if (_config->FindB("APT::Get::Download",true) == true) - ListUpdate(Stat, List); + ListUpdate(Stat, *List); // Rebuild the cache. if (Cache.BuildCaches() == false) @@ -1491,7 +1625,7 @@ bool DoAutomaticRemove(CacheFile &Cache) { if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install()) if(Debug) - std::cout << "We could delete %s" << Pkg.Name() << std::endl; + std::cout << "We could delete %s" << Pkg.FullName(true).c_str() << std::endl; if (doAutoRemove) { @@ -1506,12 +1640,11 @@ bool DoAutomaticRemove(CacheFile &Cache) // only show stuff in the list that is not yet marked for removal if(Cache[Pkg].Delete() == false) { + ++autoRemoveCount; // we don't need to fill the strings if we don't need them - if (smallList == true) - ++autoRemoveCount; - else + if (smallList == false) { - autoremovelist += string(Pkg.Name()) + " "; + autoremovelist += Pkg.FullName(true) + " "; autoremoveversions += string(Cache[Pkg].CandVersion) + "\n"; } } @@ -1522,9 +1655,12 @@ bool DoAutomaticRemove(CacheFile &Cache) if (doAutoRemove == false && (autoremovelist.empty() == false || autoRemoveCount != 0)) { if (smallList == false) - ShowList(c1out, _("The following packages were automatically installed and are no longer required:"), autoremovelist, autoremoveversions); + ShowList(c1out, P_("The following package was automatically installed and is no longer required:", + "The following packages were automatically installed and are no longer required:", + autoRemoveCount), autoremovelist, autoremoveversions); else - ioprintf(c1out, _("%lu packages were automatically installed and are no longer required.\n"), autoRemoveCount); + ioprintf(c1out, P_("%lu package was automatically installed and is no longer required.\n", + "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount), autoRemoveCount); c1out << _("Use 'apt-get autoremove' to remove them.") << std::endl; } // Now see if we had destroyed anything (if we had done anything) @@ -1562,61 +1698,6 @@ bool DoUpgrade(CommandLine &CmdL) return InstallPackages(Cache,true); } /*}}}*/ -// DoInstallTask - Install task from the command line /*{{{*/ -// --------------------------------------------------------------------- -/* Install named task */ -bool TryInstallTask(pkgDepCache &Cache, pkgProblemResolver &Fix, - bool BrokenFix, - unsigned int& ExpectedInst, - const char *taskname, - bool Remove) -{ - const char *start, *end; - pkgCache::PkgIterator Pkg; - char buf[64*1024]; - regex_t Pattern; - - // get the records - pkgRecords Recs(Cache); - - // build regexp for the task - char S[300]; - snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", taskname); - if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0) - return _error->Error("Failed to compile task regexp"); - - bool found = false; - bool res = true; - - // two runs, first ignore dependencies, second install any missing - for(int IgnoreBroken=1; IgnoreBroken >= 0; IgnoreBroken--) - { - for (Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) - { - pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache); - if(ver.end()) - continue; - pkgRecords::Parser &parser = Recs.Lookup(ver.FileList()); - parser.GetRec(start,end); - strncpy(buf, start, end-start); - buf[end-start] = 0x0; - if (regexec(&Pattern,buf,0,0,0) != 0) - continue; - res &= TryToInstall(Pkg,Cache,Fix,Remove,IgnoreBroken,ExpectedInst); - found = true; - } - } - - // now let the problem resolver deal with any issues - Fix.Resolve(true); - - if(!found) - _error->Error(_("Couldn't find task %s"),taskname); - - regfree(&Pattern); - return res; -} - /*}}}*/ // DoInstall - Install packages from the command line /*{{{*/ // --------------------------------------------------------------------- /* Install named packages */ @@ -1632,169 +1713,75 @@ bool DoInstall(CommandLine &CmdL) if (Cache->BrokenCount() != 0) BrokenFix = true; - unsigned int AutoMarkChanged = 0; - unsigned int ExpectedInst = 0; - unsigned int Packages = 0; pkgProblemResolver Fix(Cache); - - bool DefRemove = false; + + static const unsigned short MOD_REMOVE = 1; + static const unsigned short MOD_INSTALL = 2; + + unsigned short fallback = MOD_INSTALL; if (strcasecmp(CmdL.FileList[0],"remove") == 0) - DefRemove = true; + fallback = MOD_REMOVE; else if (strcasecmp(CmdL.FileList[0], "purge") == 0) { _config->Set("APT::Get::Purge", true); - DefRemove = true; + fallback = MOD_REMOVE; } else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0) { _config->Set("APT::Get::AutomaticRemove", "true"); - DefRemove = true; + fallback = MOD_REMOVE; } - // new scope for the ActionGroup + + std::list<APT::VersionSet::Modifier> mods; + mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+", + APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDIDATE)); + mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-", + APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::NEWEST)); + CacheSetHelperAPTGet helper(c0out); + std::map<unsigned short, APT::VersionSet> verset = APT::VersionSet::GroupedFromCommandLine(Cache, + CmdL.FileList + 1, mods, fallback, helper); + + if (_error->PendingError() == true) { - pkgDepCache::ActionGroup group(Cache); - for (const char **I = CmdL.FileList + 1; *I != 0; I++) - { - // Duplicate the string - unsigned int Length = strlen(*I); - char S[300]; - if (Length >= sizeof(S)) - continue; - strcpy(S,*I); - - // See if we are removing and special indicators.. - bool Remove = DefRemove; - char *VerTag = 0; - bool VerIsRel = false; + helper.showVirtualPackageErrors(Cache); + return false; + } - // this is a task! - if (Length >= 1 && S[Length - 1] == '^') - { - S[--Length] = 0; - // tasks must always be confirmed - ExpectedInst += 1000; - // see if we can install it - TryInstallTask(Cache, Fix, BrokenFix, ExpectedInst, S, Remove); - continue; - } + unsigned short order[] = { 0, 0, 0 }; + if (fallback == MOD_INSTALL) { + order[0] = MOD_INSTALL; + order[1] = MOD_REMOVE; + } else { + order[0] = MOD_REMOVE; + order[1] = MOD_INSTALL; + } - while (Cache->FindPkg(S).end() == true) - { - // Handle an optional end tag indicating what to do - if (Length >= 1 && S[Length - 1] == '-') - { - Remove = true; - S[--Length] = 0; - continue; - } - - if (Length >= 1 && S[Length - 1] == '+') - { - Remove = false; - S[--Length] = 0; - continue; - } - - char *Slash = strchr(S,'='); - if (Slash != 0) - { - VerIsRel = false; - *Slash = 0; - VerTag = Slash + 1; - } - - Slash = strchr(S,'/'); - if (Slash != 0) - { - VerIsRel = true; - *Slash = 0; - VerTag = Slash + 1; - } - - break; - } - - // Locate the package - pkgCache::PkgIterator Pkg = Cache->FindPkg(S); - Packages++; - if (Pkg.end() == true) - { - // Check if the name is a regex - const char *I; - for (I = S; *I != 0; I++) - if (*I == '?' || *I == '*' || *I == '|' || - *I == '[' || *I == '^' || *I == '$') - break; - if (*I == 0) - return _error->Error(_("Couldn't find package %s"),S); + TryToInstall InstallAction(Cache, Fix, BrokenFix); + TryToRemove RemoveAction(Cache, Fix); - // Regexs must always be confirmed - ExpectedInst += 1000; - - // Compile the regex pattern - regex_t Pattern; - int Res; - if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE | - REG_NOSUB)) != 0) - { - char Error[300]; - regerror(Res,&Pattern,Error,sizeof(Error)); - return _error->Error(_("Regex compilation error - %s"),Error); - } - - // Run over the matches - bool Hit = false; - for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++) - { - if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0) - continue; - - ioprintf(c1out,_("Note, selecting %s for regex '%s'\n"), - Pkg.Name(),S); - - if (VerTag != 0) - if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false) - return false; - - Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix, - ExpectedInst,false); - } - regfree(&Pattern); - - if (Hit == false) - return _error->Error(_("Couldn't find package %s"),S); + // new scope for the ActionGroup + { + pkgDepCache::ActionGroup group(Cache); + + for (unsigned short i = 0; order[i] != 0; ++i) + { + if (order[i] == MOD_INSTALL) { + InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction); + InstallAction.doAutoInstall(); } - else - { - if (VerTag != 0) - if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false) - return false; - if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false) - return false; - - // see if we need to fix the auto-mark flag - // e.g. apt-get install foo - // where foo is marked automatic - if(!Remove && - Cache[Pkg].Install() == false && - (Cache[Pkg].Flags & pkgCache::Flag::Auto) && - _config->FindB("APT::Get::ReInstall",false) == false && - _config->FindB("APT::Get::Download-Only",false) == false) - { - ioprintf(c1out,_("%s set to manually installed.\n"), - Pkg.Name()); - Cache->MarkAuto(Pkg,false); - AutoMarkChanged++; - } - } + else if (order[i] == MOD_REMOVE) + RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction); } + if (_error->PendingError() == true) + return false; + /* If we are in the Broken fixing mode we do not attempt to fix the problems. This is if the user invoked install without -f and gave packages */ if (BrokenFix == true && Cache->BrokenCount() != 0) { - c1out << _("You might want to run `apt-get -f install' to correct these:") << endl; + c1out << _("You might want to run 'apt-get -f install' to correct these:") << endl; ShowBroken(c1out,Cache,false); return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).")); @@ -1835,7 +1822,7 @@ bool DoInstall(CommandLine &CmdL) /* Print out a list of packages that are going to be installed extra to what the user asked */ - if (Cache->InstCount() != ExpectedInst) + if (Cache->InstCount() != verset[MOD_INSTALL].size()) { string List; string VersionsList; @@ -1851,7 +1838,7 @@ bool DoInstall(CommandLine &CmdL) break; if (*J == 0) { - List += string(I.Name()) + " "; + List += I.FullName(true) + " "; VersionsList += string(Cache[I].CandVersion) + "\n"; } } @@ -1887,10 +1874,11 @@ bool DoInstall(CommandLine &CmdL) for(;;) { /* Skip if package is installed already, or is about to be */ - string target = string(Start.TargetPkg().Name()) + " "; - - if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install - || Cache[Start.TargetPkg()].Install()) + string target = Start.TargetPkg().FullName(true) + " "; + pkgCache::PkgIterator const TarPkg = Start.TargetPkg(); + if (TarPkg->SelectedState == pkgCache::State::Install || + TarPkg->SelectedState == pkgCache::State::Hold || + Cache[Start.TargetPkg()].Install()) { foundInstalledInOrGroup=true; break; @@ -1953,18 +1941,59 @@ bool DoInstall(CommandLine &CmdL) // if nothing changed in the cache, but only the automark information // we write the StateFile here, otherwise it will be written in // cache.commit() - if (AutoMarkChanged > 0 && + if (InstallAction.AutoMarkChanged > 0 && Cache->DelCount() == 0 && Cache->InstCount() == 0 && Cache->BadCount() == 0 && _config->FindB("APT::Get::Simulate",false) == false) Cache->writeStateFile(NULL); // See if we need to prompt - if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0) + // FIXME: check if really the packages in the set are going to be installed + if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0) return InstallPackages(Cache,false,false); return InstallPackages(Cache,false); } + +/* mark packages as automatically/manually installed. */ +bool DoMarkAuto(CommandLine &CmdL) +{ + bool Action = true; + int AutoMarkChanged = 0; + OpTextProgress progress; + CacheFile Cache; + if (Cache.Open() == false) + return false; + + if (strcasecmp(CmdL.FileList[0],"markauto") == 0) + Action = true; + else if (strcasecmp(CmdL.FileList[0],"unmarkauto") == 0) + Action = false; + + for (const char **I = CmdL.FileList + 1; *I != 0; I++) + { + const char *S = *I; + // Locate the package + pkgCache::PkgIterator Pkg = Cache->FindPkg(S); + if (Pkg.end() == true) { + return _error->Error(_("Couldn't find package %s"),S); + } + else + { + if (!Action) + ioprintf(c1out,_("%s set to manually installed.\n"), Pkg.Name()); + else + ioprintf(c1out,_("%s set to automatically installed.\n"), + Pkg.Name()); + + Cache->MarkAuto(Pkg,Action); + AutoMarkChanged++; + } + } + if (AutoMarkChanged && ! _config->FindB("APT::Get::Simulate",false)) + return Cache->writeStateFile(NULL); + return false; +} /*}}}*/ // DoDistUpgrade - Automatic smart upgrader /*{{{*/ // --------------------------------------------------------------------- @@ -2161,25 +2190,35 @@ bool DoSource(CommandLine &CmdL) return _error->Error(_("Must specify at least one package to fetch source for")); // Read the source list - pkgSourceList List; - if (List.ReadMainList() == false) - return _error->Error(_("The list of sources could not be read.")); + if (Cache.BuildSourceList() == false) + return false; + pkgSourceList *List = Cache.GetSourceList(); // Create the text record parsers pkgRecords Recs(Cache); - pkgSrcRecords SrcRecs(List); + pkgSrcRecords SrcRecs(*List); if (_error->PendingError() == true) return false; // Create the download object AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); - pkgAcquire Fetcher(&Stat); + pkgAcquire Fetcher; + if (Fetcher.Setup(&Stat) == false) + return false; DscFile *Dsc = new DscFile[CmdL.FileSize()]; // insert all downloaded uris into this set to avoid downloading them // twice set<string> queued; + + // Diff only mode only fetches .diff files + bool const diffOnly = _config->FindB("APT::Get::Diff-Only", false); + // Tar only mode only fetches .tar files + bool const tarOnly = _config->FindB("APT::Get::Tar-Only", false); + // Dsc only mode only fetches .dsc files + bool const dscOnly = _config->FindB("APT::Get::Dsc-Only", false); + // Load the requestd sources into the fetcher unsigned J = 0; for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) @@ -2190,6 +2229,33 @@ bool DoSource(CommandLine &CmdL) if (Last == 0) return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); + string srec = Last->AsStr(); + string::size_type pos = srec.find("\nVcs-"); + while (pos != string::npos) + { + pos += strlen("\nVcs-"); + string vcs = srec.substr(pos,srec.find(":",pos)-pos); + if(vcs == "Browser") + { + pos = srec.find("\nVcs-", pos); + continue; + } + pos += vcs.length()+2; + string::size_type epos = srec.find("\n", pos); + string uri = srec.substr(pos,epos-pos).c_str(); + ioprintf(c1out, _("NOTICE: '%s' packaging is maintained in " + "the '%s' version control system at:\n" + "%s\n"), + Src.c_str(), vcs.c_str(), uri.c_str()); + if(vcs == "Bzr") + ioprintf(c1out,_("Please use:\n" + "bzr get %s\n" + "to retrieve the latest (possibly unreleased) " + "updates to the package.\n"), + uri.c_str()); + break; + } + // Back track vector<pkgSrcRecords::File> Lst; if (Last->Files(Lst) == false) @@ -2206,21 +2272,17 @@ bool DoSource(CommandLine &CmdL) Dsc[J].Version = Last->Version(); Dsc[J].Dsc = flNotDir(I->Path); } - - // Diff only mode only fetches .diff files - if (_config->FindB("APT::Get::Diff-Only",false) == true && - I->Type != "diff") - continue; - - // Tar only mode only fetches .tar files - if (_config->FindB("APT::Get::Tar-Only",false) == true && - I->Type != "tar") - continue; - // Dsc only mode only fetches .dsc files - if (_config->FindB("APT::Get::Dsc-Only",false) == true && - I->Type != "dsc") - continue; + // Handle the only options so that multiple can be used at once + if (diffOnly == true || tarOnly == true || dscOnly == true) + { + if ((diffOnly == true && I->Type == "diff") || + (tarOnly == true && I->Type == "tar") || + (dscOnly == true && I->Type == "dsc")) + ; // Fine, we want this file downloaded + else + continue; + } // don't download the same uri twice (should this be moved to // the fetcher interface itself?) @@ -2250,9 +2312,9 @@ bool DoSource(CommandLine &CmdL) } // Display statistics - double FetchBytes = Fetcher.FetchNeeded(); - double FetchPBytes = Fetcher.PartialPresent(); - double DebBytes = Fetcher.TotalNeeded(); + unsigned long long FetchBytes = Fetcher.FetchNeeded(); + unsigned long long FetchPBytes = Fetcher.PartialPresent(); + unsigned long long DebBytes = Fetcher.TotalNeeded(); // Check for enough free space struct statvfs Buf; @@ -2288,6 +2350,7 @@ bool DoSource(CommandLine &CmdL) { for (unsigned I = 0; I != J; I++) ioprintf(cout,_("Fetch source %s\n"),Dsc[I].Package.c_str()); + delete[] Dsc; return true; } @@ -2298,6 +2361,7 @@ bool DoSource(CommandLine &CmdL) for (; I != Fetcher.UriEnd(); I++) cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl; + delete[] Dsc; return true; } @@ -2323,6 +2387,7 @@ bool DoSource(CommandLine &CmdL) if (_config->FindB("APT::Get::Download-only",false) == true) { c1out << _("Download complete and in download only mode") << endl; + delete[] Dsc; return true; } @@ -2331,6 +2396,7 @@ bool DoSource(CommandLine &CmdL) if (Process == 0) { + bool const fixBroken = _config->FindB("APT::Get::Fix-Broken", false); for (unsigned I = 0; I != J; I++) { string Dir = Dsc[I].Package + '-' + Cache->VS().UpstreamVersion(Dsc[I].Version.c_str()); @@ -2343,7 +2409,7 @@ bool DoSource(CommandLine &CmdL) // See if the package is already unpacked struct stat Stat; - if (stat(Dir.c_str(),&Stat) == 0 && + if (fixBroken == false && stat(Dir.c_str(),&Stat) == 0 && S_ISDIR(Stat.st_mode) != 0) { ioprintf(c0out ,_("Skipping unpack of already unpacked source in %s\n"), @@ -2384,7 +2450,8 @@ bool DoSource(CommandLine &CmdL) _exit(0); } - + delete[] Dsc; + // Wait for the subprocess int Status = 0; while (waitpid(Process,&Status,0) != Process) @@ -2414,21 +2481,24 @@ bool DoBuildDep(CommandLine &CmdL) return _error->Error(_("Must specify at least one package to check builddeps for")); // Read the source list - pkgSourceList List; - if (List.ReadMainList() == false) - return _error->Error(_("The list of sources could not be read.")); + if (Cache.BuildSourceList() == false) + return false; + pkgSourceList *List = Cache.GetSourceList(); // Create the text record parsers pkgRecords Recs(Cache); - pkgSrcRecords SrcRecs(List); + pkgSrcRecords SrcRecs(*List); if (_error->PendingError() == true) return false; // Create the download object AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); - pkgAcquire Fetcher(&Stat); + pkgAcquire Fetcher; + if (Fetcher.Setup(&Stat) == false) + return false; unsigned J = 0; + bool const StripMultiArch = APT::Configuration::getArchitectures().size() <= 1; for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; @@ -2438,7 +2508,7 @@ bool DoBuildDep(CommandLine &CmdL) // Process the build-dependencies vector<pkgSrcRecords::Parser::BuildDepRec> BuildDeps; - if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only",false)) == false) + if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only", false), StripMultiArch) == false) return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str()); // Also ensure that build-essential packages are present @@ -2464,7 +2534,6 @@ bool DoBuildDep(CommandLine &CmdL) } // Install the requested packages - unsigned int ExpectedInst = 0; vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D; pkgProblemResolver Fix(Cache); bool skipAlternatives = false; // skip remaining alternatives in an or group @@ -2495,7 +2564,7 @@ bool DoBuildDep(CommandLine &CmdL) */ if (IV.end() == false && Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true) - TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst); + TryToInstallBuildDep(Pkg,Cache,Fix,true,false); } else // BuildDep || BuildDepIndep { @@ -2537,7 +2606,7 @@ bool DoBuildDep(CommandLine &CmdL) for (; Prv.end() != true; Prv++) { if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Checking provider " << Prv.OwnerPkg().Name() << endl; + cout << " Checking provider " << Prv.OwnerPkg().FullName() << endl; if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false) break; @@ -2578,7 +2647,7 @@ bool DoBuildDep(CommandLine &CmdL) if (Prv.end() == false) { if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Is provided by installed package " << Prv.OwnerPkg().Name() << endl; + cout << " Is provided by installed package " << Prv.OwnerPkg().FullName() << endl; skipAlternatives = hasAlternatives; continue; } @@ -2603,7 +2672,7 @@ bool DoBuildDep(CommandLine &CmdL) return _error->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"), Last->BuildDepType((*D).Type), Src.c_str(), - Pkg.Name()); + Pkg.FullName(true).c_str()); } } @@ -2611,7 +2680,7 @@ bool DoBuildDep(CommandLine &CmdL) if (_config->FindB("Debug::BuildDeps",false) == true) cout << " Trying to install " << (*D).Package << endl; - if (TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst) == true) + if (TryToInstallBuildDep(Pkg,Cache,Fix,false,false) == true) { // We successfully installed something; skip remaining alternatives skipAlternatives = hasAlternatives; @@ -2652,7 +2721,6 @@ bool DoBuildDep(CommandLine &CmdL) return true; } /*}}}*/ - // DoMoo - Never Ask, Never Tell /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -2743,6 +2811,8 @@ bool ShowHelp(CommandLine &CmdL) " clean - Erase downloaded archive files\n" " autoclean - Erase old downloaded archive files\n" " check - Verify that there are no broken dependencies\n" + " markauto - Mark the given packages as automatically installed\n" + " unmarkauto - Mark the given packages as manually installed\n" "\n" "Options:\n" " -h This help text.\n" @@ -2764,22 +2834,6 @@ bool ShowHelp(CommandLine &CmdL) return true; } /*}}}*/ -// GetInitialize - Initialize things for apt-get /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void GetInitialize() -{ - _config->Set("quiet",0); - _config->Set("help",false); - _config->Set("APT::Get::Download-Only",false); - _config->Set("APT::Get::Simulate",false); - _config->Set("APT::Get::Assume-Yes",false); - _config->Set("APT::Get::Fix-Broken",false); - _config->Set("APT::Get::Force-Yes",false); - _config->Set("APT::Get::List-Cleanup",true); - _config->Set("APT::Get::AutomaticRemove",false); -} - /*}}}*/ // SigWinch - Window size change signal handler /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -2821,6 +2875,7 @@ int main(int argc,const char *argv[]) /*{{{*/ {0,"fix-missing","APT::Get::Fix-Missing",0}, {0,"ignore-hold","APT::Ignore-Hold",0}, {0,"upgrade","APT::Get::upgrade",0}, + {0,"only-upgrade","APT::Get::Only-Upgrade",0}, {0,"force-yes","APT::Get::force-yes",0}, {0,"print-uris","APT::Get::Print-URIs",0}, {0,"diff-only","APT::Get::Diff-Only",0}, @@ -2847,7 +2902,8 @@ int main(int argc,const char *argv[]) /*{{{*/ {"remove",&DoInstall}, {"purge",&DoInstall}, {"autoremove",&DoInstall}, - {"purge",&DoInstall}, + {"markauto",&DoMarkAuto}, + {"unmarkauto",&DoMarkAuto}, {"dist-upgrade",&DoDistUpgrade}, {"dselect-upgrade",&DoDSelectUpgrade}, {"build-dep",&DoBuildDep}, @@ -2898,7 +2954,7 @@ int main(int argc,const char *argv[]) /*{{{*/ } // Deal with stdout not being a tty - if (!isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1) + if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) _config->Set("quiet","1"); // Setup the output streams @@ -2919,13 +2975,11 @@ int main(int argc,const char *argv[]) /*{{{*/ CmdL.DispatchArg(Cmds); // Print any errors or warnings found during parsing - if (_error->empty() == false) - { - bool Errors = _error->PendingError(); + bool const Errors = _error->PendingError(); + if (_config->FindI("quiet",0) > 0) _error->DumpErrors(); - return Errors == true?100:0; - } - - return 0; + else + _error->DumpErrors(GlobalError::DEBUG); + return Errors == true ? 100 : 0; } /*}}}*/ diff --git a/cmdline/apt-key b/cmdline/apt-key index e45468fd4..27731ef7d 100755 --- a/cmdline/apt-key +++ b/cmdline/apt-key @@ -146,6 +146,7 @@ if [ "$1" = "--keyring" ]; then else #echo "generate list" TRUSTEDFILE="/etc/apt/trusted.gpg" + eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring) if [ -r "$TRUSTEDFILE" ]; then GPG="$GPG --keyring $TRUSTEDFILE" fi diff --git a/cmdline/apt-mark b/cmdline/apt-mark index 466a56f27..c64d4356c 100755 --- a/cmdline/apt-mark +++ b/cmdline/apt-mark @@ -8,7 +8,7 @@ import os.path try: import apt_pkg except ImportError: - print "Error importing apt_pkg, is python-apt installed?" + print >> sys.stderr, "Error importing apt_pkg, is python-apt installed?" sys.exit(1) actions = { "markauto" : 1, @@ -19,10 +19,10 @@ def show_automatic(filename): if not os.path.exists(STATE_FILE): return auto = set() - tagfile = apt_pkg.ParseTagFile(open(STATE_FILE)) - while tagfile.Step(): - pkgname = tagfile.Section.get("Package") - autoInst = tagfile.Section.get("Auto-Installed") + tagfile = apt_pkg.TagFile(open(STATE_FILE)) + for section in tagfile: + pkgname = section.get("Package") + autoInst = section.get("Auto-Installed") if int(autoInst): auto.add(pkgname) print "\n".join(sorted(auto)) @@ -33,24 +33,24 @@ def mark_unmark_automatic(filename, action, pkgs): # open the statefile if os.path.exists(STATE_FILE): try: - tagfile = apt_pkg.ParseTagFile(open(STATE_FILE)) + tagfile = apt_pkg.TagFile(open(STATE_FILE)) outfile = open(STATE_FILE+".tmp","w") except IOError, msg: print "%s, are you root?" % (msg) sys.exit(1) - while tagfile.Step(): - pkgname = tagfile.Section.get("Package") - autoInst = tagfile.Section.get("Auto-Installed") + for section in tagfile: + pkgname = section.get("Package") + autoInst = section.get("Auto-Installed") if pkgname in pkgs: if options.verbose: print "changing %s to %s" % (pkgname,action) - newsec = apt_pkg.RewriteSection(tagfile.Section, + newsec = apt_pkg.rewrite_section(section, [], [ ("Auto-Installed",str(action)) ]) pkgs.remove(pkgname) outfile.write(newsec+"\n") else: - outfile.write(str(tagfile.Section)+"\n") + outfile.write(str(section)+"\n") if action == 1: for pkgname in pkgs: if options.verbose: @@ -68,6 +68,7 @@ if __name__ == "__main__": # option parsing parser = OptionParser() parser.usage = "%prog [options] {markauto|unmarkauto} packages..." + parser.epilog = "apt-mark is deprecated, use apt-get markauto/unmarkauto." parser.add_option("-f", "--file", action="store", type="string", dest="filename", help="read/write a different file") @@ -76,9 +77,13 @@ if __name__ == "__main__": help="print verbose status messages to stdout") (options, args) = parser.parse_args() + if not args: + parser.print_help() + sys.exit(1) + # get the state-file if not options.filename: - STATE_FILE = apt_pkg.Config.FindDir("Dir::State") + "extended_states" + STATE_FILE = apt_pkg.config.find_dir("Dir::State") + "extended_states" else: STATE_FILE=options.filename diff --git a/cmdline/apt-report-mirror-failure b/cmdline/apt-report-mirror-failure new file mode 100755 index 000000000..7c390642a --- /dev/null +++ b/cmdline/apt-report-mirror-failure @@ -0,0 +1,29 @@ +#!/usr/bin/python +# +# This is a stub that is meant to support failure reporting of +# mirrors to a central database +# +# its currently not used + +import sys +import urllib +import apt_pkg + +apt_pkg.init() +url = apt_pkg.Config.find("Acquire::Mirror::ReportFailures", "") + #"http://people.ubuntu.com:9000/mirror-failure") + #"http://localhost:9000/mirror-failure") +if not url: + sys.exit(0) + +print "Reporting mirror failure to '%s'" % url + +data = {} +data['mirror'] = sys.argv[1] +data['failurl'] = sys.argv[2] +data['error'] = sys.argv[3] +f = urllib.urlopen(url, urllib.urlencode(data)) +f.read() +f.close() + + diff --git a/cmdline/makefile b/cmdline/makefile index 3260e375b..917ccc96a 100644 --- a/cmdline/makefile +++ b/cmdline/makefile @@ -58,3 +58,9 @@ SOURCE=apt-mark TO=$(BIN) TARGET=program include $(COPY_H) + +# The apt-report-mirror-failure program +#SOURCE=apt-report-mirror-failure +#TO=$(BIN) +#TARGET=program +#include $(COPY_H) |