3 #include <apt-pkg/cachefile.h>
4 #include <apt-pkg/pkgcache.h>
5 #include <apt-pkg/depcache.h>
6 #include <apt-pkg/cacheiterators.h>
7 #include <apt-pkg/aptconfiguration.h>
8 #include <apt-pkg/configuration.h>
9 #include <apt-pkg/progress.h>
10 #include <apt-pkg/policy.h>
11 #include <apt-pkg/strutl.h>
13 #include <apt-private/private-cacheset.h>
19 bool GetLocalitySortedVersionSet(pkgCacheFile
&CacheFile
, /*{{{*/
20 APT::VersionContainerInterface
* const vci
,
21 OpProgress
* const progress
)
23 Matcher null_matcher
= Matcher();
24 return GetLocalitySortedVersionSet(CacheFile
, vci
,
25 null_matcher
, progress
);
27 bool GetLocalitySortedVersionSet(pkgCacheFile
&CacheFile
,
28 APT::VersionContainerInterface
* const vci
,
30 OpProgress
* const progress
)
32 pkgCache
*Cache
= CacheFile
.GetPkgCache();
33 pkgDepCache
*DepCache
= CacheFile
.GetDepCache();
34 APT::CacheSetHelper
helper(false);
38 progress
->SubProgress(Cache
->Head().PackageCount
, _("Sorting"));
40 bool const insertCurrentVer
= _config
->FindB("APT::Cmd::Installed", false);
41 bool const insertUpgradable
= _config
->FindB("APT::Cmd::Upgradable", false);
42 bool const insertManualInstalled
= _config
->FindB("APT::Cmd::Manual-Installed", false);
44 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; ++P
)
49 progress
->Progress(Done
);
53 // exclude virtual pkgs
54 if (P
->VersionList
== 0)
57 if ((matcher
)(P
) == false)
60 pkgDepCache::StateCache
&state
= (*DepCache
)[P
];
61 if (insertCurrentVer
== true)
63 if (P
->CurrentVer
!= 0)
64 vci
->FromPackage(vci
, CacheFile
, P
, APT::CacheSetHelper::INSTALLED
, helper
);
66 else if (insertUpgradable
== true)
68 if(P
.CurrentVer() && state
.Upgradable())
69 vci
->FromPackage(vci
, CacheFile
, P
, APT::CacheSetHelper::CANDIDATE
, helper
);
71 else if (insertManualInstalled
== true)
74 ((*DepCache
)[P
].Flags
& pkgCache::Flag::Auto
) == false)
75 vci
->FromPackage(vci
, CacheFile
, P
, APT::CacheSetHelper::CANDIDATE
, helper
);
79 if (vci
->FromPackage(vci
, CacheFile
, P
, APT::CacheSetHelper::CANDIDATE
, helper
) == false)
81 // no candidate, this may happen for packages in
82 // dpkg "deinstall ok config-file" state - we pick the first ver
83 // (which should be the only one)
84 vci
->insert(P
.VersionList());
94 // CacheSetHelper saving virtual packages /*{{{*/
95 pkgCache::VerIterator
CacheSetHelperVirtuals::canNotGetVersion(
96 enum CacheSetHelper::VerSelector
const select
,
98 pkgCache::PkgIterator
const &Pkg
)
100 if (select
== NEWEST
|| select
== CANDIDATE
|| select
== ALL
)
101 virtualPkgs
.insert(Pkg
);
102 return CacheSetHelper::canNotGetVersion(select
, Cache
, Pkg
);
104 void CacheSetHelperVirtuals::canNotFindVersion(
105 enum CacheSetHelper::VerSelector
const select
,
106 APT::VersionContainerInterface
* vci
,
108 pkgCache::PkgIterator
const &Pkg
)
110 if (select
== NEWEST
|| select
== CANDIDATE
|| select
== ALL
)
111 virtualPkgs
.insert(Pkg
);
112 return CacheSetHelper::canNotFindVersion(select
, vci
, Cache
, Pkg
);
114 CacheSetHelperVirtuals::CacheSetHelperVirtuals(bool const ShowErrors
, GlobalError::MsgType
const &ErrorType
) :
115 CacheSetHelper
{ShowErrors
, ErrorType
}
119 // CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/
120 CacheSetHelperAPTGet::CacheSetHelperAPTGet(std::ostream
&out
) :
121 APT::CacheSetHelper
{true}, out
{out
}
123 explicitlyNamed
= true;
125 void CacheSetHelperAPTGet::showTaskSelection(pkgCache::PkgIterator
const &Pkg
, std::string
const &pattern
)
127 ioprintf(out
, _("Note, selecting '%s' for task '%s'\n"),
128 Pkg
.FullName(true).c_str(), pattern
.c_str());
129 explicitlyNamed
= false;
131 void CacheSetHelperAPTGet::showFnmatchSelection(pkgCache::PkgIterator
const &Pkg
, std::string
const &pattern
)
133 ioprintf(out
, _("Note, selecting '%s' for glob '%s'\n"),
134 Pkg
.FullName(true).c_str(), pattern
.c_str());
135 explicitlyNamed
= false;
137 void CacheSetHelperAPTGet::showRegExSelection(pkgCache::PkgIterator
const &Pkg
, std::string
const &pattern
)
139 ioprintf(out
, _("Note, selecting '%s' for regex '%s'\n"),
140 Pkg
.FullName(true).c_str(), pattern
.c_str());
141 explicitlyNamed
= false;
143 void CacheSetHelperAPTGet::showSelectedVersion(pkgCache::PkgIterator
const &/*Pkg*/, pkgCache::VerIterator
const Ver
,
144 std::string
const &ver
, bool const /*verIsRel*/)
146 if (ver
== Ver
.VerStr())
148 selectedByRelease
.push_back(make_pair(Ver
, ver
));
150 bool CacheSetHelperAPTGet::showVirtualPackageErrors(pkgCacheFile
&Cache
)
152 if (virtualPkgs
.empty() == true)
154 for (APT::PackageSet::const_iterator Pkg
= virtualPkgs
.begin();
155 Pkg
!= virtualPkgs
.end(); ++Pkg
) {
156 if (Pkg
->ProvidesList
!= 0) {
157 ioprintf(c1out
,_("Package %s is a virtual package provided by:\n"),
158 Pkg
.FullName(true).c_str());
160 pkgCache::PrvIterator I
= Pkg
.ProvidesList();
161 unsigned short provider
= 0;
162 for (; I
.end() == false; ++I
) {
163 pkgCache::PkgIterator Pkg
= I
.OwnerPkg();
165 if (Cache
[Pkg
].CandidateVerIter(Cache
) == I
.OwnerVer()) {
166 c1out
<< " " << Pkg
.FullName(true) << " " << I
.OwnerVer().VerStr();
167 if (Cache
[Pkg
].Install() == true && Cache
[Pkg
].NewInstall() == false)
168 c1out
<< _(" [Installed]");
173 // if we found no candidate which provide this package, show non-candidates
175 for (I
= Pkg
.ProvidesList(); I
.end() == false; ++I
)
176 c1out
<< " " << I
.OwnerPkg().FullName(true) << " " << I
.OwnerVer().VerStr()
177 << _(" [Not candidate version]") << std::endl
;
179 out
<< _("You should explicitly select one to install.") << std::endl
;
182 _("Package %s is not available, but is referred to by another package.\n"
183 "This may mean that the package is missing, has been obsoleted, or\n"
184 "is only available from another source\n"),Pkg
.FullName(true).c_str());
187 std::string VersionsList
;
188 std::vector
<bool> Seen(Cache
.GetPkgCache()->Head().PackageCount
, false);
189 APT::PackageList pkglist
;
190 for (pkgCache::DepIterator Dep
= Pkg
.RevDependsList();
191 Dep
.end() == false; ++Dep
) {
192 if (Dep
->Type
!= pkgCache::Dep::Replaces
)
194 pkgCache::PkgIterator
const DP
= Dep
.ParentPkg();
195 if (Seen
[DP
->ID
] == true)
200 ShowList(c1out
, _("However the following packages replace it:"), pkglist
,
201 &AlwaysTrue
, &PrettyFullName
, &EmptyString
);
207 pkgCache::VerIterator
CacheSetHelperAPTGet::canNotFindCandidateVer(pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &Pkg
)
209 APT::VersionSet
const verset
= tryVirtualPackage(Cache
, Pkg
, CacheSetHelper::CANDIDATE
);
210 if (verset
.empty() == false)
211 return *(verset
.begin());
212 else if (ShowError
== true) {
213 _error
->Error(_("Package '%s' has no installation candidate"),Pkg
.FullName(true).c_str());
214 virtualPkgs
.insert(Pkg
);
216 return pkgCache::VerIterator(Cache
, 0);
218 pkgCache::VerIterator
CacheSetHelperAPTGet::canNotFindNewestVer(pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &Pkg
)
220 if (Pkg
->ProvidesList
!= 0)
222 APT::VersionSet
const verset
= tryVirtualPackage(Cache
, Pkg
, CacheSetHelper::NEWEST
);
223 if (verset
.empty() == false)
224 return *(verset
.begin());
225 if (ShowError
== true)
226 ioprintf(out
, _("Virtual packages like '%s' can't be removed\n"), Pkg
.FullName(true).c_str());
230 pkgCache::GrpIterator Grp
= Pkg
.Group();
231 pkgCache::PkgIterator P
= Grp
.PackageList();
232 for (; P
.end() != true; P
= Grp
.NextPkg(P
))
236 if (P
->CurrentVer
!= 0) {
237 // TRANSLATORS: Note, this is not an interactive question
238 ioprintf(c1out
,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
239 Pkg
.FullName(true).c_str(), P
.FullName(true).c_str());
244 ioprintf(c1out
,_("Package '%s' is not installed, so not removed\n"),Pkg
.FullName(true).c_str());
246 return pkgCache::VerIterator(Cache
, 0);
248 APT::VersionSet
CacheSetHelperAPTGet::tryVirtualPackage(pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &Pkg
,
249 CacheSetHelper::VerSelector
const select
)
251 /* This is a pure virtual package and there is a single available
252 candidate providing it. */
253 if (unlikely(Cache
[Pkg
].CandidateVer
!= 0) || Pkg
->ProvidesList
== 0)
254 return APT::VersionSet();
256 pkgCache::PkgIterator Prov
;
257 bool found_one
= false;
258 for (pkgCache::PrvIterator P
= Pkg
.ProvidesList(); P
; ++P
) {
259 pkgCache::VerIterator
const PVer
= P
.OwnerVer();
260 pkgCache::PkgIterator
const PPkg
= PVer
.ParentPkg();
262 /* Ignore versions that are not a candidate. */
263 if (Cache
[PPkg
].CandidateVer
!= PVer
)
266 if (found_one
== false) {
269 } else if (PPkg
!= Prov
) {
270 // same group, so it's a foreign package
271 if (PPkg
->Group
== Prov
->Group
) {
272 // do we already have the requested arch?
273 if (strcmp(Pkg
.Arch(), Prov
.Arch()) == 0 ||
274 strcmp(Prov
.Arch(), "all") == 0 ||
275 unlikely(strcmp(PPkg
.Arch(), Prov
.Arch()) == 0)) // packages have only on candidate, but just to be sure
277 // see which architecture we prefer more and switch to it
278 std::vector
<std::string
> archs
= APT::Configuration::getArchitectures();
279 if (std::find(archs
.begin(), archs
.end(), PPkg
.Arch()) < std::find(archs
.begin(), archs
.end(), Prov
.Arch()))
283 found_one
= false; // we found at least two
288 if (found_one
== true) {
289 ioprintf(out
, _("Note, selecting '%s' instead of '%s'\n"),
290 Prov
.FullName(true).c_str(), Pkg
.FullName(true).c_str());
291 return APT::VersionSet::FromPackage(Cache
, Prov
, select
, *this);
293 return APT::VersionSet();