1 // Include Files /*{{{*/
4 #include <apt-pkg/acquire.h>
5 #include <apt-pkg/acquire-item.h>
6 #include <apt-pkg/algorithms.h>
7 #include <apt-pkg/cachefile.h>
8 #include <apt-pkg/cacheset.h>
9 #include <apt-pkg/cmndline.h>
10 #include <apt-pkg/depcache.h>
11 #include <apt-pkg/error.h>
12 #include <apt-pkg/fileutl.h>
13 #include <apt-pkg/pkgrecords.h>
14 #include <apt-pkg/pkgsystem.h>
15 #include <apt-pkg/sptr.h>
16 #include <apt-pkg/strutl.h>
17 #include <apt-pkg/cacheiterators.h>
18 #include <apt-pkg/configuration.h>
19 #include <apt-pkg/macros.h>
20 #include <apt-pkg/packagemanager.h>
21 #include <apt-pkg/pkgcache.h>
22 #include <apt-pkg/upgrade.h>
23 #include <apt-pkg/install-progress.h>
24 #include <apt-pkg/prettyprinters.h>
34 #include <apt-private/acqprogress.h>
35 #include <apt-private/private-install.h>
36 #include <apt-private/private-cachefile.h>
37 #include <apt-private/private-cacheset.h>
38 #include <apt-private/private-download.h>
39 #include <apt-private/private-output.h>
45 bool CheckNothingBroken(CacheFile
&Cache
) /*{{{*/
47 // Now we check the state of the packages,
48 if (Cache
->BrokenCount() == 0)
51 // FIXME: if an external solver showed an error, we shouldn't show one here
52 if (_error
->PendingError() && _config
->Find("APT::Solver") == "dump")
56 _("Some packages could not be installed. This may mean that you have\n"
57 "requested an impossible situation or if you are using the unstable\n"
58 "distribution that some required packages have not yet been created\n"
59 "or been moved out of Incoming.") << std::endl
;
65 _("Since you only requested a single operation it is extremely likely that\n"
66 "the package is simply not installable and a bug report against\n"
67 "that package should be filed.") << std::endl;
71 c1out
<< _("The following information may help to resolve the situation:") << std::endl
;
73 ShowBroken(c1out
,Cache
,false);
74 if (_error
->PendingError() == true)
77 return _error
->Error(_("Broken packages"));
80 // InstallPackages - Actually download and install the packages /*{{{*/
81 // ---------------------------------------------------------------------
82 /* This displays the informative messages describing what is going to
83 happen and then calls the download routines */
84 static void RemoveDownloadNeedingItemsFromFetcher(pkgAcquire
&Fetcher
, bool &Transient
)
86 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
< Fetcher
.ItemsEnd();)
88 if ((*I
)->Local
== true)
94 // Close the item and check if it was found in cache
96 if ((*I
)->Complete
== false)
99 // Clear it out of the fetch list
101 I
= Fetcher
.ItemsBegin();
104 bool InstallPackages(CacheFile
&Cache
,bool ShwKept
,bool Ask
, bool Safety
)
106 if (_config
->FindB("APT::Get::Purge", false) == true)
107 for (pkgCache::PkgIterator I
= Cache
->PkgBegin(); I
.end() == false; ++I
)
108 if (Cache
[I
].Delete() == true && Cache
[I
].Purge() == false)
109 Cache
->MarkDelete(I
,true);
111 // Create the download object
112 aptAcquireWithTextStatus Fetcher
;
113 if (_config
->FindB("APT::Get::Print-URIs", false) == true)
115 // force a hashsum for compatibility reasons
116 _config
->CndSet("Acquire::ForceHash", "md5sum");
118 else if (_config
->FindB("APT::Get::Simulate") == true)
120 else if (Fetcher
.GetLock(_config
->FindDir("Dir::Cache::Archives")) == false)
123 // Read the source list
124 if (Cache
.BuildSourceList() == false)
126 pkgSourceList
* const List
= Cache
.GetSourceList();
128 // Create the text record parser
129 pkgRecords
Recs(Cache
);
130 if (_error
->PendingError() == true)
133 // Create the package manager and prepare to download
134 std::unique_ptr
<pkgPackageManager
> PM(_system
->CreatePM(Cache
));
135 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false ||
136 _error
->PendingError() == true)
139 if (_config
->FindB("APT::Get::Fix-Missing",false) == true &&
140 _config
->FindB("APT::Get::Download",true) == false)
142 bool Missing
= false;
143 RemoveDownloadNeedingItemsFromFetcher(Fetcher
, Missing
);
147 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false ||
148 _error
->PendingError() == true)
152 // Show all the various warning indicators
153 ShowDel(c1out
,Cache
);
154 ShowNew(c1out
,Cache
);
156 ShowKept(c1out
,Cache
);
157 bool const Hold
= !ShowHold(c1out
,Cache
);
158 if (_config
->FindB("APT::Get::Show-Upgraded",true) == true)
159 ShowUpgraded(c1out
,Cache
);
160 bool const Downgrade
= !ShowDowngraded(c1out
,Cache
);
162 bool Essential
= false;
163 if (_config
->FindB("APT::Get::Download-Only",false) == false)
164 Essential
= !ShowEssential(c1out
,Cache
);
169 if (Cache
->BrokenCount() != 0)
171 ShowBroken(c1out
,Cache
,false);
172 return _error
->Error(_("Internal error, InstallPackages was called with broken packages!"));
175 if (Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
176 Cache
->BadCount() == 0)
180 if (Cache
->DelCount() != 0 && _config
->FindB("APT::Get::Remove",true) == false)
181 return _error
->Error(_("Packages need to be removed but remove is disabled."));
184 bool const Fail
= (Essential
|| Downgrade
|| Hold
);
185 if (_config
->FindI("quiet",0) >= 2 ||
186 _config
->FindB("APT::Get::Assume-Yes",false) == true)
188 if (_config
->FindB("APT::Get::Force-Yes",false) == true) {
189 _error
->Warning(_("--force-yes is deprecated, use one of the options starting with --allow instead."));
192 if (Fail
== true && _config
->FindB("APT::Get::Force-Yes",false) == false) {
193 if (Essential
== true && _config
->FindB("APT::Get::allow-remove-essential", false) == false)
194 return _error
->Error(_("Essential packages were removed and -y was used without --allow-remove-essential."));
195 if (Downgrade
== true && _config
->FindB("APT::Get::allow-downgrades", false) == false)
196 return _error
->Error(_("Packages were downgraded and -y was used without --allow-downgrades."));
197 if (Hold
== true && _config
->FindB("APT::Get::allow-change-held-packages", false) == false)
198 return _error
->Error(_("Held packages were changed and -y was used without --allow-change-held-packages."));
202 // Run the simulator ..
203 if (_config
->FindB("APT::Get::Simulate") == true)
205 pkgSimulate
PM(Cache
);
207 APT::Progress::PackageManager
*progress
= APT::Progress::PackageManagerProgressFactory();
208 pkgPackageManager::OrderResult Res
= PM
.DoInstall(progress
);
211 if (Res
== pkgPackageManager::Failed
)
213 if (Res
!= pkgPackageManager::Completed
)
214 return _error
->Error(_("Internal error, Ordering didn't finish"));
218 // Display statistics
219 auto const FetchBytes
= Fetcher
.FetchNeeded();
220 auto const FetchPBytes
= Fetcher
.PartialPresent();
221 auto const DebBytes
= Fetcher
.TotalNeeded();
222 if (DebBytes
!= Cache
->DebSize())
224 c0out
<< DebBytes
<< ',' << Cache
->DebSize() << std::endl
;
225 c0out
<< _("How odd... The sizes didn't match, email apt@packages.debian.org") << std::endl
;
229 if (DebBytes
!= FetchBytes
)
230 //TRANSLATOR: The required space between number and unit is already included
231 // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
232 ioprintf(c1out
,_("Need to get %sB/%sB of archives.\n"),
233 SizeToStr(FetchBytes
).c_str(),SizeToStr(DebBytes
).c_str());
234 else if (DebBytes
!= 0)
235 //TRANSLATOR: The required space between number and unit is already included
236 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
237 ioprintf(c1out
,_("Need to get %sB of archives.\n"),
238 SizeToStr(DebBytes
).c_str());
241 if (Cache
->UsrSize() >= 0)
242 //TRANSLATOR: The required space between number and unit is already included
243 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
244 ioprintf(c1out
,_("After this operation, %sB of additional disk space will be used.\n"),
245 SizeToStr(Cache
->UsrSize()).c_str());
247 //TRANSLATOR: The required space between number and unit is already included
248 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
249 ioprintf(c1out
,_("After this operation, %sB disk space will be freed.\n"),
250 SizeToStr(-1*Cache
->UsrSize()).c_str());
252 if (CheckFreeSpaceBeforeDownload(_config
->FindDir("Dir::Cache::Archives"), (FetchBytes
- FetchPBytes
)) == false)
255 if (_error
->PendingError() == true)
258 // Just print out the uris an exit if the --print-uris flag was used
259 if (_config
->FindB("APT::Get::Print-URIs") == true)
261 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
262 for (; I
!= Fetcher
.UriEnd(); ++I
)
263 std::cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
264 std::to_string(I
->Owner
->FileSize
) << ' ' << I
->Owner
->HashSum() << std::endl
;
268 if (Essential
== true && Safety
== true && _config
->FindB("APT::Get::allow-remove-essential", false) == false)
270 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
271 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
273 // TRANSLATOR: This string needs to be typed by the user as a confirmation, so be
274 // careful with hard to type or special characters (like non-breaking spaces)
275 const char *Prompt
= _("Yes, do as I say!");
276 std::string question
;
278 _("You are about to do something potentially harmful.\n"
279 "To continue type in the phrase '%s'\n"
281 if (AnalPrompt(question
, Prompt
) == false)
283 c2out
<< _("Abort.") << std::endl
;
289 // Prompt to continue
290 if (Ask
== true || Fail
== true)
292 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
293 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
295 if (_config
->FindI("quiet",0) < 2 &&
296 _config
->FindB("APT::Get::Assume-Yes",false) == false)
298 if (YnPrompt(_("Do you want to continue?")) == false)
300 c2out
<< _("Abort.") << std::endl
;
307 if (!CheckAuth(Fetcher
, true))
310 /* Unlock the dpkg lock if we are not going to be doing an install
312 if (_config
->FindB("APT::Get::Download-Only",false) == true)
319 bool Transient
= false;
320 if (AcquireRun(Fetcher
, 0, &Failed
, &Transient
) == false)
323 if (_config
->FindB("APT::Get::Download-Only",false) == true)
325 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
326 return _error
->Error(_("Some files failed to download"));
327 c1out
<< _("Download complete and in download only mode") << std::endl
;
331 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
332 return _error
->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
334 if (Transient
== true && Failed
== true)
335 return _error
->Error(_("--fix-missing and media swapping is not currently supported"));
337 // Try to deal with missing package files
338 if (Failed
== true && PM
->FixMissing() == false)
340 c2out
<< _("Unable to correct missing packages.") << std::endl
;
341 return _error
->Error(_("Aborting install."));
344 auto const progress
= APT::Progress::PackageManagerProgressFactory();
346 pkgPackageManager::OrderResult
const Res
= PM
->DoInstall(progress
);
349 if (Res
== pkgPackageManager::Failed
|| _error
->PendingError() == true)
351 if (Res
== pkgPackageManager::Completed
)
356 // Reload the fetcher object and loop again for media swapping
358 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false)
362 if (_config
->FindB("APT::Get::Download",true) == false)
363 RemoveDownloadNeedingItemsFromFetcher(Fetcher
, Failed
);
366 std::set
<std::string
> const disappearedPkgs
= PM
->GetDisappearedPackages();
367 if (disappearedPkgs
.empty() == false)
369 ShowList(c1out
, P_("The following package disappeared from your system as\n"
370 "all files have been overwritten by other packages:",
371 "The following packages disappeared from your system as\n"
372 "all files have been overwritten by other packages:", disappearedPkgs
.size()), disappearedPkgs
,
373 [](std::string
const &Pkg
) { return Pkg
.empty() == false; },
374 [](std::string
const &Pkg
) { return Pkg
; },
375 [](std::string
const &) { return std::string(); });
376 c0out
<< _("Note: This is done automatically and on purpose by dpkg.") << std::endl
;
379 // cleanup downloaded debs
380 if (_config
->FindB("APT::Keep-Downloaded-Packages", true) == false)
382 std::string
const archivedir
= _config
->FindDir("Dir::Cache::archives");
383 for (auto I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); ++I
)
385 if (flNotFile((*I
)->DestFile
) != archivedir
|| (*I
)->Local
)
387 RemoveFile("Keep-Downloaded-Packages=false", (*I
)->DestFile
);
394 // DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
395 // ---------------------------------------------------------------------
396 /* Remove unused automatic packages */
397 bool DoAutomaticRemove(CacheFile
&Cache
)
399 bool Debug
= _config
->FindI("Debug::pkgAutoRemove",false);
400 bool doAutoRemove
= _config
->FindB("APT::Get::AutomaticRemove", false);
401 bool hideAutoRemove
= _config
->FindB("APT::Get::HideAutoRemove");
403 pkgDepCache::ActionGroup
group(*Cache
);
405 std::cout
<< "DoAutomaticRemove()" << std::endl
;
407 if (doAutoRemove
== true &&
408 _config
->FindB("APT::Get::Remove",true) == false)
410 c1out
<< _("We are not supposed to delete stuff, can't start "
411 "AutoRemover") << std::endl
;
415 bool purgePkgs
= _config
->FindB("APT::Get::Purge", false);
416 bool smallList
= (hideAutoRemove
== false &&
417 strcasecmp(_config
->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
419 unsigned long autoRemoveCount
= 0;
420 APT::PackageSet tooMuch
;
421 SortedPackageUniverse
Universe(Cache
);
422 // look over the cache to see what can be removed
423 for (auto const &Pkg
: Universe
)
425 if (Cache
[Pkg
].Garbage
)
427 if(Pkg
.CurrentVer() != 0 || Cache
[Pkg
].Install())
429 std::cout
<< "We could delete " << APT::PrettyPkg(Cache
, Pkg
) << std::endl
;
433 if(Pkg
.CurrentVer() != 0 &&
434 Pkg
->CurrentState
!= pkgCache::State::ConfigFiles
)
435 Cache
->MarkDelete(Pkg
, purgePkgs
, 0, false);
437 Cache
->MarkKeep(Pkg
, false, false);
441 // if the package is a new install and already garbage we don't need to
442 // install it in the first place, so nuke it instead of show it
443 if (Cache
[Pkg
].Install() == true && Pkg
.CurrentVer() == 0)
446 Cache
->MarkDelete(Pkg
, false, 0, false);
448 // only show stuff in the list that is not yet marked for removal
449 else if(hideAutoRemove
== false && Cache
[Pkg
].Delete() == false)
455 // we could have removed a new dependency of a garbage package,
456 // so check if a reverse depends is broken and if so install it again.
457 if (tooMuch
.empty() == false && (Cache
->BrokenCount() != 0 || Cache
->PolicyBrokenCount() != 0))
462 for (APT::PackageSet::iterator Pkg
= tooMuch
.begin();
463 Pkg
!= tooMuch
.end(); ++Pkg
)
467 for (pkgCache::PrvIterator Prv
= Cache
[Pkg
].CandidateVerIter(Cache
).ProvidesList();
468 Prv
.end() == false; ++Prv
)
469 too
.insert(Prv
.ParentPkg());
470 for (APT::PackageSet::const_iterator P
= too
.begin(); P
!= too
.end(); ++P
)
472 for (pkgCache::DepIterator R
= P
.RevDependsList();
473 R
.end() == false; ++R
)
475 if (R
.IsNegative() == true ||
476 Cache
->IsImportantDep(R
) == false)
478 auto const RV
= R
.ParentVer();
479 if (unlikely(RV
.end() == true))
481 auto const RP
= RV
.ParentPkg();
482 // check if that dependency comes from an interesting version
483 if (RP
.CurrentVer() == RV
)
485 if ((*Cache
)[RP
].Keep() == false)
488 else if (Cache
[RP
].CandidateVerIter(Cache
) == RV
)
490 if ((*Cache
)[RP
].NewInstall() == false && (*Cache
)[RP
].Upgrade() == false)
493 else // ignore dependency from a non-candidate version
496 std::clog
<< "Save " << APT::PrettyPkg(Cache
, Pkg
) << " as another installed package depends on it: " << APT::PrettyPkg(Cache
, RP
) << std::endl
;
497 Cache
->MarkInstall(Pkg
, false, 0, false);
498 if (hideAutoRemove
== false)
510 } while (Changed
== true);
512 // trigger marking now so that the package list below is correct
515 // Now see if we had destroyed anything (if we had done anything)
516 if (Cache
->BrokenCount() != 0)
518 c1out
<< _("Hmm, seems like the AutoRemover destroyed something which really\n"
519 "shouldn't happen. Please file a bug report against apt.") << std::endl
;
521 c1out
<< _("The following information may help to resolve the situation:") << std::endl
;
523 ShowBroken(c1out
,Cache
,false);
525 return _error
->Error(_("Internal Error, AutoRemover broke stuff"));
528 // if we don't remove them, we should show them!
529 if (doAutoRemove
== false && autoRemoveCount
!= 0)
531 if (smallList
== false)
533 SortedPackageUniverse
Universe(Cache
);
534 ShowList(c1out
, P_("The following package was automatically installed and is no longer required:",
535 "The following packages were automatically installed and are no longer required:",
536 autoRemoveCount
), Universe
,
537 [&Cache
](pkgCache::PkgIterator
const &Pkg
) { return (*Cache
)[Pkg
].Garbage
== true && (*Cache
)[Pkg
].Delete() == false; },
538 &PrettyFullName
, CandidateVersion(&Cache
));
541 ioprintf(c1out
, P_("%lu package was automatically installed and is no longer required.\n",
542 "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount
), autoRemoveCount
);
543 std::string autocmd
= "apt autoremove";
544 if (getenv("SUDO_USER") != nullptr)
546 auto const envsudocmd
= getenv("SUDO_COMMAND");
547 auto const envshell
= getenv("SHELL");
548 if (envsudocmd
== nullptr || envshell
== nullptr || strcmp(envsudocmd
, envshell
) != 0)
549 autocmd
= "sudo " + autocmd
;
551 ioprintf(c1out
, P_("Use '%s' to remove it.", "Use '%s' to remove them.", autoRemoveCount
), autocmd
.c_str());
557 // DoCacheManipulationFromCommandLine /*{{{*/
558 static const unsigned short MOD_REMOVE
= 1;
559 static const unsigned short MOD_INSTALL
= 2;
561 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, CacheFile
&Cache
, int UpgradeMode
)
563 std::vector
<std::string
> VolatileCmdL
;
564 return DoCacheManipulationFromCommandLine(CmdL
, VolatileCmdL
, Cache
, UpgradeMode
);
566 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, std::vector
<std::string
> &VolatileCmdL
, CacheFile
&Cache
, int UpgradeMode
)
568 std::map
<unsigned short, APT::VersionSet
> verset
;
569 return DoCacheManipulationFromCommandLine(CmdL
, VolatileCmdL
, Cache
, verset
, UpgradeMode
);
571 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, std::vector
<std::string
> &VolatileCmdL
, CacheFile
&Cache
,
572 std::map
<unsigned short, APT::VersionSet
> &verset
, int UpgradeMode
)
574 // Enter the special broken fixing mode if the user specified arguments
575 bool BrokenFix
= false;
576 if (Cache
->BrokenCount() != 0)
579 std::unique_ptr
<pkgProblemResolver
> Fix(nullptr);
580 if (_config
->FindB("APT::Get::CallResolver", true) == true)
581 Fix
.reset(new pkgProblemResolver(Cache
));
583 unsigned short fallback
= MOD_INSTALL
;
584 if (strcasecmp(CmdL
.FileList
[0],"remove") == 0)
585 fallback
= MOD_REMOVE
;
586 else if (strcasecmp(CmdL
.FileList
[0], "purge") == 0)
588 _config
->Set("APT::Get::Purge", true);
589 fallback
= MOD_REMOVE
;
591 else if (strcasecmp(CmdL
.FileList
[0], "autoremove") == 0 ||
592 strcasecmp(CmdL
.FileList
[0], "auto-remove") == 0)
594 _config
->Set("APT::Get::AutomaticRemove", "true");
595 fallback
= MOD_REMOVE
;
598 std::list
<APT::VersionSet::Modifier
> mods
;
599 mods
.push_back(APT::VersionSet::Modifier(MOD_INSTALL
, "+",
600 APT::VersionSet::Modifier::POSTFIX
, APT::CacheSetHelper::CANDIDATE
));
601 mods
.push_back(APT::VersionSet::Modifier(MOD_REMOVE
, "-",
602 APT::VersionSet::Modifier::POSTFIX
, APT::CacheSetHelper::NEWEST
));
603 CacheSetHelperAPTGet
helper(c0out
);
604 verset
= APT::VersionSet::GroupedFromCommandLine(Cache
,
605 CmdL
.FileList
+ 1, mods
, fallback
, helper
);
607 for (auto const &I
: VolatileCmdL
)
609 pkgCache::PkgIterator
const P
= Cache
->FindPkg(I
);
613 // Set any version providing the .deb as the candidate.
614 for (auto Prv
= P
.ProvidesList(); Prv
.end() == false; Prv
++)
615 Cache
.GetDepCache()->SetCandidateVersion(Prv
.OwnerVer());
617 // via cacheset to have our usual virtual handling
618 APT::VersionContainerInterface::FromPackage(&(verset
[MOD_INSTALL
]), Cache
, P
, APT::CacheSetHelper::CANDIDATE
, helper
);
621 if (_error
->PendingError() == true)
623 helper
.showVirtualPackageErrors(Cache
);
628 TryToInstall
InstallAction(Cache
, Fix
.get(), BrokenFix
);
629 TryToRemove
RemoveAction(Cache
, Fix
.get());
631 // new scope for the ActionGroup
633 pkgDepCache::ActionGroup
group(Cache
);
634 unsigned short const order
[] = { MOD_REMOVE
, MOD_INSTALL
, 0 };
636 for (unsigned short i
= 0; order
[i
] != 0; ++i
)
638 if (order
[i
] == MOD_INSTALL
)
639 InstallAction
= std::for_each(verset
[MOD_INSTALL
].begin(), verset
[MOD_INSTALL
].end(), InstallAction
);
640 else if (order
[i
] == MOD_REMOVE
)
641 RemoveAction
= std::for_each(verset
[MOD_REMOVE
].begin(), verset
[MOD_REMOVE
].end(), RemoveAction
);
644 if (Fix
!= NULL
&& _config
->FindB("APT::Get::AutoSolving", true) == true)
646 InstallAction
.propergateReleaseCandiateSwitching(helper
.selectedByRelease
, c0out
);
647 InstallAction
.doAutoInstall();
650 if (_error
->PendingError() == true)
655 /* If we are in the Broken fixing mode we do not attempt to fix the
656 problems. This is if the user invoked install without -f and gave
658 if (BrokenFix
== true && Cache
->BrokenCount() != 0)
660 c1out
<< _("You might want to run 'apt-get -f install' to correct these:") << std::endl
;
661 ShowBroken(c1out
,Cache
,false);
662 return _error
->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
667 // Call the scored problem resolver
668 OpTextProgress
Progress(*_config
);
669 bool const distUpgradeMode
= strcmp(CmdL
.FileList
[0], "dist-upgrade") == 0 || strcmp(CmdL
.FileList
[0], "full-upgrade") == 0;
671 bool resolver_fail
= false;
672 if (distUpgradeMode
== true || UpgradeMode
!= APT::Upgrade::ALLOW_EVERYTHING
)
673 resolver_fail
= APT::Upgrade::Upgrade(Cache
, UpgradeMode
, &Progress
);
675 resolver_fail
= Fix
->Resolve(true, &Progress
);
677 if (resolver_fail
== false && Cache
->BrokenCount() == 0)
681 if (CheckNothingBroken(Cache
) == false)
684 if (!DoAutomaticRemove(Cache
))
687 // if nothing changed in the cache, but only the automark information
688 // we write the StateFile here, otherwise it will be written in
690 if (InstallAction
.AutoMarkChanged
> 0 &&
691 Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
692 Cache
->BadCount() == 0 &&
693 _config
->FindB("APT::Get::Simulate",false) == false)
694 Cache
->writeStateFile(NULL
);
699 // DoInstall - Install packages from the command line /*{{{*/
700 // ---------------------------------------------------------------------
701 /* Install named packages */
702 struct PkgIsExtraInstalled
{
703 pkgCacheFile
* const Cache
;
704 APT::VersionSet
const * const verset
;
705 PkgIsExtraInstalled(pkgCacheFile
* const Cache
, APT::VersionSet
const * const Container
) : Cache(Cache
), verset(Container
) {}
706 bool operator() (pkgCache::PkgIterator
const &Pkg
)
708 if ((*Cache
)[Pkg
].Install() == false)
710 pkgCache::VerIterator
const Cand
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
711 return verset
->find(Cand
) == verset
->end();
714 bool DoInstall(CommandLine
&CmdL
)
717 std::vector
<std::string
> VolatileCmdL
;
718 Cache
.GetSourceList()->AddVolatileFiles(CmdL
, &VolatileCmdL
);
720 // then open the cache
721 if (Cache
.OpenForInstall() == false ||
722 Cache
.CheckDeps(CmdL
.FileSize() != 1) == false)
725 std::map
<unsigned short, APT::VersionSet
> verset
;
726 if(!DoCacheManipulationFromCommandLine(CmdL
, VolatileCmdL
, Cache
, verset
, 0))
729 /* Print out a list of packages that are going to be installed extra
730 to what the user asked */
731 SortedPackageUniverse
Universe(Cache
);
732 if (Cache
->InstCount() != verset
[MOD_INSTALL
].size())
733 ShowList(c1out
, _("The following additional packages will be installed:"), Universe
,
734 PkgIsExtraInstalled(&Cache
, &verset
[MOD_INSTALL
]),
735 &PrettyFullName
, CandidateVersion(&Cache
));
737 /* Print out a list of suggested and recommended packages */
739 std::list
<std::string
> Recommends
, Suggests
, SingleRecommends
, SingleSuggests
;
740 for (auto const &Pkg
: Universe
)
742 /* Just look at the ones we want to install */
743 if ((*Cache
)[Pkg
].Install() == false)
746 // get the recommends/suggests for the candidate ver
747 pkgCache::VerIterator CV
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
748 for (pkgCache::DepIterator D
= CV
.DependsList(); D
.end() == false; )
750 pkgCache::DepIterator Start
;
751 pkgCache::DepIterator End
;
752 D
.GlobOr(Start
,End
); // advances D
753 if (Start
->Type
!= pkgCache::Dep::Recommends
&& Start
->Type
!= pkgCache::Dep::Suggests
)
757 // Skip if we already saw this
759 for (pkgCache::DepIterator I
= Start
; I
!= D
; ++I
)
761 if (target
.empty() == false)
762 target
.append(" | ");
763 target
.append(I
.TargetPkg().FullName(true));
765 std::list
<std::string
> &Type
= Start
->Type
== pkgCache::Dep::Recommends
? SingleRecommends
: SingleSuggests
;
766 if (std::find(Type
.begin(), Type
.end(), target
) != Type
.end())
768 Type
.push_back(target
);
771 std::list
<std::string
> OrList
;
772 bool foundInstalledInOrGroup
= false;
773 for (pkgCache::DepIterator I
= Start
; I
!= D
; ++I
)
776 // satisfying package is installed and not marked for deletion
777 APT::VersionList installed
= APT::VersionList::FromDependency(Cache
, I
, APT::CacheSetHelper::INSTALLED
);
778 if (std::find_if(installed
.begin(), installed
.end(),
779 [&Cache
](pkgCache::VerIterator
const &Ver
) { return Cache
[Ver
.ParentPkg()].Delete() == false; }) != installed
.end())
781 foundInstalledInOrGroup
= true;
787 // satisfying package is upgraded to/new install
788 APT::VersionList upgrades
= APT::VersionList::FromDependency(Cache
, I
, APT::CacheSetHelper::CANDIDATE
);
789 if (std::find_if(upgrades
.begin(), upgrades
.end(),
790 [&Cache
](pkgCache::VerIterator
const &Ver
) { return Cache
[Ver
.ParentPkg()].Upgrade(); }) != upgrades
.end())
792 foundInstalledInOrGroup
= true;
798 OrList
.push_back(I
.TargetPkg().FullName(true));
800 OrList
.push_back("| " + I
.TargetPkg().FullName(true));
803 if(foundInstalledInOrGroup
== false)
805 std::list
<std::string
> &Type
= Start
->Type
== pkgCache::Dep::Recommends
? Recommends
: Suggests
;
806 std::move(OrList
.begin(), OrList
.end(), std::back_inserter(Type
));
810 auto always_true
= [](std::string
const&) { return true; };
811 auto string_ident
= [](std::string
const&str
) { return str
; };
812 auto verbose_show_candidate
=
813 [&Cache
](std::string str
)
815 if (APT::String::Startswith(str
, "| "))
817 pkgCache::PkgIterator
const Pkg
= Cache
->FindPkg(str
);
818 if (Pkg
.end() == true)
820 return (*Cache
)[Pkg
].CandVersion
;
822 ShowList(c1out
,_("Suggested packages:"), Suggests
,
823 always_true
, string_ident
, verbose_show_candidate
);
824 ShowList(c1out
,_("Recommended packages:"), Recommends
,
825 always_true
, string_ident
, verbose_show_candidate
);
828 // See if we need to prompt
829 // FIXME: check if really the packages in the set are going to be installed
830 if (Cache
->InstCount() == verset
[MOD_INSTALL
].size() && Cache
->DelCount() == 0)
831 return InstallPackages(Cache
,false,false);
833 return InstallPackages(Cache
,false);
837 // TryToInstall - Mark a package for installation /*{{{*/
838 void TryToInstall::operator() (pkgCache::VerIterator
const &Ver
) {
839 if (unlikely(Ver
.end()))
841 _error
->Fatal("The given version to TryToInstall is invalid!");
844 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
845 if (unlikely(Pkg
.end()))
847 _error
->Fatal("The given version to TryToInstall has an invalid parent package!");
851 Cache
->GetDepCache()->SetCandidateVersion(Ver
);
852 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
854 // Handle the no-upgrade case
855 if (_config
->FindB("APT::Get::upgrade",true) == false && Pkg
->CurrentVer
!= 0)
856 ioprintf(c1out
,_("Skipping %s, it is already installed and upgrade is not set.\n"),
857 Pkg
.FullName(true).c_str());
858 // Ignore request for install if package would be new
859 else if (_config
->FindB("APT::Get::Only-Upgrade", false) == true && Pkg
->CurrentVer
== 0)
860 ioprintf(c1out
,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
861 Pkg
.FullName(true).c_str());
867 Cache
->GetDepCache()->MarkInstall(Pkg
,false);
869 if (State
.Install() == false) {
870 if (_config
->FindB("APT::Get::ReInstall",false) == true) {
871 if (Pkg
->CurrentVer
== 0 || Pkg
.CurrentVer().Downloadable() == false)
872 ioprintf(c1out
,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
873 Pkg
.FullName(true).c_str());
875 Cache
->GetDepCache()->SetReInstall(Pkg
, true);
877 // TRANSLATORS: First string is package name, second is version
878 ioprintf(c1out
,_("%s is already the newest version (%s).\n"),
879 Pkg
.FullName(true).c_str(), Pkg
.CurrentVer().VerStr());
882 // Install it with autoinstalling enabled (if we not respect the minial
883 // required deps or the policy)
884 if (FixBroken
== false)
885 doAutoInstallLater
.insert(Pkg
);
888 // see if we need to fix the auto-mark flag
889 // e.g. apt-get install foo
890 // where foo is marked automatic
891 if (State
.Install() == false &&
892 (State
.Flags
& pkgCache::Flag::Auto
) &&
893 _config
->FindB("APT::Get::ReInstall",false) == false &&
894 _config
->FindB("APT::Get::Only-Upgrade",false) == false &&
895 _config
->FindB("APT::Get::Download-Only",false) == false)
897 ioprintf(c1out
,_("%s set to manually installed.\n"),
898 Pkg
.FullName(true).c_str());
899 Cache
->GetDepCache()->MarkAuto(Pkg
,false);
904 bool TryToInstall::propergateReleaseCandiateSwitching(std::list
<std::pair
<pkgCache::VerIterator
, std::string
> > const &start
, std::ostream
&out
)/*{{{*/
906 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
907 s
!= start
.end(); ++s
)
908 Cache
->GetDepCache()->SetCandidateVersion(s
->first
);
911 // the Changed list contains:
912 // first: "new version"
913 // second: "what-caused the change"
914 std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> > Changed
;
915 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
916 s
!= start
.end(); ++s
)
918 Changed
.push_back(std::make_pair(s
->first
, pkgCache::VerIterator(*Cache
)));
919 // We continue here even if it failed to enhance the ShowBroken output
920 Success
&= Cache
->GetDepCache()->SetCandidateRelease(s
->first
, s
->second
, Changed
);
922 for (std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> >::const_iterator c
= Changed
.begin();
923 c
!= Changed
.end(); ++c
)
925 if (c
->second
.end() == true)
926 ioprintf(out
, _("Selected version '%s' (%s) for '%s'\n"),
927 c
->first
.VerStr(), c
->first
.RelStr().c_str(), c
->first
.ParentPkg().FullName(true).c_str());
928 else if (c
->first
.ParentPkg()->Group
!= c
->second
.ParentPkg()->Group
)
930 pkgCache::VerIterator V
= (*Cache
)[c
->first
.ParentPkg()].CandidateVerIter(*Cache
);
931 ioprintf(out
, _("Selected version '%s' (%s) for '%s' because of '%s'\n"), V
.VerStr(),
932 V
.RelStr().c_str(), V
.ParentPkg().FullName(true).c_str(), c
->second
.ParentPkg().FullName(true).c_str());
938 void TryToInstall::doAutoInstall() { /*{{{*/
939 for (APT::PackageSet::const_iterator P
= doAutoInstallLater
.begin();
940 P
!= doAutoInstallLater
.end(); ++P
) {
941 pkgDepCache::StateCache
&State
= (*Cache
)[P
];
942 if (State
.InstBroken() == false && State
.InstPolicyBroken() == false)
944 Cache
->GetDepCache()->MarkInstall(P
, true);
946 doAutoInstallLater
.clear();
949 // TryToRemove - Mark a package for removal /*{{{*/
950 void TryToRemove::operator() (pkgCache::VerIterator
const &Ver
)
952 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
961 if ((Pkg
->CurrentVer
== 0 && PurgePkgs
== false) ||
962 (PurgePkgs
== true && Pkg
->CurrentState
== pkgCache::State::NotInstalled
))
964 pkgCache::GrpIterator Grp
= Pkg
.Group();
965 pkgCache::PkgIterator P
= Grp
.PackageList();
966 for (; P
.end() != true; P
= Grp
.NextPkg(P
))
970 if (P
->CurrentVer
!= 0 || (PurgePkgs
== true && P
->CurrentState
!= pkgCache::State::NotInstalled
))
972 // TRANSLATORS: Note, this is not an interactive question
973 ioprintf(c1out
,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
974 Pkg
.FullName(true).c_str(), P
.FullName(true).c_str());
979 ioprintf(c1out
,_("Package '%s' is not installed, so not removed\n"),Pkg
.FullName(true).c_str());
981 // MarkInstall refuses to install packages on hold
982 Pkg
->SelectedState
= pkgCache::State::Hold
;
985 Cache
->GetDepCache()->MarkDelete(Pkg
, PurgePkgs
);