]> git.saurik.com Git - apt.git/blame - apt-pkg/depcache.cc
CMake: Do not add po/ if USE_NLS is OFF
[apt.git] / apt-pkg / depcache.cc
CommitLineData
6c139d6e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
e7b470ee 3// $Id: depcache.cc,v 1.25 2001/05/27 05:36:04 jgg Exp $
6c139d6e
AL
4/* ######################################################################
5
6 Dependency Cache - Caches Dependency information.
7
8 ##################################################################### */
9 /*}}}*/
10// Include Files /*{{{*/
ea542140
DK
11#include<config.h>
12
094a497d 13#include <apt-pkg/depcache.h>
2c085486 14#include <apt-pkg/versionmatch.h>
a0ed43f7 15#include <apt-pkg/version.h>
094a497d 16#include <apt-pkg/error.h>
afb1e2e3 17#include <apt-pkg/fileutl.h>
fa3b0945 18#include <apt-pkg/strutl.h>
afb1e2e3 19#include <apt-pkg/configuration.h>
8b32e920 20#include <apt-pkg/aptconfiguration.h>
afb1e2e3 21#include <apt-pkg/tagfile.h>
472ff00e 22#include <apt-pkg/progress.h>
2b5c35c7 23#include <apt-pkg/cacheset.h>
453b82a3
DK
24#include <apt-pkg/pkgcache.h>
25#include <apt-pkg/cacheiterators.h>
84573326 26#include <apt-pkg/prettyprinters.h>
9112f777 27#include <apt-pkg/cachefile.h>
453b82a3 28#include <apt-pkg/macros.h>
120365ce 29
453b82a3
DK
30#include <stdio.h>
31#include <string.h>
32#include <list>
33#include <string>
34#include <utility>
35#include <vector>
2b5c35c7 36#include <algorithm>
120365ce 37#include <iostream>
b1a8717a 38#include <set>
d4c5f11f 39
8a3a2e99
MV
40#include <sys/stat.h>
41
ea542140 42#include <apti18n.h>
92fcbfc1 43 /*}}}*/
8f3ba4e8
DK
44
45using std::string;
46
92fcbfc1 47// helper for Install-Recommends-Sections and Never-MarkAuto-Sections /*{{{*/
cb1933df
MV
48static bool
49ConfigValueInSubTree(const char* SubTree, const char *needle)
50{
51 Configuration::Item const *Opts;
52 Opts = _config->Tree(SubTree);
53 if (Opts != 0 && Opts->Child != 0)
54 {
55 Opts = Opts->Child;
56 for (; Opts != 0; Opts = Opts->Next)
57 {
58 if (Opts->Value.empty() == true)
59 continue;
60 if (strcmp(needle, Opts->Value.c_str()) == 0)
61 return true;
62 }
63 }
64 return false;
65}
92fcbfc1
DK
66 /*}}}*/
67pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) : /*{{{*/
6c55f07a 68 d(NULL), cache(cache), released(false)
74a05226
MV
69{
70 ++cache.group_level;
71}
72
73void pkgDepCache::ActionGroup::release()
74{
75 if(!released)
76 {
77 if(cache.group_level == 0)
78 std::cerr << "W: Unbalanced action groups, expect badness" << std::endl;
79 else
80 {
81 --cache.group_level;
82
83 if(cache.group_level == 0)
84 cache.MarkAndSweep();
85 }
86
ab60fb67 87 released = true;
74a05226
MV
88 }
89}
90
91pkgDepCache::ActionGroup::~ActionGroup()
92{
93 release();
94}
92fcbfc1 95 /*}}}*/
6c139d6e
AL
96// DepCache::pkgDepCache - Constructors /*{{{*/
97// ---------------------------------------------------------------------
98/* */
fd23676e 99pkgDepCache::pkgDepCache(pkgCache * const pCache,Policy * const Plcy) :
e8afd168
DK
100 group_level(0), Cache(pCache), PkgState(0), DepState(0),
101 iUsrSize(0), iDownloadSize(0), iInstCount(0), iDelCount(0), iKeepCount(0),
6c55f07a 102 iBrokenCount(0), iPolicyBrokenCount(0), iBadCount(0), d(NULL)
6c139d6e 103{
af29ffb4
MV
104 DebugMarker = _config->FindB("Debug::pkgDepCache::Marker", false);
105 DebugAutoInstall = _config->FindB("Debug::pkgDepCache::AutoInstall", false);
b2e465d6
AL
106 delLocalPolicy = 0;
107 LocalPolicy = Plcy;
108 if (LocalPolicy == 0)
109 delLocalPolicy = LocalPolicy = new Policy;
6c139d6e
AL
110}
111 /*}}}*/
112// DepCache::~pkgDepCache - Destructor /*{{{*/
113// ---------------------------------------------------------------------
114/* */
115pkgDepCache::~pkgDepCache()
116{
117 delete [] PkgState;
118 delete [] DepState;
b2e465d6 119 delete delLocalPolicy;
6c139d6e
AL
120}
121 /*}}}*/
6c139d6e
AL
122// DepCache::Init - Generate the initial extra structures. /*{{{*/
123// ---------------------------------------------------------------------
124/* This allocats the extension buffers and initializes them. */
fd23676e 125bool pkgDepCache::Init(OpProgress * const Prog)
6c139d6e 126{
74a05226
MV
127 // Suppress mark updates during this operation (just in case) and
128 // run a mark operation when Init terminates.
129 ActionGroup actions(*this);
130
6c139d6e
AL
131 delete [] PkgState;
132 delete [] DepState;
133 PkgState = new StateCache[Head().PackageCount];
134 DepState = new unsigned char[Head().DependsCount];
135 memset(PkgState,0,sizeof(*PkgState)*Head().PackageCount);
fd23676e 136 memset(DepState,0,sizeof(*DepState)*Head().DependsCount);
b2e465d6 137
a246f2dc
AL
138 if (Prog != 0)
139 {
140 Prog->OverallProgress(0,2*Head().PackageCount,Head().PackageCount,
db0db9fe
CP
141 _("Building dependency tree"));
142 Prog->SubProgress(Head().PackageCount,_("Candidate versions"));
a246f2dc 143 }
fd23676e 144
6c139d6e
AL
145 /* Set the current state of everything. In this state all of the
146 packages are kept exactly as is. See AllUpgrade */
a246f2dc 147 int Done = 0;
f7f0d6c7 148 for (PkgIterator I = PkgBegin(); I.end() != true; ++I, ++Done)
6c139d6e 149 {
2edcefd5 150 if (Prog != 0 && Done%20 == 0)
a246f2dc 151 Prog->Progress(Done);
fd23676e 152
6c139d6e
AL
153 // Find the proper cache slot
154 StateCache &State = PkgState[I->ID];
155 State.iFlags = 0;
afb1e2e3 156
6c139d6e 157 // Figure out the install version
294a8020 158 State.CandidateVer = LocalPolicy->GetCandidateVer(I);
6c139d6e
AL
159 State.InstallVer = I.CurrentVer();
160 State.Mode = ModeKeep;
fd23676e 161
6c139d6e 162 State.Update(I,*this);
fd23676e
DK
163 }
164
a246f2dc
AL
165 if (Prog != 0)
166 {
a246f2dc
AL
167 Prog->OverallProgress(Head().PackageCount,2*Head().PackageCount,
168 Head().PackageCount,
db0db9fe
CP
169 _("Building dependency tree"));
170 Prog->SubProgress(Head().PackageCount,_("Dependency generation"));
a246f2dc 171 }
fd23676e 172
a246f2dc 173 Update(Prog);
e004867d
MV
174
175 if(Prog != 0)
176 Prog->Done();
74a05226 177
6c139d6e 178 return true;
fd23676e 179}
6c139d6e 180 /*}}}*/
fd23676e 181bool pkgDepCache::readStateFile(OpProgress * const Prog) /*{{{*/
a83d884d
MV
182{
183 FileFd state_file;
d34690e1 184 string const state = _config->FindFile("Dir::State::extended_states");
36f1098a 185 if(RealFileExists(state)) {
a83d884d 186 state_file.Open(state, FileFd::ReadOnly);
650faab0 187 off_t const file_size = state_file.Size();
bc80031f 188 if(Prog != NULL)
fd23676e 189 Prog->OverallProgress(0, file_size, 1,
bc80031f 190 _("Reading state information"));
a83d884d
MV
191
192 pkgTagFile tagfile(&state_file);
193 pkgTagSection section;
650faab0 194 off_t amt = 0;
e0b94b97 195 bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
a83d884d 196 while(tagfile.Step(section)) {
e0b94b97
DK
197 string const pkgname = section.FindS("Package");
198 string pkgarch = section.FindS("Architecture");
199 if (pkgarch.empty() == true)
200 pkgarch = "any";
201 pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch);
202 // Silently ignore unknown packages and packages with no actual version.
203 if(pkg.end() == true || pkg->VersionList == 0)
204 continue;
205
206 short const reason = section.FindI("Auto-Installed", 0);
207 if(reason > 0)
208 {
209 PkgState[pkg->ID].Flags |= Flag::Auto;
210 if (unlikely(debug_autoremove))
6ee2b0f8 211 std::clog << "Auto-Installed : " << pkg.FullName() << std::endl;
e0b94b97
DK
212 if (pkgarch == "any")
213 {
214 pkgCache::GrpIterator G = pkg.Group();
215 for (pkg = G.NextPkg(pkg); pkg.end() != true; pkg = G.NextPkg(pkg))
216 if (pkg->VersionList != 0)
217 PkgState[pkg->ID].Flags |= Flag::Auto;
218 }
a83d884d 219 }
e0b94b97
DK
220 amt += section.size();
221 if(Prog != NULL)
222 Prog->OverallProgress(amt, file_size, 1,
223 _("Reading state information"));
a83d884d 224 }
eef21b9f
DK
225 if(Prog != NULL)
226 Prog->OverallProgress(file_size, file_size, 1,
227 _("Reading state information"));
a83d884d
MV
228 }
229
230 return true;
231}
92fcbfc1 232 /*}}}*/
fd23676e 233bool pkgDepCache::writeStateFile(OpProgress * const /*prog*/, bool const InstalledOnly) /*{{{*/
a83d884d 234{
e0b94b97 235 bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
95afdfd0
OS
236
237 if(debug_autoremove)
e23e6733
MV
238 std::clog << "pkgDepCache::writeStateFile()" << std::endl;
239
b1a8717a 240 FileFd StateFile;
d34690e1 241 string const state = _config->FindFile("Dir::State::extended_states");
1b671a9b
DK
242 if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), flNotFile(state)) == false)
243 return false;
9a9665f9
MV
244
245 // if it does not exist, create a empty one
1b671a9b 246 if(!RealFileExists(state))
9a9665f9 247 {
22041bd2 248 StateFile.Open(state, FileFd::WriteAtomic);
9a9665f9
MV
249 StateFile.Close();
250 }
251
252 // open it
b1a8717a
MV
253 if(!StateFile.Open(state, FileFd::ReadOnly))
254 return _error->Error(_("Failed to open StateFile %s"),
a83d884d
MV
255 state.c_str());
256
88593886
DK
257 FileFd OutFile(state, FileFd::ReadWrite | FileFd::Atomic);
258 if (OutFile.IsOpen() == false || OutFile.Failed() == true)
259 return _error->Error(_("Failed to write temporary StateFile %s"), state.c_str());
80fa0d8a 260
b1a8717a
MV
261 // first merge with the existing sections
262 pkgTagFile tagfile(&StateFile);
263 pkgTagSection section;
264 std::set<string> pkgs_seen;
b1a8717a 265 while(tagfile.Step(section)) {
c176c4d0 266 string const pkgname = section.FindS("Package");
e0b94b97
DK
267 string pkgarch = section.FindS("Architecture");
268 if (pkgarch.empty() == true)
269 pkgarch = "native";
b1a8717a
MV
270 // Silently ignore unknown packages and packages with no actual
271 // version.
e0b94b97 272 pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch);
88593886 273 if(pkg.end() || pkg.VersionList().end())
b1a8717a 274 continue;
c176c4d0
DK
275 StateCache const &P = PkgState[pkg->ID];
276 bool newAuto = (P.Flags & Flag::Auto);
e5c3f3cc 277 // reset to default (=manual) not installed or now-removed ones if requested
c176c4d0
DK
278 if (InstalledOnly && (
279 (pkg->CurrentVer == 0 && P.Mode != ModeInstall) ||
280 (pkg->CurrentVer != 0 && P.Mode == ModeDelete)))
e5c3f3cc
DK
281 newAuto = false;
282 if (newAuto == false)
c176c4d0
DK
283 {
284 // The section is obsolete if it contains no other tag
e5c3f3cc 285 auto const count = section.Count();
c176c4d0 286 if (count < 2 ||
c67dc114
DK
287 (count == 2 && section.Exists("Auto-Installed")) ||
288 (count == 3 && section.Exists("Auto-Installed") && section.Exists("Architecture")))
e5c3f3cc
DK
289 {
290 if(debug_autoremove)
291 std::clog << "Drop obsolete section with " << count << " fields for " << APT::PrettyPkg(this, pkg) << std::endl;
c176c4d0 292 continue;
e5c3f3cc 293 }
c176c4d0 294 }
e5c3f3cc
DK
295
296 if(debug_autoremove)
297 std::clog << "Update existing AutoInstall to " << newAuto << " for " << APT::PrettyPkg(this, pkg) << std::endl;
88593886
DK
298
299 std::vector<pkgTagSection::Tag> rewrite;
300 rewrite.push_back(pkgTagSection::Tag::Rewrite("Architecture", pkg.Arch()));
301 rewrite.push_back(pkgTagSection::Tag::Rewrite("Auto-Installed", newAuto ? "1" : "0"));
302 section.Write(OutFile, NULL, rewrite);
303 if (OutFile.Write("\n", 1) == false)
304 return false;
e0b94b97 305 pkgs_seen.insert(pkg.FullName());
b1a8717a 306 }
88593886 307
b1a8717a 308 // then write the ones we have not seen yet
f7f0d6c7 309 for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); ++pkg) {
c176c4d0
DK
310 StateCache const &P = PkgState[pkg->ID];
311 if(P.Flags & Flag::Auto) {
e0b94b97 312 if (pkgs_seen.find(pkg.FullName()) != pkgs_seen.end()) {
95afdfd0 313 if(debug_autoremove)
e5c3f3cc 314 std::clog << "Skipping already written " << APT::PrettyPkg(this, pkg) << std::endl;
b1a8717a
MV
315 continue;
316 }
c176c4d0
DK
317 // skip not installed ones if requested
318 if (InstalledOnly && (
319 (pkg->CurrentVer == 0 && P.Mode != ModeInstall) ||
320 (pkg->CurrentVer != 0 && P.Mode == ModeDelete)))
321 continue;
95afdfd0 322 if(debug_autoremove)
e5c3f3cc 323 std::clog << "Writing new AutoInstall: " << APT::PrettyPkg(this, pkg) << std::endl;
88593886
DK
324 std::string stanza = "Package: ";
325 stanza.append(pkg.Name())
e5c3f3cc 326 .append("\nArchitecture: ").append(pkg.Arch())
88593886
DK
327 .append("\nAuto-Installed: 1\n\n");
328 if (OutFile.Write(stanza.c_str(), stanza.length()) == false)
329 return false;
a83d884d
MV
330 }
331 }
52093186
DK
332 if (StateFile.Failed())
333 {
334 OutFile.OpFail();
335 return false;
336 }
88593886
DK
337 if (OutFile.Close() == false)
338 return false;
8a3a2e99 339 chmod(state.c_str(), 0644);
a83d884d
MV
340 return true;
341}
92fcbfc1 342 /*}}}*/
6c139d6e
AL
343// DepCache::CheckDep - Checks a single dependency /*{{{*/
344// ---------------------------------------------------------------------
345/* This first checks the dependency against the main target package and
346 then walks along the package provides list and checks if each provides
347 will be installed then checks the provides against the dep. Res will be
348 set to the package which was used to satisfy the dep. */
fd23676e 349bool pkgDepCache::CheckDep(DepIterator const &Dep,int const Type,PkgIterator &Res)
6c139d6e
AL
350{
351 Res = Dep.TargetPkg();
352
353 /* Check simple depends. A depends -should- never self match but
354 we allow it anyhow because dpkg does. Technically it is a packaging
355 bug. Conflicts may never self match */
021626db 356 if (Dep.IsIgnorable(Res) == false)
6c139d6e 357 {
6c139d6e 358 // Check the base package
fd23676e
DK
359 if (Type == NowVersion)
360 {
71c9e95b 361 if (Res->CurrentVer != 0 && Dep.IsSatisfied(Res.CurrentVer()) == true)
6c139d6e 362 return true;
fd23676e
DK
363 }
364 else if (Type == InstallVersion)
365 {
71c9e95b
DK
366 if (PkgState[Res->ID].InstallVer != 0 &&
367 Dep.IsSatisfied(PkgState[Res->ID].InstVerIter(*this)) == true)
6c139d6e 368 return true;
fd23676e
DK
369 }
370 else if (Type == CandidateVersion)
71c9e95b
DK
371 if (PkgState[Res->ID].CandidateVer != 0 &&
372 Dep.IsSatisfied(PkgState[Res->ID].CandidateVerIter(*this)) == true)
6c139d6e
AL
373 return true;
374 }
fd23676e 375
b2e465d6
AL
376 if (Dep->Type == Dep::Obsoletes)
377 return false;
fd23676e 378
6c139d6e
AL
379 // Check the providing packages
380 PrvIterator P = Dep.TargetPkg().ProvidesList();
f7f0d6c7 381 for (; P.end() != true; ++P)
6c139d6e 382 {
85434114
DK
383 if (Dep.IsIgnorable(P) == true)
384 continue;
88a52816 385
6c139d6e
AL
386 // Check if the provides is a hit
387 if (Type == NowVersion)
388 {
389 if (P.OwnerPkg().CurrentVer() != P.OwnerVer())
390 continue;
391 }
fd23676e 392 else if (Type == InstallVersion)
6c139d6e
AL
393 {
394 StateCache &State = PkgState[P.OwnerPkg()->ID];
395 if (State.InstallVer != (Version *)P.OwnerVer())
396 continue;
397 }
fd23676e 398 else if (Type == CandidateVersion)
6c139d6e
AL
399 {
400 StateCache &State = PkgState[P.OwnerPkg()->ID];
401 if (State.CandidateVer != (Version *)P.OwnerVer())
402 continue;
403 }
fd23676e 404
6c139d6e 405 // Compare the versions.
887c6940 406 if (Dep.IsSatisfied(P) == true)
6c139d6e
AL
407 {
408 Res = P.OwnerPkg();
409 return true;
410 }
411 }
fd23676e 412
6c139d6e
AL
413 return false;
414}
415 /*}}}*/
416// DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
417// ---------------------------------------------------------------------
81305a0b 418/* Call with Inverse = true to preform the inverse opration */
6935cd05 419void pkgDepCache::AddSizes(const PkgIterator &Pkg, bool const Inverse)
81305a0b
DK
420{
421 StateCache &P = PkgState[Pkg->ID];
422
423 if (Pkg->VersionList == 0)
424 return;
425
426 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
427 P.Keep() == true)
428 return;
429
430 // Compute the size data
431 if (P.NewInstall() == true)
432 {
433 if (Inverse == false) {
434 iUsrSize += P.InstVerIter(*this)->InstalledSize;
435 iDownloadSize += P.InstVerIter(*this)->Size;
436 } else {
437 iUsrSize -= P.InstVerIter(*this)->InstalledSize;
438 iDownloadSize -= P.InstVerIter(*this)->Size;
439 }
440 return;
441 }
442
443 // Upgrading
444 if (Pkg->CurrentVer != 0 &&
445 (P.InstallVer != (Version *)Pkg.CurrentVer() ||
446 (P.iFlags & ReInstall) == ReInstall) && P.InstallVer != 0)
447 {
448 if (Inverse == false) {
449 iUsrSize -= Pkg.CurrentVer()->InstalledSize;
450 iUsrSize += P.InstVerIter(*this)->InstalledSize;
451 iDownloadSize += P.InstVerIter(*this)->Size;
452 } else {
453 iUsrSize -= P.InstVerIter(*this)->InstalledSize;
454 iUsrSize += Pkg.CurrentVer()->InstalledSize;
455 iDownloadSize -= P.InstVerIter(*this)->Size;
456 }
457 return;
458 }
459
460 // Reinstall
461 if (Pkg.State() == pkgCache::PkgIterator::NeedsUnpack &&
462 P.Delete() == false)
463 {
464 if (Inverse == false)
465 iDownloadSize += P.InstVerIter(*this)->Size;
466 else
467 iDownloadSize -= P.InstVerIter(*this)->Size;
468 return;
469 }
470
471 // Removing
472 if (Pkg->CurrentVer != 0 && P.InstallVer == 0)
473 {
474 if (Inverse == false)
475 iUsrSize -= Pkg.CurrentVer()->InstalledSize;
476 else
477 iUsrSize += Pkg.CurrentVer()->InstalledSize;
d38b7b3d
AL
478 return;
479 }
6c139d6e
AL
480}
481 /*}}}*/
482// DepCache::AddStates - Add the package to the state counter /*{{{*/
483// ---------------------------------------------------------------------
484/* This routine is tricky to use, you must make sure that it is never
485 called twice for the same package. This means the Remove/Add section
486 should be as short as possible and not encompass any code that will
487 calld Remove/Add itself. Remember, dependencies can be circular so
488 while processing a dep for Pkg it is possible that Add/Remove
489 will be called on Pkg */
6935cd05 490void pkgDepCache::AddStates(const PkgIterator &Pkg, bool const Invert)
6c139d6e 491{
6935cd05 492 signed char const Add = (Invert == false) ? 1 : -1;
6c139d6e 493 StateCache &State = PkgState[Pkg->ID];
fd23676e 494
4ef9a929 495 // The Package is broken (either minimal dep or policy dep)
6c139d6e
AL
496 if ((State.DepState & DepInstMin) != DepInstMin)
497 iBrokenCount += Add;
4ef9a929
MV
498 if ((State.DepState & DepInstPolicy) != DepInstPolicy)
499 iPolicyBrokenCount += Add;
fd23676e 500
6c139d6e
AL
501 // Bad state
502 if (Pkg.State() != PkgIterator::NeedsNothing)
503 iBadCount += Add;
fd23676e 504
6c139d6e
AL
505 // Not installed
506 if (Pkg->CurrentVer == 0)
507 {
949e033c
DK
508 if (State.Mode == ModeDelete &&
509 (State.iFlags & Purge) == Purge && Pkg.Purge() == false)
d556d1a1 510 iDelCount += Add;
fd23676e 511
6c139d6e
AL
512 if (State.Mode == ModeInstall)
513 iInstCount += Add;
514 return;
515 }
fd23676e 516
6c139d6e 517 // Installed, no upgrade
6321777b 518 if (State.Status == 0)
fd23676e 519 {
6c139d6e
AL
520 if (State.Mode == ModeDelete)
521 iDelCount += Add;
d0c59649
AL
522 else
523 if ((State.iFlags & ReInstall) == ReInstall)
524 iInstCount += Add;
6c139d6e
AL
525 return;
526 }
fd23676e 527
6c139d6e
AL
528 // Alll 3 are possible
529 if (State.Mode == ModeDelete)
fd23676e
DK
530 iDelCount += Add;
531 else if (State.Mode == ModeKeep)
6c139d6e 532 iKeepCount += Add;
fd23676e 533 else if (State.Mode == ModeInstall)
6c139d6e
AL
534 iInstCount += Add;
535}
536 /*}}}*/
537// DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
538// ---------------------------------------------------------------------
539/* The or group results are stored in the last item of the or group. This
540 allows easy detection of the state of a whole or'd group. */
541void pkgDepCache::BuildGroupOrs(VerIterator const &V)
542{
543 unsigned char Group = 0;
f7f0d6c7 544 for (DepIterator D = V.DependsList(); D.end() != true; ++D)
6c139d6e
AL
545 {
546 // Build the dependency state.
547 unsigned char &State = DepState[D->ID];
548
549 /* Invert for Conflicts. We have to do this twice to get the
550 right sense for a conflicts group */
359e46db 551 if (D.IsNegative() == true)
6c139d6e 552 State = ~State;
fd23676e 553
6c139d6e 554 // Add to the group if we are within an or..
d2685fd6 555 State &= 0x7;
6c139d6e
AL
556 Group |= State;
557 State |= Group << 3;
558 if ((D->CompareOp & Dep::Or) != Dep::Or)
559 Group = 0;
fd23676e 560
6c139d6e 561 // Invert for Conflicts
359e46db 562 if (D.IsNegative() == true)
6c139d6e 563 State = ~State;
fd23676e 564 }
6c139d6e
AL
565}
566 /*}}}*/
567// DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
568// ---------------------------------------------------------------------
569/* This is used to run over a dependency list and determine the dep
570 state of the list, filtering it through both a Min check and a Policy
571 check. The return result will have SetMin/SetPolicy low if a check
572 fails. It uses the DepState cache for it's computations. */
fd23676e
DK
573unsigned char pkgDepCache::VersionState(DepIterator D, unsigned char const Check,
574 unsigned char const SetMin,
575 unsigned char const SetPolicy) const
6c139d6e
AL
576{
577 unsigned char Dep = 0xFF;
6c139d6e
AL
578 while (D.end() != true)
579 {
fd23676e
DK
580 // the last or-dependency has the state of all previous or'ed
581 DepIterator Start, End;
582 D.GlobOr(Start, End);
583 // ignore if we are called with Dep{Install,…} or DepG{Install,…}
584 // the later would be more correct, but the first is what we get
585 unsigned char const State = DepState[End->ID] | (DepState[End->ID] >> 3);
586
6c139d6e
AL
587 // Minimum deps that must be satisfied to have a working package
588 if (Start.IsCritical() == true)
fd23676e 589 {
6c139d6e 590 if ((State & Check) != Check)
fd23676e
DK
591 return Dep &= ~(SetMin | SetPolicy);
592 }
6c139d6e 593 // Policy deps that must be satisfied to install the package
fd23676e 594 else if (IsImportantDep(Start) == true &&
6c139d6e
AL
595 (State & Check) != Check)
596 Dep &= ~SetPolicy;
597 }
6c139d6e
AL
598 return Dep;
599}
600 /*}}}*/
601// DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
602// ---------------------------------------------------------------------
603/* This is the main dependency computation bit. It computes the 3 main
604 results for a dependencys, Now, Install and Candidate. Callers must
605 invert the result if dealing with conflicts. */
fd23676e 606unsigned char pkgDepCache::DependencyState(DepIterator const &D)
6c139d6e
AL
607{
608 unsigned char State = 0;
fd23676e 609
6c139d6e
AL
610 if (CheckDep(D,NowVersion) == true)
611 State |= DepNow;
612 if (CheckDep(D,InstallVersion) == true)
613 State |= DepInstall;
614 if (CheckDep(D,CandidateVersion) == true)
615 State |= DepCVer;
fd23676e 616
6c139d6e
AL
617 return State;
618}
619 /*}}}*/
620// DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
621// ---------------------------------------------------------------------
622/* This determines the combined dependency representation of a package
623 for its two states now and install. This is done by using the pre-generated
624 dependency information. */
fd23676e 625void pkgDepCache::UpdateVerState(PkgIterator const &Pkg)
6c139d6e
AL
626{
627 // Empty deps are always true
628 StateCache &State = PkgState[Pkg->ID];
629 State.DepState = 0xFF;
630
631 // Check the Current state
632 if (Pkg->CurrentVer != 0)
633 {
634 DepIterator D = Pkg.CurrentVer().DependsList();
635 State.DepState &= VersionState(D,DepNow,DepNowMin,DepNowPolicy);
636 }
637
638 /* Check the candidate state. We do not compare against the whole as
639 a candidate state but check the candidate version against the
640 install states */
641 if (State.CandidateVer != 0)
642 {
643 DepIterator D = State.CandidateVerIter(*this).DependsList();
644 State.DepState &= VersionState(D,DepInstall,DepCandMin,DepCandPolicy);
645 }
646
647 // Check target state which can only be current or installed
648 if (State.InstallVer != 0)
649 {
650 DepIterator D = State.InstVerIter(*this).DependsList();
651 State.DepState &= VersionState(D,DepInstall,DepInstMin,DepInstPolicy);
652 }
653}
654 /*}}}*/
655// DepCache::Update - Figure out all the state information /*{{{*/
656// ---------------------------------------------------------------------
657/* This will figure out the state of all the packages and all the
658 dependencies based on the current policy. */
fd23676e 659void pkgDepCache::Update(OpProgress * const Prog)
6c139d6e
AL
660{
661 iUsrSize = 0;
662 iDownloadSize = 0;
6c139d6e 663 iInstCount = 0;
fb4c7643 664 iDelCount = 0;
6c139d6e
AL
665 iKeepCount = 0;
666 iBrokenCount = 0;
fb4c7643 667 iPolicyBrokenCount = 0;
6c139d6e 668 iBadCount = 0;
8b32e920 669
6c139d6e 670 // Perform the depends pass
a246f2dc 671 int Done = 0;
f7f0d6c7 672 for (PkgIterator I = PkgBegin(); I.end() != true; ++I, ++Done)
6c139d6e 673 {
2edcefd5 674 if (Prog != 0 && Done%20 == 0)
a246f2dc 675 Prog->Progress(Done);
f7f0d6c7 676 for (VerIterator V = I.VersionList(); V.end() != true; ++V)
6c139d6e
AL
677 {
678 unsigned char Group = 0;
8b32e920 679
f7f0d6c7 680 for (DepIterator D = V.DependsList(); D.end() != true; ++D)
6c139d6e
AL
681 {
682 // Build the dependency state.
683 unsigned char &State = DepState[D->ID];
b2e465d6 684 State = DependencyState(D);
6c139d6e
AL
685
686 // Add to the group if we are within an or..
687 Group |= State;
688 State |= Group << 3;
689 if ((D->CompareOp & Dep::Or) != Dep::Or)
690 Group = 0;
691
692 // Invert for Conflicts
359e46db 693 if (D.IsNegative() == true)
6c139d6e 694 State = ~State;
8b32e920 695 }
6c139d6e
AL
696 }
697
8b32e920 698 // Compute the package dependency state and size additions
6c139d6e
AL
699 AddSizes(I);
700 UpdateVerState(I);
701 AddStates(I);
702 }
a246f2dc 703
8b32e920 704 if (Prog != 0)
a246f2dc 705 Prog->Progress(Done);
74a05226
MV
706
707 readStateFile(Prog);
6c139d6e
AL
708}
709 /*}}}*/
710// DepCache::Update - Update the deps list of a package /*{{{*/
711// ---------------------------------------------------------------------
712/* This is a helper for update that only does the dep portion of the scan.
74a05226 713 It is mainly meant to scan reverse dependencies. */
6c139d6e
AL
714void pkgDepCache::Update(DepIterator D)
715{
716 // Update the reverse deps
f7f0d6c7 717 for (;D.end() != true; ++D)
6c139d6e
AL
718 {
719 unsigned char &State = DepState[D->ID];
720 State = DependencyState(D);
721
722 // Invert for Conflicts
359e46db 723 if (D.IsNegative() == true)
6c139d6e 724 State = ~State;
b2e465d6 725
6c139d6e
AL
726 RemoveStates(D.ParentPkg());
727 BuildGroupOrs(D.ParentVer());
728 UpdateVerState(D.ParentPkg());
729 AddStates(D.ParentPkg());
730 }
731}
732 /*}}}*/
733// DepCache::Update - Update the related deps of a package /*{{{*/
734// ---------------------------------------------------------------------
735/* This is called whenever the state of a package changes. It updates
736 all cached dependencies related to this package. */
737void pkgDepCache::Update(PkgIterator const &Pkg)
b2e465d6 738{
6c139d6e
AL
739 // Recompute the dep of the package
740 RemoveStates(Pkg);
741 UpdateVerState(Pkg);
742 AddStates(Pkg);
743
744 // Update the reverse deps
745 Update(Pkg.RevDependsList());
746
747 // Update the provides map for the current ver
748 if (Pkg->CurrentVer != 0)
749 for (PrvIterator P = Pkg.CurrentVer().ProvidesList();
f7f0d6c7 750 P.end() != true; ++P)
6c139d6e
AL
751 Update(P.ParentPkg().RevDependsList());
752
753 // Update the provides map for the candidate ver
9972233d
AL
754 if (PkgState[Pkg->ID].CandidateVer != 0)
755 for (PrvIterator P = PkgState[Pkg->ID].CandidateVerIter(*this).ProvidesList();
f7f0d6c7 756 P.end() != true; ++P)
9972233d 757 Update(P.ParentPkg().RevDependsList());
6c139d6e 758}
6c139d6e 759 /*}}}*/
6c139d6e
AL
760// DepCache::MarkKeep - Put the package in the keep state /*{{{*/
761// ---------------------------------------------------------------------
762/* */
3d619a20 763bool pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
af29ffb4 764 unsigned long Depth)
6c139d6e 765{
dde0c674 766 if (IsModeChangeOk(ModeKeep, Pkg, Depth, FromUser) == false)
3d619a20 767 return false;
813c8eea
AL
768
769 /* Reject an attempt to keep a non-source broken installed package, those
770 must be upgraded */
771 if (Pkg.State() == PkgIterator::NeedsUnpack &&
772 Pkg.CurrentVer().Downloadable() == false)
3d619a20 773 return false;
74a05226 774
6c139d6e
AL
775 /* We changed the soft state all the time so the UI is a bit nicer
776 to use */
777 StateCache &P = PkgState[Pkg->ID];
dde0c674
DK
778
779 // Check that it is not already kept
780 if (P.Mode == ModeKeep)
3d619a20 781 return true;
dde0c674 782
6c139d6e
AL
783 if (Soft == true)
784 P.iFlags |= AutoKept;
785 else
786 P.iFlags &= ~AutoKept;
6c139d6e 787
dde0c674
DK
788 ActionGroup group(*this);
789
32085498
MV
790#if 0 // reseting the autoflag here means we lose the
791 // auto-mark information if a user selects a package for removal
792 // but changes his mind then and sets it for keep again
793 // - this makes sense as default when all Garbage dependencies
794 // are automatically marked for removal (as aptitude does).
795 // setting a package for keep then makes it no longer autoinstalled
1e3f4083 796 // for all other use-case this action is rather surprising
74a05226
MV
797 if(FromUser && !P.Marked)
798 P.Flags &= ~Flag::Auto;
32085498
MV
799#endif
800
af29ffb4 801 if (DebugMarker == true)
84573326 802 std::clog << OutputInDepth(Depth) << "MarkKeep " << APT::PrettyPkg(this, Pkg) << " FU=" << FromUser << std::endl;
af29ffb4 803
6c139d6e
AL
804 RemoveSizes(Pkg);
805 RemoveStates(Pkg);
806
807 P.Mode = ModeKeep;
808 if (Pkg->CurrentVer == 0)
809 P.InstallVer = 0;
810 else
811 P.InstallVer = Pkg.CurrentVer();
812
813 AddStates(Pkg);
6c139d6e 814 Update(Pkg);
6c139d6e 815 AddSizes(Pkg);
3d619a20
DK
816
817 return true;
6c139d6e
AL
818}
819 /*}}}*/
820// DepCache::MarkDelete - Put the package in the delete state /*{{{*/
821// ---------------------------------------------------------------------
822/* */
3d619a20 823bool pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
6910a2ac 824 unsigned long Depth, bool FromUser)
6c139d6e 825{
dde0c674 826 if (IsModeChangeOk(ModeDelete, Pkg, Depth, FromUser) == false)
3d619a20 827 return false;
6c139d6e 828
dde0c674 829 StateCache &P = PkgState[Pkg->ID];
74a05226 830
6c139d6e 831 // Check that it is not already marked for delete
d556d1a1
AL
832 if ((P.Mode == ModeDelete || P.InstallVer == 0) &&
833 (Pkg.Purge() == true || rPurge == false))
3d619a20 834 return true;
6c139d6e 835
dde0c674 836 // check if we are allowed to remove the package
6910a2ac 837 if (IsDeleteOk(Pkg,rPurge,Depth,FromUser) == false)
3d619a20 838 return false;
6910a2ac 839
dde0c674
DK
840 P.iFlags &= ~(AutoKept | Purge);
841 if (rPurge == true)
842 P.iFlags |= Purge;
843
844 ActionGroup group(*this);
845
7c2cc4a7
DK
846 if (FromUser == false)
847 {
848 VerIterator const PV = P.InstVerIter(*this);
849 if (PV.end() == false)
850 {
851 // removed metapackages mark their dependencies as manual to prevent in "desktop depends browser, texteditor"
852 // the removal of browser to suggest the removal of desktop and texteditor.
853 // We ignore the auto-bit here as we can't deal with metapackage cascardes otherwise.
854 // We do not check for or-groups here as we don't know which package takes care of
855 // providing the feature the user likes e.g.: browser1 | browser2 | browser3
856 // Temporary removals are effected by this as well, which is bad, but unlikely in practice
857 bool const PinNeverMarkAutoSection = (PV->Section != 0 && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", PV.Section()));
858 if (PinNeverMarkAutoSection)
859 {
860 for (DepIterator D = PV.DependsList(); D.end() != true; ++D)
861 {
862 if (D.IsMultiArchImplicit() == true || D.IsNegative() == true || IsImportantDep(D) == false)
863 continue;
864
865 pkgCacheFile CacheFile(this);
866 APT::VersionList verlist = APT::VersionList::FromDependency(CacheFile, D, APT::CacheSetHelper::INSTALLED);
867 for (auto const &V : verlist)
868 {
869 PkgIterator const DP = V.ParentPkg();
870 if(DebugAutoInstall == true)
871 std::clog << OutputInDepth(Depth) << "Setting " << DP.FullName(false) << " NOT as auto-installed (direct "
872 << D.DepType() << " of " << Pkg.FullName(false) << " which is in APT::Never-MarkAuto-Sections)" << std::endl;
873
874 MarkAuto(DP, false);
875 }
876 }
877 }
878 }
879 }
880
af29ffb4 881 if (DebugMarker == true)
84573326 882 std::clog << OutputInDepth(Depth) << (rPurge ? "MarkPurge " : "MarkDelete ") << APT::PrettyPkg(this, Pkg) << " FU=" << FromUser << std::endl;
af29ffb4 883
6c139d6e
AL
884 RemoveSizes(Pkg);
885 RemoveStates(Pkg);
886
d556d1a1 887 if (Pkg->CurrentVer == 0 && (Pkg.Purge() == true || rPurge == false))
3d615484
AL
888 P.Mode = ModeKeep;
889 else
890 P.Mode = ModeDelete;
6c139d6e 891 P.InstallVer = 0;
6c139d6e
AL
892
893 AddStates(Pkg);
894 Update(Pkg);
895 AddSizes(Pkg);
803ea2a8 896
3d619a20 897 return true;
6c139d6e
AL
898}
899 /*}}}*/
6910a2ac
DK
900// DepCache::IsDeleteOk - check if it is ok to remove this package /*{{{*/
901// ---------------------------------------------------------------------
dde0c674
DK
902/* The default implementation tries to prevent deletion of install requests.
903 dpkg holds are enforced by the private IsModeChangeOk */
6910a2ac
DK
904bool pkgDepCache::IsDeleteOk(PkgIterator const &Pkg,bool rPurge,
905 unsigned long Depth, bool FromUser)
486d190d
DK
906{
907 return IsDeleteOkProtectInstallRequests(Pkg, rPurge, Depth, FromUser);
908}
909bool pkgDepCache::IsDeleteOkProtectInstallRequests(PkgIterator const &Pkg,
65512241 910 bool const /*rPurge*/, unsigned long const Depth, bool const FromUser)
6910a2ac 911{
dde0c674 912 if (FromUser == false && Pkg->CurrentVer == 0)
0c6aa02e
DK
913 {
914 StateCache &P = PkgState[Pkg->ID];
915 if (P.InstallVer != 0 && P.Status == 2 && (P.Flags & Flag::Auto) != Flag::Auto)
916 {
917 if (DebugMarker == true)
84573326 918 std::clog << OutputInDepth(Depth) << "Manual install request prevents MarkDelete of " << APT::PrettyPkg(this, Pkg) << std::endl;
0c6aa02e
DK
919 return false;
920 }
921 }
dde0c674
DK
922 return true;
923}
924 /*}}}*/
925// DepCache::IsModeChangeOk - check if it is ok to change the mode /*{{{*/
926// ---------------------------------------------------------------------
927/* this is used by all Mark methods on the very first line to check sanity
928 and prevents mode changes for packages on hold for example.
929 If you want to check Mode specific stuff you can use the virtual public
930 Is<Mode>Ok methods instead */
c3ccac92 931static char const* PrintMode(char const mode)
dde0c674
DK
932{
933 switch (mode)
934 {
935 case pkgDepCache::ModeInstall: return "Install";
936 case pkgDepCache::ModeKeep: return "Keep";
937 case pkgDepCache::ModeDelete: return "Delete";
8fa042ca 938 case pkgDepCache::ModeGarbage: return "Garbage";
dde0c674
DK
939 default: return "UNKNOWN";
940 }
941}
942bool pkgDepCache::IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
943 unsigned long const Depth, bool const FromUser)
944{
945 // we are not trying to hard…
946 if (unlikely(Depth > 100))
947 return false;
948
949 // general sanity
950 if (unlikely(Pkg.end() == true || Pkg->VersionList == 0))
951 return false;
952
cc26da01
DK
953 // the user is always right
954 if (FromUser == true)
955 return true;
956
957 StateCache &P = PkgState[Pkg->ID];
35f6b9ea
DK
958 // not changing the mode is obviously also fine as we might want to call
959 // e.g. MarkInstall multiple times with different arguments for the same package
960 if (P.Mode == mode)
961 return true;
cc26da01
DK
962
963 // if previous state was set by user only user can reset it
964 if ((P.iFlags & Protected) == Protected)
965 {
35f6b9ea 966 if (unlikely(DebugMarker == true))
cc26da01 967 std::clog << OutputInDepth(Depth) << "Ignore Mark" << PrintMode(mode)
84573326 968 << " of " << APT::PrettyPkg(this, Pkg) << " as its mode (" << PrintMode(P.Mode)
cc26da01
DK
969 << ") is protected" << std::endl;
970 return false;
971 }
dde0c674 972 // enforce dpkg holds
cc26da01 973 else if (mode != ModeKeep && Pkg->SelectedState == pkgCache::State::Hold &&
dde0c674
DK
974 _config->FindB("APT::Ignore-Hold",false) == false)
975 {
35f6b9ea 976 if (unlikely(DebugMarker == true))
dde0c674 977 std::clog << OutputInDepth(Depth) << "Hold prevents Mark" << PrintMode(mode)
84573326 978 << " of " << APT::PrettyPkg(this, Pkg) << std::endl;
dde0c674
DK
979 return false;
980 }
981
6910a2ac
DK
982 return true;
983}
984 /*}}}*/
6c139d6e
AL
985// DepCache::MarkInstall - Put the package in the install state /*{{{*/
986// ---------------------------------------------------------------------
987/* */
2b5c35c7
DK
988struct CompareProviders {
989 pkgCache::PkgIterator const Pkg;
e8afd168 990 explicit CompareProviders(pkgCache::DepIterator const &Dep) : Pkg(Dep.TargetPkg()) {};
2b5c35c7
DK
991 //bool operator() (APT::VersionList::iterator const &AV, APT::VersionList::iterator const &BV)
992 bool operator() (pkgCache::VerIterator const &AV, pkgCache::VerIterator const &BV)
993 {
994 pkgCache::PkgIterator const A = AV.ParentPkg();
995 pkgCache::PkgIterator const B = BV.ParentPkg();
9bfd7b57
DK
996 // Prefer MA:same packages if other architectures for it are installed
997 if ((AV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same ||
998 (BV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
999 {
1000 bool instA = false;
1001 if ((AV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
1002 {
1003 pkgCache::GrpIterator Grp = A.Group();
1004 for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
1005 if (P->CurrentVer != 0)
1006 {
1007 instA = true;
1008 break;
1009 }
1010 }
1011 bool instB = false;
1012 if ((BV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
1013 {
1014 pkgCache::GrpIterator Grp = B.Group();
1015 for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
1016 {
1017 if (P->CurrentVer != 0)
1018 {
1019 instB = true;
1020 break;
1021 }
1022 }
1023 }
1024 if (instA != instB)
1025 return instA == false;
1026 }
529bf9b0
DK
1027 if ((A->CurrentVer == 0 || B->CurrentVer == 0) && A->CurrentVer != B->CurrentVer)
1028 return A->CurrentVer == 0;
2b5c35c7
DK
1029 // Prefer packages in the same group as the target; e.g. foo:i386, foo:amd64
1030 if (A->Group != B->Group)
1031 {
1032 if (A->Group == Pkg->Group && B->Group != Pkg->Group)
1033 return false;
1034 else if (B->Group == Pkg->Group && A->Group != Pkg->Group)
1035 return true;
1036 }
1037 // we like essentials
1038 if ((A->Flags & pkgCache::Flag::Essential) != (B->Flags & pkgCache::Flag::Essential))
1039 {
1040 if ((A->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
1041 return false;
1042 else if ((B->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
1043 return true;
1044 }
c5200869
JAK
1045 if ((A->Flags & pkgCache::Flag::Important) != (B->Flags & pkgCache::Flag::Important))
1046 {
1047 if ((A->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
1048 return false;
1049 else if ((B->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
1050 return true;
1051 }
2b5c35c7
DK
1052 // prefer native architecture
1053 if (strcmp(A.Arch(), B.Arch()) != 0)
1054 {
1055 if (strcmp(A.Arch(), A.Cache()->NativeArch()) == 0)
1056 return false;
1057 else if (strcmp(B.Arch(), B.Cache()->NativeArch()) == 0)
1058 return true;
1059 std::vector<std::string> archs = APT::Configuration::getArchitectures();
1060 for (std::vector<std::string>::const_iterator a = archs.begin(); a != archs.end(); ++a)
1061 if (*a == A.Arch())
1062 return false;
1063 else if (*a == B.Arch())
1064 return true;
1065 }
096bd9f5
CW
1066 // higher priority seems like a good idea
1067 if (AV->Priority != BV->Priority)
1068 return AV->Priority > BV->Priority;
2b5c35c7
DK
1069 // unable to decide…
1070 return A->ID < B->ID;
1071 }
1072};
3d619a20 1073bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
7610bb3d
MV
1074 unsigned long Depth, bool FromUser,
1075 bool ForceImportantDeps)
b2e465d6 1076{
dde0c674 1077 if (IsModeChangeOk(ModeInstall, Pkg, Depth, FromUser) == false)
3d619a20 1078 return false;
dde0c674
DK
1079
1080 StateCache &P = PkgState[Pkg->ID];
1081
1082 // See if there is even any possible instalation candidate
1083 if (P.CandidateVer == 0)
3d619a20 1084 return false;
74a05226 1085
6c139d6e
AL
1086 /* Check that it is not already marked for install and that it can be
1087 installed */
60681f93
MV
1088 if ((P.InstPolicyBroken() == false && P.InstBroken() == false) &&
1089 (P.Mode == ModeInstall ||
6c139d6e
AL
1090 P.CandidateVer == (Version *)Pkg.CurrentVer()))
1091 {
1092 if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
3d619a20
DK
1093 return MarkKeep(Pkg, false, FromUser, Depth+1);
1094 return true;
6c139d6e 1095 }
b2e465d6 1096
be7ce6f1
DK
1097 // check if we are allowed to install the package
1098 if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false)
1099 return false;
6910a2ac 1100
dde0c674
DK
1101 ActionGroup group(*this);
1102 P.iFlags &= ~AutoKept;
1103
6c139d6e
AL
1104 /* Target the candidate version and remove the autoflag. We reset the
1105 autoflag below if this was called recursively. Otherwise the user
1106 should have the ability to de-auto a package by changing its state */
1107 RemoveSizes(Pkg);
1108 RemoveStates(Pkg);
1109
1110 P.Mode = ModeInstall;
1111 P.InstallVer = P.CandidateVer;
74a05226
MV
1112
1113 if(FromUser)
1114 {
e26a777c
DK
1115 // Set it to manual if it's a new install or already installed,
1116 // but only if its not marked by the autoremover (aptitude depend on this behavior)
1117 // or if we do automatic installation (aptitude never does it)
1118 if(P.Status == 2 || (Pkg->CurrentVer != 0 && (AutoInst == true || P.Marked == false)))
74a05226
MV
1119 P.Flags &= ~Flag::Auto;
1120 }
1121 else
1122 {
1123 // Set it to auto if this is a new install.
1124 if(P.Status == 2)
1125 P.Flags |= Flag::Auto;
1126 }
6c139d6e
AL
1127 if (P.CandidateVer == (Version *)Pkg.CurrentVer())
1128 P.Mode = ModeKeep;
1129
1130 AddStates(Pkg);
1131 Update(Pkg);
1132 AddSizes(Pkg);
6910a2ac 1133
98278a81 1134 if (AutoInst == false || _config->Find("APT::Solver", "internal") != "internal")
3d619a20 1135 return true;
6c139d6e 1136
af29ffb4 1137 if (DebugMarker == true)
84573326 1138 std::clog << OutputInDepth(Depth) << "MarkInstall " << APT::PrettyPkg(this, Pkg) << " FU=" << FromUser << std::endl;
af29ffb4 1139
5f4495e3 1140 bool MoveAutoBitToDependencies = false;
3cbeed98
DK
1141 VerIterator const PV = P.InstVerIter(*this);
1142 if (unlikely(PV.end() == true))
1143 return false;
5f4495e3
DK
1144 else if (PV->Section != 0 && (P.Flags & Flag::Auto) != Flag::Auto)
1145 {
1146 VerIterator const CurVer = Pkg.CurrentVer();
1147 if (CurVer.end() == false && CurVer->Section != 0 && strcmp(CurVer.Section(), PV.Section()) != 0)
1148 {
1149 bool const CurVerInMoveSection = ConfigValueInSubTree("APT::Move-Autobit-Sections", CurVer.Section());
1150 bool const InstVerInMoveSection = ConfigValueInSubTree("APT::Move-Autobit-Sections", PV.Section());
1151 MoveAutoBitToDependencies = (CurVerInMoveSection == false && InstVerInMoveSection == true);
1152 if (MoveAutoBitToDependencies == true)
1153 {
1154 if(DebugAutoInstall == true)
1155 std::clog << OutputInDepth(Depth) << "Setting " << Pkg.FullName(false) << " as auto-installed, moving manual to its dependencies" << std::endl;
1156 MarkAuto(Pkg, true);
1157 }
1158 }
1159 }
3cbeed98
DK
1160
1161 DepIterator Dep = PV.DependsList();
6c139d6e
AL
1162 for (; Dep.end() != true;)
1163 {
1164 // Grok or groups
1165 DepIterator Start = Dep;
1166 bool Result = true;
b2e465d6 1167 unsigned Ors = 0;
f7f0d6c7 1168 for (bool LastOR = true; Dep.end() == false && LastOR == true; ++Dep, ++Ors)
6c139d6e
AL
1169 {
1170 LastOR = (Dep->CompareOp & Dep::Or) == Dep::Or;
1171
1172 if ((DepState[Dep->ID] & DepInstall) == DepInstall)
1173 Result = false;
1174 }
1175
1176 // Dep is satisfied okay.
1177 if (Result == false)
1178 continue;
1179
1180 /* Check if this dep should be consider for install. If it is a user
21b3eac8 1181 defined important dep and we are installed a new package then
4ef9a929 1182 it will be installed. Otherwise we only check for important
21b3eac8 1183 deps that have changed from the installed version */
6c139d6e
AL
1184 if (IsImportantDep(Start) == false)
1185 continue;
e92f6a18 1186
21b3eac8
DK
1187 /* If we are in an or group locate the first or that can
1188 succeed. We have already cached this… */
e92f6a18
DK
1189 for (; Ors > 1 && (DepState[Start->ID] & DepCVer) != DepCVer; --Ors)
1190 ++Start;
21b3eac8
DK
1191
1192 /* unsatisfiable dependency: IsInstallOkDependenciesSatisfiableByCandidates
1193 would have prevented us to get here if not overridden, so just skip
add81166 1194 over the problem here as the front-end will know what it is doing */
e92f6a18 1195 if (Ors == 1 && (DepState[Start->ID] &DepCVer) != DepCVer && Start.IsNegative() == false)
21b3eac8 1196 continue;
e92f6a18 1197
0526822a
DB
1198 /* Check if any ImportantDep() (but not Critical) were added
1199 * since we installed the package. Also check for deps that
1200 * were satisfied in the past: for instance, if a version
1201 * restriction in a Recommends was tightened, upgrading the
1202 * package should follow that Recommends rather than causing the
1203 * dependency to be removed. (bug #470115)
1b1c2224 1204 */
6ed08516 1205 if (Pkg->CurrentVer != 0 && ForceImportantDeps == false && Start.IsCritical() == false)
1b1c2224 1206 {
6ed08516
DK
1207 bool isNewImportantDep = true;
1208 bool isPreviouslySatisfiedImportantDep = false;
1209 for (DepIterator D = Pkg.CurrentVer().DependsList(); D.end() != true; ++D)
1d722933 1210 {
6ed08516
DK
1211 //FIXME: Should we handle or-group better here?
1212 // We do not check if the package we look for is part of the same or-group
1213 // we might find while searching, but could that really be a problem?
1214 if (D.IsCritical() == true || IsImportantDep(D) == false ||
1215 Start.TargetPkg() != D.TargetPkg())
1216 continue;
1217
1218 isNewImportantDep = false;
1219
1220 while ((D->CompareOp & Dep::Or) != 0)
1221 ++D;
1222
1223 isPreviouslySatisfiedImportantDep = (((*this)[D] & DepGNow) != 0);
1224 if (isPreviouslySatisfiedImportantDep == true)
1225 break;
1226 }
1227
1228 if(isNewImportantDep == true)
1229 {
1230 if (DebugAutoInstall == true)
1231 std::clog << OutputInDepth(Depth) << "new important dependency: "
1232 << Start.TargetPkg().FullName() << std::endl;
1233 }
1234 else if(isPreviouslySatisfiedImportantDep == true)
1235 {
1236 if (DebugAutoInstall == true)
1237 std::clog << OutputInDepth(Depth) << "previously satisfied important dependency on "
1238 << Start.TargetPkg().FullName() << std::endl;
1239 }
1240 else
1241 {
1242 if (DebugAutoInstall == true)
1243 std::clog << OutputInDepth(Depth) << "ignore old unsatisfied important dependency on "
1244 << Start.TargetPkg().FullName() << std::endl;
1245 continue;
1d722933 1246 }
1b1c2224 1247 }
6ed08516 1248
1e3f4083 1249 /* This bit is for processing the possibility of an install/upgrade
074da097
DK
1250 fixing the problem for "positive" dependencies */
1251 if (Start.IsNegative() == false && (DepState[Start->ID] & DepCVer) == DepCVer)
6c139d6e 1252 {
9112f777
DK
1253 pkgCacheFile CacheFile(this);
1254 APT::VersionList verlist = APT::VersionList::FromDependency(CacheFile, Start, APT::CacheSetHelper::CANDIDATE);
2b5c35c7 1255 CompareProviders comp(Start);
b2e465d6 1256
66706285
DK
1257 do {
1258 APT::VersionList::iterator InstVer = std::max_element(verlist.begin(), verlist.end(), comp);
1259
1260 if (InstVer == verlist.end())
1261 break;
1262
2b5c35c7 1263 pkgCache::PkgIterator InstPkg = InstVer.ParentPkg();
af29ffb4
MV
1264 if(DebugAutoInstall == true)
1265 std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.Name()
1266 << " as " << Start.DepType() << " of " << Pkg.Name()
d4c5f11f 1267 << std::endl;
66706285
DK
1268 if (MarkInstall(InstPkg, true, Depth + 1, false, ForceImportantDeps) == false)
1269 {
1270 verlist.erase(InstVer);
1271 continue;
1272 }
5f4495e3
DK
1273
1274 // now check if we should consider it a automatic dependency or not
1275 if(InstPkg->CurrentVer == 0 && MoveAutoBitToDependencies)
1276 {
1277 if(DebugAutoInstall == true)
1278 std::clog << OutputInDepth(Depth) << "Setting " << InstPkg.FullName(false) << " NOT as auto-installed (direct "
1279 << Start.DepType() << " of " << Pkg.FullName(false) << " which is manual and in APT::Move-Autobit-Sections)" << std::endl;
1280 MarkAuto(InstPkg, false);
1281 }
1282
1283
66706285
DK
1284 break;
1285 } while(true);
6c139d6e
AL
1286 continue;
1287 }
074da097
DK
1288 /* Negative dependencies have no or-group
1289 If the dependency isn't versioned, we try if an upgrade might solve the problem.
1290 Otherwise we remove the offender if needed */
1291 else if (Start.IsNegative() == true && Start->Type != pkgCache::Dep::Obsoletes)
6c139d6e 1292 {
98cc7fd2 1293 std::unique_ptr<Version *[]> List(Start.AllTargets());
074da097 1294 pkgCache::PkgIterator TrgPkg = Start.TargetPkg();
98cc7fd2 1295 for (Version **I = List.get(); *I != 0; I++)
6c139d6e
AL
1296 {
1297 VerIterator Ver(*this,*I);
1298 PkgIterator Pkg = Ver.ParentPkg();
308c7d30 1299
edbda33b
DK
1300 /* The List includes all packages providing this dependency,
1301 even providers which are not installed, so skip them. */
1302 if (PkgState[Pkg->ID].InstallVer == 0)
1303 continue;
1304
0dfc7eef
MV
1305 /* Ignore negative dependencies that we are not going to
1306 get installed */
1307 if (PkgState[Pkg->ID].InstallVer != *I)
1308 continue;
1309
074da097
DK
1310 if ((Start->Version != 0 || TrgPkg != Pkg) &&
1311 PkgState[Pkg->ID].CandidateVer != PkgState[Pkg->ID].InstallVer &&
1312 PkgState[Pkg->ID].CandidateVer != *I &&
a16dec4d
DK
1313 MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps) == true)
1314 continue;
06f88117
MV
1315 else if (Start->Type == pkgCache::Dep::Conflicts ||
1316 Start->Type == pkgCache::Dep::DpkgBreaks)
1317 {
1318 if(DebugAutoInstall == true)
1319 std::clog << OutputInDepth(Depth)
1320 << " Removing: " << Pkg.Name()
1321 << std::endl;
1322 if (MarkDelete(Pkg,false,Depth + 1, false) == false)
1323 break;
1324 }
6c139d6e 1325 }
6c139d6e 1326 continue;
074da097 1327 }
6c139d6e 1328 }
3d619a20 1329
a16dec4d 1330 return Dep.end() == true;
6c139d6e 1331}
92fcbfc1 1332 /*}}}*/
6910a2ac 1333// DepCache::IsInstallOk - check if it is ok to install this package /*{{{*/
2d403b92 1334// ---------------------------------------------------------------------
486d190d
DK
1335/* The default implementation checks if the installation of an M-A:same
1336 package would lead us into a version-screw and if so forbids it.
dde0c674 1337 dpkg holds are enforced by the private IsModeChangeOk */
6910a2ac
DK
1338bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst,
1339 unsigned long Depth, bool FromUser)
2d403b92 1340{
21b3eac8
DK
1341 return IsInstallOkMultiArchSameVersionSynced(Pkg,AutoInst, Depth, FromUser) &&
1342 IsInstallOkDependenciesSatisfiableByCandidates(Pkg,AutoInst, Depth, FromUser);
486d190d
DK
1343}
1344bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg,
65512241 1345 bool const /*AutoInst*/, unsigned long const Depth, bool const FromUser)
486d190d
DK
1346{
1347 if (FromUser == true) // as always: user is always right
1348 return true;
1349
be7ce6f1
DK
1350 // if we have checked before and it was okay, it will still be okay
1351 if (PkgState[Pkg->ID].Mode == ModeInstall &&
1352 PkgState[Pkg->ID].InstallVer == PkgState[Pkg->ID].CandidateVer)
1353 return true;
1354
486d190d
DK
1355 // ignore packages with none-M-A:same candidates
1356 VerIterator const CandVer = PkgState[Pkg->ID].CandidateVerIter(*this);
1357 if (unlikely(CandVer.end() == true) || CandVer == Pkg.CurrentVer() ||
1358 (CandVer->MultiArch & pkgCache::Version::Same) != pkgCache::Version::Same)
1359 return true;
1360
1361 GrpIterator const Grp = Pkg.Group();
1362 for (PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
1363 {
98c9c26c
DK
1364 // not installed or self-check: fine by definition
1365 if (P->CurrentVer == 0 || P == Pkg)
1366 continue;
1367
1368 // not having a candidate or being in sync
486d190d 1369 // (simple string-compare as stuff like '1' == '0:1-0' can't happen here)
98c9c26c 1370 VerIterator CV = PkgState[P->ID].CandidateVerIter(*this);
91414dd7 1371 if (CV.end() == true || strcmp(CandVer.VerStr(), CV.VerStr()) == 0)
486d190d 1372 continue;
98c9c26c 1373
1e3f4083 1374 // packages losing M-A:same can be out-of-sync
98c9c26c 1375 if ((CV->MultiArch & pkgCache::Version::Same) != pkgCache::Version::Same)
486d190d
DK
1376 continue;
1377
1378 // not downloadable means the package is obsolete, so allow out-of-sync
1379 if (CV.Downloadable() == false)
1380 continue;
1381
1382 PkgState[Pkg->ID].iFlags |= AutoKept;
1383 if (unlikely(DebugMarker == true))
84573326
DK
1384 std::clog << OutputInDepth(Depth) << "Ignore MarkInstall of " << APT::PrettyPkg(this, Pkg)
1385 << " as it is not in sync with its M-A:same sibling " << APT::PrettyPkg(this, P)
91414dd7 1386 << " (" << CandVer.VerStr() << " != " << CV.VerStr() << ")" << std::endl;
486d190d
DK
1387 return false;
1388 }
1389
21b3eac8
DK
1390 return true;
1391}
1392bool pkgDepCache::IsInstallOkDependenciesSatisfiableByCandidates(PkgIterator const &Pkg,
1393 bool const AutoInst, unsigned long const Depth, bool const /*FromUser*/)
1394{
1395 if (AutoInst == false)
1396 return true;
1397
1398 VerIterator const CandVer = PkgState[Pkg->ID].CandidateVerIter(*this);
1399 if (unlikely(CandVer.end() == true) || CandVer == Pkg.CurrentVer())
1400 return true;
1401
1402 for (DepIterator Dep = CandVer.DependsList(); Dep.end() != true;)
1403 {
1404 // Grok or groups
1405 DepIterator Start = Dep;
1406 bool Result = true;
1407 unsigned Ors = 0;
1408 for (bool LastOR = true; Dep.end() == false && LastOR == true; ++Dep, ++Ors)
1409 {
1410 LastOR = (Dep->CompareOp & Dep::Or) == Dep::Or;
1411
1412 if ((DepState[Dep->ID] & DepInstall) == DepInstall)
1413 Result = false;
1414 }
1415
1416 if (Start.IsCritical() == false || Start.IsNegative() == true || Result == false)
1417 continue;
1418
1419 /* If we are in an or group locate the first or that can succeed.
1420 We have already cached this… */
1421 for (; Ors > 1 && (DepState[Start->ID] & DepCVer) != DepCVer; --Ors)
1422 ++Start;
1423
1424 if (Ors == 1 && (DepState[Start->ID] &DepCVer) != DepCVer)
1425 {
1426 if (DebugAutoInstall == true)
84573326 1427 std::clog << OutputInDepth(Depth) << APT::PrettyDep(this, Start) << " can't be satisfied!" << std::endl;
21b3eac8
DK
1428
1429 // the dependency is critical, but can't be installed, so discard the candidate
1430 // as the problemresolver will trip over it otherwise trying to install it (#735967)
e41d3d7e 1431 if (Pkg->CurrentVer != 0 && (PkgState[Pkg->ID].iFlags & Protected) != Protected)
0390edd5 1432 {
21b3eac8 1433 SetCandidateVersion(Pkg.CurrentVer());
0390edd5 1434 StateCache &State = PkgState[Pkg->ID];
6df56323
JAK
1435 if (State.Mode != ModeDelete)
1436 {
1437 State.Mode = ModeKeep;
1438 State.Update(Pkg, *this);
1439 }
0390edd5 1440 }
21b3eac8
DK
1441 return false;
1442 }
1443 }
1444
6910a2ac 1445 return true;
2d403b92
MV
1446}
1447 /*}}}*/
d0c59649
AL
1448// DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
1449// ---------------------------------------------------------------------
1450/* */
1451void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
1452{
1019948c
DK
1453 if (unlikely(Pkg.end() == true))
1454 return;
1455
9535a4db
DK
1456 APT::PackageList pkglist;
1457 if (Pkg->CurrentVer != 0 &&
1458 (Pkg.CurrentVer()-> MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
1459 {
1460 pkgCache::GrpIterator Grp = Pkg.Group();
1461 for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
1462 {
1463 if (P->CurrentVer != 0)
1464 pkglist.insert(P);
1465 }
1466 }
1467 else
1468 pkglist.insert(Pkg);
1469
74a05226
MV
1470 ActionGroup group(*this);
1471
9535a4db
DK
1472 for (APT::PackageList::const_iterator Pkg = pkglist.begin(); Pkg != pkglist.end(); ++Pkg)
1473 {
1474 RemoveSizes(Pkg);
1475 RemoveStates(Pkg);
1476
1477 StateCache &P = PkgState[Pkg->ID];
1478 if (To == true)
1479 P.iFlags |= ReInstall;
1480 else
1481 P.iFlags &= ~ReInstall;
1482
1483 AddStates(Pkg);
1484 AddSizes(Pkg);
1485 }
d0c59649
AL
1486}
1487 /*}}}*/
294a8020
DK
1488pkgCache::VerIterator pkgDepCache::GetCandidateVersion(PkgIterator const &Pkg)/*{{{*/
1489{
1490 return PkgState[Pkg->ID].CandidateVerIter(*this);
1491}
1492 /*}}}*/
b2e465d6
AL
1493// DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
1494// ---------------------------------------------------------------------
1495/* */
27e8981a 1496void pkgDepCache::SetCandidateVersion(VerIterator TargetVer)
b2e465d6
AL
1497{
1498 pkgCache::PkgIterator Pkg = TargetVer.ParentPkg();
1499 StateCache &P = PkgState[Pkg->ID];
74a05226 1500
08fa1cab
DK
1501 if (P.CandidateVer == TargetVer)
1502 return;
1503
1504 ActionGroup group(*this);
1505
b2e465d6
AL
1506 RemoveSizes(Pkg);
1507 RemoveStates(Pkg);
1508
758729c8 1509 if (P.CandidateVer == P.InstallVer && P.Install() == true)
b2e465d6
AL
1510 P.InstallVer = (Version *)TargetVer;
1511 P.CandidateVer = (Version *)TargetVer;
1512 P.Update(Pkg,*this);
1513
1514 AddStates(Pkg);
1515 Update(Pkg);
1516 AddSizes(Pkg);
1019948c 1517
b2e465d6 1518}
08fa1cab 1519 /*}}}*/
2c085486
DK
1520// DepCache::SetCandidateRelease - Change the candidate version /*{{{*/
1521// ---------------------------------------------------------------------
1522/* changes the candidate of a package and walks over all its dependencies
1523 to check if it needs to change the candidate of the dependency, too,
1524 to reach a installable versionstate */
1525bool pkgDepCache::SetCandidateRelease(pkgCache::VerIterator TargetVer,
1526 std::string const &TargetRel)
1527{
1528 std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > Changed;
1529 return SetCandidateRelease(TargetVer, TargetRel, Changed);
1530}
1531bool pkgDepCache::SetCandidateRelease(pkgCache::VerIterator TargetVer,
1532 std::string const &TargetRel,
1533 std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > &Changed)
1534{
758729c8 1535 ActionGroup group(*this);
2c085486
DK
1536 SetCandidateVersion(TargetVer);
1537
1538 if (TargetRel == "installed" || TargetRel == "candidate") // both doesn't make sense in this context
1539 return true;
1540
1541 pkgVersionMatch Match(TargetRel, pkgVersionMatch::Release);
1542 // save the position of the last element we will not undo - if we have to
1543 std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::iterator newChanged = --(Changed.end());
1544
1545 for (pkgCache::DepIterator D = TargetVer.DependsList(); D.end() == false; ++D)
1546 {
1547 if (D->Type != pkgCache::Dep::PreDepends && D->Type != pkgCache::Dep::Depends &&
1548 ((D->Type != pkgCache::Dep::Recommends && D->Type != pkgCache::Dep::Suggests) ||
1549 IsImportantDep(D) == false))
1550 continue;
1551
1552 // walk over an or-group and check if we need to do anything
1553 // for simpilicity no or-group is handled as a or-group including one dependency
1554 pkgCache::DepIterator Start = D;
1555 bool itsFine = false;
1556 for (bool stillOr = true; stillOr == true; ++Start)
1557 {
1558 stillOr = (Start->CompareOp & Dep::Or) == Dep::Or;
1559 pkgCache::PkgIterator const P = Start.TargetPkg();
1560 // virtual packages can't be a solution
1561 if (P.end() == true || (P->ProvidesList == 0 && P->VersionList == 0))
1562 continue;
1563 pkgCache::VerIterator const Cand = PkgState[P->ID].CandidateVerIter(*this);
1564 // no versioned dependency - but is it installable?
1565 if (Start.TargetVer() == 0 || Start.TargetVer()[0] == '\0')
1566 {
1567 // Check if one of the providers is installable
1568 if (P->ProvidesList != 0)
1569 {
1570 pkgCache::PrvIterator Prv = P.ProvidesList();
1571 for (; Prv.end() == false; ++Prv)
1572 {
1573 pkgCache::VerIterator const C = PkgState[Prv.OwnerPkg()->ID].CandidateVerIter(*this);
1574 if (C.end() == true || C != Prv.OwnerVer() ||
1575 (VersionState(C.DependsList(), DepInstall, DepCandMin, DepCandPolicy) & DepCandMin) != DepCandMin)
1576 continue;
1577 break;
1578 }
1579 if (Prv.end() == true)
1580 continue;
1581 }
1582 // no providers, so check if we have an installable candidate version
1583 else if (Cand.end() == true ||
1584 (VersionState(Cand.DependsList(), DepInstall, DepCandMin, DepCandPolicy) & DepCandMin) != DepCandMin)
1585 continue;
1586 itsFine = true;
1587 break;
1588 }
1589 if (Cand.end() == true)
1590 continue;
1591 // check if the current candidate is enough for the versioned dependency - and installable?
887c6940 1592 if (Start.IsSatisfied(Cand) == true &&
2c085486
DK
1593 (VersionState(Cand.DependsList(), DepInstall, DepCandMin, DepCandPolicy) & DepCandMin) == DepCandMin)
1594 {
1595 itsFine = true;
1596 break;
1597 }
1598 }
1599
1600 if (itsFine == true) {
1601 // something in the or-group was fine, skip all other members
1602 for (; (D->CompareOp & Dep::Or) == Dep::Or; ++D);
1603 continue;
1604 }
1605
1606 // walk again over the or-group and check each if a candidate switch would help
1607 itsFine = false;
1608 for (bool stillOr = true; stillOr == true; ++D)
1609 {
1610 stillOr = (D->CompareOp & Dep::Or) == Dep::Or;
1611 // changing candidate will not help if the dependency is not versioned
1612 if (D.TargetVer() == 0 || D.TargetVer()[0] == '\0')
1613 {
1614 if (stillOr == true)
1615 continue;
1616 break;
1617 }
1618
1619 pkgCache::VerIterator V;
1620 if (TargetRel == "newest")
1621 V = D.TargetPkg().VersionList();
1622 else
1623 V = Match.Find(D.TargetPkg());
1624
1625 // check if the version from this release could satisfy the dependency
887c6940 1626 if (V.end() == true || D.IsSatisfied(V) == false)
2c085486
DK
1627 {
1628 if (stillOr == true)
1629 continue;
1630 break;
1631 }
1632
1633 pkgCache::VerIterator oldCand = PkgState[D.TargetPkg()->ID].CandidateVerIter(*this);
1634 if (V == oldCand)
1635 {
1636 // Do we already touched this Version? If so, their versioned dependencies are okay, no need to check again
1637 for (std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::const_iterator c = Changed.begin();
1638 c != Changed.end(); ++c)
1639 {
1640 if (c->first->ParentPkg != V->ParentPkg)
1641 continue;
1642 itsFine = true;
1643 break;
1644 }
1645 }
1646
1647 if (itsFine == false)
1648 {
1649 // change the candidate
2f5ed336 1650 Changed.push_back(make_pair(V, TargetVer));
2c085486
DK
1651 if (SetCandidateRelease(V, TargetRel, Changed) == false)
1652 {
1653 if (stillOr == false)
1654 break;
1655 // undo the candidate changing
1656 SetCandidateVersion(oldCand);
1657 Changed.pop_back();
1658 continue;
1659 }
1660 itsFine = true;
1661 }
1662
1663 // something in the or-group was fine, skip all other members
1664 for (; (D->CompareOp & Dep::Or) == Dep::Or; ++D);
1665 break;
1666 }
1667
1668 if (itsFine == false && (D->Type == pkgCache::Dep::PreDepends || D->Type == pkgCache::Dep::Depends))
1669 {
1670 // undo all changes which aren't lead to a solution
1671 for (std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::const_iterator c = ++newChanged;
1672 c != Changed.end(); ++c)
1673 SetCandidateVersion(c->first);
1674 Changed.erase(newChanged, Changed.end());
1675 return false;
1676 }
1677 }
1678 return true;
1679}
1680 /*}}}*/
08fa1cab
DK
1681// DepCache::MarkAuto - set the Auto flag for a package /*{{{*/
1682// ---------------------------------------------------------------------
1683/* */
74a05226
MV
1684void pkgDepCache::MarkAuto(const PkgIterator &Pkg, bool Auto)
1685{
1686 StateCache &state = PkgState[Pkg->ID];
1687
1688 ActionGroup group(*this);
1689
1690 if(Auto)
1691 state.Flags |= Flag::Auto;
1692 else
1693 state.Flags &= ~Flag::Auto;
1694}
b2e465d6 1695 /*}}}*/
6c139d6e
AL
1696// StateCache::Update - Compute the various static display things /*{{{*/
1697// ---------------------------------------------------------------------
1698/* This is called whenever the Candidate version changes. */
1699void pkgDepCache::StateCache::Update(PkgIterator Pkg,pkgCache &Cache)
1700{
1701 // Some info
1702 VerIterator Ver = CandidateVerIter(Cache);
1703
1704 // Use a null string or the version string
1705 if (Ver.end() == true)
1706 CandVersion = "";
1707 else
1708 CandVersion = Ver.VerStr();
1709
1710 // Find the current version
1711 CurVersion = "";
1712 if (Pkg->CurrentVer != 0)
1713 CurVersion = Pkg.CurrentVer().VerStr();
a38cec81 1714
6c139d6e
AL
1715 // Figure out if its up or down or equal
1716 Status = Ver.CompareVer(Pkg.CurrentVer());
1717 if (Pkg->CurrentVer == 0 || Pkg->VersionList == 0 || CandidateVer == 0)
1718 Status = 2;
1719}
1720 /*}}}*/
1721// StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
1722// ---------------------------------------------------------------------
1723/* */
1724const char *pkgDepCache::StateCache::StripEpoch(const char *Ver)
1725{
1726 if (Ver == 0)
1727 return 0;
1728
1729 // Strip any epoch
fd23676e
DK
1730 char const * const I = strchr(Ver, ':');
1731 if (I == nullptr)
1732 return Ver;
1733 return I + 1;
6c139d6e
AL
1734}
1735 /*}}}*/
b2e465d6 1736// Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
6321777b 1737// ---------------------------------------------------------------------
b2e465d6
AL
1738/* The default just returns the highest available version that is not
1739 a source and automatic. */
e841200b 1740pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator const &Pkg)
6321777b 1741{
b2e465d6
AL
1742 /* Not source/not automatic versions cannot be a candidate version
1743 unless they are already installed */
de6221c9 1744 VerIterator Last;
6321777b 1745
f7f0d6c7 1746 for (VerIterator I = Pkg.VersionList(); I.end() == false; ++I)
b2e465d6
AL
1747 {
1748 if (Pkg.CurrentVer() == I)
1749 return I;
1750
f7f0d6c7 1751 for (VerFileIterator J = I.FileList(); J.end() == false; ++J)
b2e465d6 1752 {
b07aeb1a 1753 if (J.File().Flagged(Flag::NotSource))
b2e465d6
AL
1754 continue;
1755
1756 /* Stash the highest version of a not-automatic source, we use it
1757 if there is nothing better */
b07aeb1a
DK
1758 if (J.File().Flagged(Flag::NotAutomatic) ||
1759 J.File().Flagged(Flag::ButAutomaticUpgrades))
b2e465d6
AL
1760 {
1761 if (Last.end() == true)
1762 Last = I;
1763 continue;
1764 }
1765
1766 return I;
1767 }
1768 }
6321777b 1769
b2e465d6
AL
1770 return Last;
1771}
1772 /*}}}*/
1773// Policy::IsImportantDep - True if the dependency is important /*{{{*/
1774// ---------------------------------------------------------------------
1775/* */
fd23676e 1776bool pkgDepCache::Policy::IsImportantDep(DepIterator const &Dep) const
b2e465d6 1777{
60681f93
MV
1778 if(Dep.IsCritical())
1779 return true;
fd23676e 1780 else if(Dep->Type == pkgCache::Dep::Recommends)
1d722933 1781 {
b20c1683 1782 if (InstallRecommends)
1d722933
MV
1783 return true;
1784 // we suport a special mode to only install-recommends for certain
1785 // sections
fd23676e 1786 // FIXME: this is a meant as a temporarly solution until the
1d722933 1787 // recommends are cleaned up
cb1933df
MV
1788 const char *sec = Dep.ParentVer().Section();
1789 if (sec && ConfigValueInSubTree("APT::Install-Recommends-Sections", sec))
1790 return true;
1d722933 1791 }
60681f93 1792 else if(Dep->Type == pkgCache::Dep::Suggests)
b20c1683 1793 return InstallSuggests;
60681f93 1794
74a05226
MV
1795 return false;
1796}
92fcbfc1 1797 /*}}}*/
6d38011b 1798// Policy::GetPriority - Get the priority of the package pin /*{{{*/
a02db58f 1799APT_CONST signed short pkgDepCache::Policy::GetPriority(pkgCache::PkgIterator const &/*Pkg*/)
d3e8fbb3 1800{ return 0; }
a0a66955
JAK
1801APT_CONST signed short pkgDepCache::Policy::GetPriority(pkgCache::VerIterator const &/*Ver*/, bool /*ConsiderFiles*/)
1802{ return 0; }
a02db58f 1803APT_CONST signed short pkgDepCache::Policy::GetPriority(pkgCache::PkgFileIterator const &/*File*/)
d3e8fbb3 1804{ return 0; }
6d38011b 1805 /*}}}*/
92fcbfc1 1806pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc() /*{{{*/
74a05226
MV
1807{
1808 DefaultRootSetFunc *f = new DefaultRootSetFunc;
1809 if(f->wasConstructedSuccessfully())
1810 return f;
1811 else
1812 {
1813 delete f;
1814 return NULL;
1815 }
1816}
92fcbfc1 1817 /*}}}*/
74a05226
MV
1818bool pkgDepCache::MarkFollowsRecommends()
1819{
1820 return _config->FindB("APT::AutoRemove::RecommendsImportant", true);
1821}
1822
1823bool pkgDepCache::MarkFollowsSuggests()
1824{
db4351be 1825 return _config->FindB("APT::AutoRemove::SuggestsImportant", true);
74a05226
MV
1826}
1827
92fcbfc1 1828// pkgDepCache::MarkRequired - the main mark algorithm /*{{{*/
5a3339db
DK
1829static bool IsPkgInBoringState(pkgCache::PkgIterator const &Pkg, pkgDepCache::StateCache const * const PkgState)
1830{
1831 if (Pkg->CurrentVer == 0)
1832 {
1833 if (PkgState[Pkg->ID].Keep())
1834 return true;
1835 }
1836 else
1837 {
1838 if (PkgState[Pkg->ID].Delete())
1839 return true;
1840 }
1841 return false;
1842}
74a05226
MV
1843bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
1844{
98278a81 1845 if (_config->Find("APT::Solver", "internal") != "internal")
76d4aab0
DK
1846 return true;
1847
fd23676e 1848 bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
74a05226
MV
1849
1850 // init the states
5a3339db
DK
1851 auto const PackagesCount = Head().PackageCount;
1852 for(auto i = decltype(PackagesCount){0}; i < PackagesCount; ++i)
74a05226 1853 {
fd23676e
DK
1854 PkgState[i].Marked = false;
1855 PkgState[i].Garbage = false;
74a05226 1856 }
fd23676e
DK
1857 if (debug_autoremove)
1858 for(PkgIterator p = PkgBegin(); !p.end(); ++p)
1859 if(PkgState[p->ID].Flags & Flag::Auto)
1860 std::clog << "AutoDep: " << p.FullName() << std::endl;
74a05226 1861
fd23676e
DK
1862 bool const follow_recommends = MarkFollowsRecommends();
1863 bool const follow_suggests = MarkFollowsSuggests();
74a05226 1864
74a05226 1865 // do the mark part, this is the core bit of the algorithm
769e9f3e 1866 for (PkgIterator P = PkgBegin(); !P.end(); ++P)
74a05226 1867 {
5a3339db
DK
1868 if (PkgState[P->ID].Marked || IsPkgInBoringState(P, PkgState))
1869 continue;
769e9f3e
DK
1870
1871 if ((PkgState[P->ID].Flags & Flag::Auto) == 0)
1872 ;
1873 else if ((P->Flags & Flag::Essential) || (P->Flags & Flag::Important))
1874 ;
1875 // be nice even then a required package violates the policy (#583517)
1876 // and do the full mark process also for required packages
1877 else if (P->CurrentVer != 0 && P.CurrentVer()->Priority == pkgCache::State::Required)
1878 ;
1879 else if (userFunc.InRootSet(P))
1880 ;
1881 // packages which can't be changed (like holds) can't be garbage
1882 else if (IsModeChangeOk(ModeGarbage, P, 0, false) == false)
1883 ;
1884 else
1885 continue;
1886
1887 if (PkgState[P->ID].Install())
1888 MarkPackage(P, PkgState[P->ID].InstVerIter(*this),
1889 follow_recommends, follow_suggests);
1890 else
1891 MarkPackage(P, P.CurrentVer(),
1892 follow_recommends, follow_suggests);
74a05226
MV
1893 }
1894
1895 return true;
1896}
92fcbfc1
DK
1897 /*}}}*/
1898// MarkPackage - mark a single package in Mark-and-Sweep /*{{{*/
5a3339db
DK
1899void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &Pkg,
1900 const pkgCache::VerIterator &Ver,
e0b94b97
DK
1901 bool const &follow_recommends,
1902 bool const &follow_suggests)
74a05226 1903{
5a3339db
DK
1904 {
1905 pkgDepCache::StateCache &state = PkgState[Pkg->ID];
1906 // if we are marked already we are done
1907 if(state.Marked || unlikely(Ver.end()))
1908 return;
1909 state.Marked=true;
1910 }
e0b94b97 1911
5a3339db 1912 if (IsPkgInBoringState(Pkg, PkgState))
e0b94b97
DK
1913 return;
1914
5a3339db
DK
1915 bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove", false);
1916 if(debug_autoremove)
1917 std::clog << "Marking: " << Pkg.FullName() << " " << Ver.VerStr() << std::endl;
cda456d7 1918
5a3339db 1919 for (auto D = Ver.DependsList(); D.end() == false; ++D)
74a05226 1920 {
5a3339db
DK
1921 auto const T = D.TargetPkg();
1922 if (PkgState[T->ID].Marked)
1923 continue;
74a05226 1924
5a3339db
DK
1925 if (D->Type != Dep::Depends &&
1926 D->Type != Dep::PreDepends &&
1927 (follow_recommends == false || D->Type != Dep::Recommends) &&
1928 (follow_suggests == false || D->Type != Dep::Suggests))
1929 continue;
74a05226 1930
5a3339db 1931 // handle the virtual part first
a0ed43f7 1932 APT::VersionVector providers;
5a3339db
DK
1933 for(auto Prv = T.ProvidesList(); Prv.end() == false; ++Prv)
1934 {
1935 auto PP = Prv.OwnerPkg();
a0ed43f7 1936 if (IsPkgInBoringState(PP, PkgState))
5a3339db 1937 continue;
74a05226 1938
5a3339db
DK
1939 // we want to ignore provides from uninteresting versions
1940 auto const PV = (PkgState[PP->ID].Install()) ?
1941 PkgState[PP->ID].InstVerIter(*this) : PP.CurrentVer();
1942 if (unlikely(PV.end()) || PV != Prv.OwnerVer() || D.IsSatisfied(Prv) == false)
1943 continue;
83860e37 1944
a0ed43f7
DK
1945 providers.emplace_back(PV);
1946 }
1947 if (providers.empty() == false)
1948 {
1949 // sort providers by source version so that only the latest versioned
1950 // binary package of a source package is marked instead of all
1951 std::sort(providers.begin(), providers.end(),
1952 [](pkgCache::VerIterator const &A, pkgCache::VerIterator const &B) {
1953 auto const nameret = strcmp(A.SourcePkgName(), B.SourcePkgName());
1954 if (nameret != 0)
1955 return nameret < 0;
1956 auto const verret = A.Cache()->VS->CmpVersion(A.SourceVerStr(), B.SourceVerStr());
1957 if (verret != 0)
1958 return verret > 0;
1959 return strcmp(A.ParentPkg().Name(), B.ParentPkg().Name()) < 0;
1960 });
1961 auto const prvsize = providers.size();
1962 providers.erase(std::unique(providers.begin(), providers.end(),
1963 [](pkgCache::VerIterator const &A, pkgCache::VerIterator const &B) {
1964 return strcmp(A.SourcePkgName(), B.SourcePkgName()) == 0 &&
1965 strcmp(A.SourceVerStr(), B.SourceVerStr()) != 0;
1966 }), providers.end());
1967 for (auto && PV: providers)
1968 {
1969 auto const PP = PV.ParentPkg();
1970 if (debug_autoremove)
1971 std::clog << "Following dep: " << APT::PrettyDep(this, D)
1972 << ", provided by " << PP.FullName() << " " << PV.VerStr()
1973 << " (" << providers.size() << "/" << prvsize << ")"<< std::endl;
1974 MarkPackage(PP, PV, follow_recommends, follow_suggests);
1975 }
5a3339db 1976 }
74a05226 1977
5a3339db
DK
1978 // now deal with the real part of the package
1979 if (IsPkgInBoringState(T, PkgState))
1980 continue;
e0b94b97 1981
5a3339db
DK
1982 auto const TV = (PkgState[T->ID].Install()) ?
1983 PkgState[T->ID].InstVerIter(*this) : T.CurrentVer();
1984 if (unlikely(TV.end()) || D.IsSatisfied(TV) == false)
1985 continue;
1986
1987 if (debug_autoremove)
1988 std::clog << "Following dep: " << APT::PrettyDep(this, D) << std::endl;
1989 MarkPackage(T, TV, follow_recommends, follow_suggests);
1990 }
74a05226 1991}
92fcbfc1
DK
1992 /*}}}*/
1993bool pkgDepCache::Sweep() /*{{{*/
74a05226 1994{
95afdfd0
OS
1995 bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
1996
74a05226
MV
1997 // do the sweep
1998 for(PkgIterator p=PkgBegin(); !p.end(); ++p)
95afdfd0 1999 {
74a05226
MV
2000 StateCache &state=PkgState[p->ID];
2001
c9b320e8
MV
2002 // skip required packages
2003 if (!p.CurrentVer().end() &&
2004 (p.CurrentVer()->Priority == pkgCache::State::Required))
2005 continue;
2006
74a05226 2007 // if it is not marked and it is installed, it's garbage
32085498 2008 if(!state.Marked && (!p.CurrentVer().end() || state.Install()))
74a05226
MV
2009 {
2010 state.Garbage=true;
95afdfd0 2011 if(debug_autoremove)
6ee2b0f8 2012 std::clog << "Garbage: " << p.FullName() << std::endl;
74a05226
MV
2013 }
2014 }
2015
2016 return true;
2017}
92fcbfc1 2018 /*}}}*/
107d054b
DK
2019// DepCache::MarkAndSweep /*{{{*/
2020bool pkgDepCache::MarkAndSweep(InRootSetFunc &rootFunc)
2021{
2022 return MarkRequired(rootFunc) && Sweep();
2023}
2024bool pkgDepCache::MarkAndSweep()
2025{
47c37a1b 2026 std::unique_ptr<InRootSetFunc> f(GetRootSetFunc());
107d054b
DK
2027 if(f.get() != NULL)
2028 return MarkAndSweep(*f.get());
2029 else
2030 return false;
2031}
2032 /*}}}*/