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)
52 _("Some packages could not be installed. This may mean that you have\n"
53 "requested an impossible situation or if you are using the unstable\n"
54 "distribution that some required packages have not yet been created\n"
55 "or been moved out of Incoming.") << std::endl
;
61 _("Since you only requested a single operation it is extremely likely that\n"
62 "the package is simply not installable and a bug report against\n"
63 "that package should be filed.") << std::endl;
67 c1out
<< _("The following information may help to resolve the situation:") << std::endl
;
69 ShowBroken(c1out
,Cache
,false);
70 if (_error
->PendingError() == true)
73 return _error
->Error(_("Broken packages"));
76 // InstallPackages - Actually download and install the packages /*{{{*/
77 // ---------------------------------------------------------------------
78 /* This displays the informative messages describing what is going to
79 happen and then calls the download routines */
80 static void RemoveDownloadNeedingItemsFromFetcher(pkgAcquire
&Fetcher
, bool &Transient
)
82 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
< Fetcher
.ItemsEnd();)
84 if ((*I
)->Local
== true)
90 // Close the item and check if it was found in cache
92 if ((*I
)->Complete
== false)
95 // Clear it out of the fetch list
97 I
= Fetcher
.ItemsBegin();
100 bool InstallPackages(CacheFile
&Cache
,bool ShwKept
,bool Ask
, bool Safety
)
102 if (_config
->FindB("APT::Get::Purge", false) == true)
103 for (pkgCache::PkgIterator I
= Cache
->PkgBegin(); I
.end() == false; ++I
)
104 if (Cache
[I
].Delete() == true && Cache
[I
].Purge() == false)
105 Cache
->MarkDelete(I
,true);
107 // Create the download object
108 aptAcquireWithTextStatus Fetcher
;
109 if (_config
->FindB("APT::Get::Print-URIs", false) == true)
111 // force a hashsum for compatibility reasons
112 _config
->CndSet("Acquire::ForceHash", "md5sum");
114 else if (_config
->FindB("APT::Get::Simulate") == true)
116 else if (Fetcher
.GetLock(_config
->FindDir("Dir::Cache::Archives")) == false)
119 // Read the source list
120 if (Cache
.BuildSourceList() == false)
122 pkgSourceList
* const List
= Cache
.GetSourceList();
124 // Create the text record parser
125 pkgRecords
Recs(Cache
);
126 if (_error
->PendingError() == true)
129 // Create the package manager and prepare to download
130 std::unique_ptr
<pkgPackageManager
> PM(_system
->CreatePM(Cache
));
131 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false ||
132 _error
->PendingError() == true)
135 if (_config
->FindB("APT::Get::Fix-Missing",false) == true &&
136 _config
->FindB("APT::Get::Download",true) == false)
138 bool Missing
= false;
139 RemoveDownloadNeedingItemsFromFetcher(Fetcher
, Missing
);
143 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false ||
144 _error
->PendingError() == true)
148 // Show all the various warning indicators
149 ShowDel(c1out
,Cache
);
150 ShowNew(c1out
,Cache
);
152 ShowKept(c1out
,Cache
);
153 bool const Hold
= !ShowHold(c1out
,Cache
);
154 if (_config
->FindB("APT::Get::Show-Upgraded",true) == true)
155 ShowUpgraded(c1out
,Cache
);
156 bool const Downgrade
= !ShowDowngraded(c1out
,Cache
);
158 bool Essential
= false;
159 if (_config
->FindB("APT::Get::Download-Only",false) == false)
160 Essential
= !ShowEssential(c1out
,Cache
);
165 if (Cache
->BrokenCount() != 0)
167 ShowBroken(c1out
,Cache
,false);
168 return _error
->Error(_("Internal error, InstallPackages was called with broken packages!"));
171 if (Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
172 Cache
->BadCount() == 0)
176 if (Cache
->DelCount() != 0 && _config
->FindB("APT::Get::Remove",true) == false)
177 return _error
->Error(_("Packages need to be removed but remove is disabled."));
180 bool const Fail
= (Essential
|| Downgrade
|| Hold
);
181 if (_config
->FindI("quiet",0) >= 2 ||
182 _config
->FindB("APT::Get::Assume-Yes",false) == true)
184 if (_config
->FindB("APT::Get::Force-Yes",false) == true) {
185 _error
->Warning(_("--force-yes is deprecated, use one of the options starting with --allow instead."));
188 if (Fail
== true && _config
->FindB("APT::Get::Force-Yes",false) == false) {
189 if (Essential
== true && _config
->FindB("APT::Get::allow-remove-essential", false) == false)
190 return _error
->Error(_("Essential packages were removed and -y was used without --allow-remove-essential."));
191 if (Downgrade
== true && _config
->FindB("APT::Get::allow-downgrades", false) == false)
192 return _error
->Error(_("Packages were downgraded and -y was used without --allow-downgrades."));
193 if (Hold
== true && _config
->FindB("APT::Get::allow-change-held-packages", false) == false)
194 return _error
->Error(_("Held packages were changed and -y was used without --allow-change-held-packages."));
198 // Run the simulator ..
199 if (_config
->FindB("APT::Get::Simulate") == true)
201 pkgSimulate
PM(Cache
);
203 APT::Progress::PackageManager
*progress
= APT::Progress::PackageManagerProgressFactory();
204 pkgPackageManager::OrderResult Res
= PM
.DoInstall(progress
);
207 if (Res
== pkgPackageManager::Failed
)
209 if (Res
!= pkgPackageManager::Completed
)
210 return _error
->Error(_("Internal error, Ordering didn't finish"));
214 // Display statistics
215 auto const FetchBytes
= Fetcher
.FetchNeeded();
216 auto const FetchPBytes
= Fetcher
.PartialPresent();
217 auto const DebBytes
= Fetcher
.TotalNeeded();
218 if (DebBytes
!= Cache
->DebSize())
220 c0out
<< DebBytes
<< ',' << Cache
->DebSize() << std::endl
;
221 c0out
<< _("How odd... The sizes didn't match, email apt@packages.debian.org") << std::endl
;
225 if (DebBytes
!= FetchBytes
)
226 //TRANSLATOR: The required space between number and unit is already included
227 // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
228 ioprintf(c1out
,_("Need to get %sB/%sB of archives.\n"),
229 SizeToStr(FetchBytes
).c_str(),SizeToStr(DebBytes
).c_str());
230 else if (DebBytes
!= 0)
231 //TRANSLATOR: The required space between number and unit is already included
232 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
233 ioprintf(c1out
,_("Need to get %sB of archives.\n"),
234 SizeToStr(DebBytes
).c_str());
237 if (Cache
->UsrSize() >= 0)
238 //TRANSLATOR: The required space between number and unit is already included
239 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
240 ioprintf(c1out
,_("After this operation, %sB of additional disk space will be used.\n"),
241 SizeToStr(Cache
->UsrSize()).c_str());
243 //TRANSLATOR: The required space between number and unit is already included
244 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
245 ioprintf(c1out
,_("After this operation, %sB disk space will be freed.\n"),
246 SizeToStr(-1*Cache
->UsrSize()).c_str());
248 if (CheckFreeSpaceBeforeDownload(_config
->FindDir("Dir::Cache::Archives"), (FetchBytes
- FetchPBytes
)) == false)
251 if (_error
->PendingError() == true)
254 // Just print out the uris an exit if the --print-uris flag was used
255 if (_config
->FindB("APT::Get::Print-URIs") == true)
257 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
258 for (; I
!= Fetcher
.UriEnd(); ++I
)
259 std::cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
260 std::to_string(I
->Owner
->FileSize
) << ' ' << I
->Owner
->HashSum() << std::endl
;
264 if (Essential
== true && Safety
== true && _config
->FindB("APT::Get::allow-remove-essential", false) == false)
266 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
267 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
269 // TRANSLATOR: This string needs to be typed by the user as a confirmation, so be
270 // careful with hard to type or special characters (like non-breaking spaces)
271 const char *Prompt
= _("Yes, do as I say!");
272 std::string question
;
274 _("You are about to do something potentially harmful.\n"
275 "To continue type in the phrase '%s'\n"
277 if (AnalPrompt(question
, Prompt
) == false)
279 c2out
<< _("Abort.") << std::endl
;
285 // Prompt to continue
286 if (Ask
== true || Fail
== true)
288 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
289 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
291 if (_config
->FindI("quiet",0) < 2 &&
292 _config
->FindB("APT::Get::Assume-Yes",false) == false)
294 if (YnPrompt(_("Do you want to continue?")) == false)
296 c2out
<< _("Abort.") << std::endl
;
303 if (!CheckAuth(Fetcher
, true))
306 /* Unlock the dpkg lock if we are not going to be doing an install
308 if (_config
->FindB("APT::Get::Download-Only",false) == true)
315 bool Transient
= false;
316 if (AcquireRun(Fetcher
, 0, &Failed
, &Transient
) == false)
319 if (_config
->FindB("APT::Get::Download-Only",false) == true)
321 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
322 return _error
->Error(_("Some files failed to download"));
323 c1out
<< _("Download complete and in download only mode") << std::endl
;
327 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
328 return _error
->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
330 if (Transient
== true && Failed
== true)
331 return _error
->Error(_("--fix-missing and media swapping is not currently supported"));
333 // Try to deal with missing package files
334 if (Failed
== true && PM
->FixMissing() == false)
336 c2out
<< _("Unable to correct missing packages.") << std::endl
;
337 return _error
->Error(_("Aborting install."));
340 auto const progress
= APT::Progress::PackageManagerProgressFactory();
342 pkgPackageManager::OrderResult
const Res
= PM
->DoInstall(progress
);
345 if (Res
== pkgPackageManager::Failed
|| _error
->PendingError() == true)
347 if (Res
== pkgPackageManager::Completed
)
352 // Reload the fetcher object and loop again for media swapping
354 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false)
358 if (_config
->FindB("APT::Get::Download",true) == false)
359 RemoveDownloadNeedingItemsFromFetcher(Fetcher
, Failed
);
362 std::set
<std::string
> const disappearedPkgs
= PM
->GetDisappearedPackages();
363 if (disappearedPkgs
.empty() == false)
365 ShowList(c1out
, P_("The following package disappeared from your system as\n"
366 "all files have been overwritten by other packages:",
367 "The following packages disappeared from your system as\n"
368 "all files have been overwritten by other packages:", disappearedPkgs
.size()), disappearedPkgs
,
369 [](std::string
const &Pkg
) { return Pkg
.empty() == false; },
370 [](std::string
const &Pkg
) { return Pkg
; },
371 [](std::string
const &) { return std::string(); });
372 c0out
<< _("Note: This is done automatically and on purpose by dpkg.") << std::endl
;
375 // cleanup downloaded debs
376 if (_config
->FindB("APT::Keep-Downloaded-Packages", true) == false)
378 std::string
const archivedir
= _config
->FindDir("Dir::Cache::archives");
379 for (auto I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); ++I
)
381 if (flNotFile((*I
)->DestFile
) != archivedir
|| (*I
)->Local
)
383 RemoveFile("Keep-Downloaded-Packages=false", (*I
)->DestFile
);
390 // DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
391 // ---------------------------------------------------------------------
392 /* Remove unused automatic packages */
393 bool DoAutomaticRemove(CacheFile
&Cache
)
395 bool Debug
= _config
->FindI("Debug::pkgAutoRemove",false);
396 bool doAutoRemove
= _config
->FindB("APT::Get::AutomaticRemove", false);
397 bool hideAutoRemove
= _config
->FindB("APT::Get::HideAutoRemove");
399 pkgDepCache::ActionGroup
group(*Cache
);
401 std::cout
<< "DoAutomaticRemove()" << std::endl
;
403 if (doAutoRemove
== true &&
404 _config
->FindB("APT::Get::Remove",true) == false)
406 c1out
<< _("We are not supposed to delete stuff, can't start "
407 "AutoRemover") << std::endl
;
411 bool purgePkgs
= _config
->FindB("APT::Get::Purge", false);
412 bool smallList
= (hideAutoRemove
== false &&
413 strcasecmp(_config
->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
415 unsigned long autoRemoveCount
= 0;
416 APT::PackageSet tooMuch
;
417 SortedPackageUniverse
Universe(Cache
);
418 // look over the cache to see what can be removed
419 for (auto const &Pkg
: Universe
)
421 if (Cache
[Pkg
].Garbage
)
423 if(Pkg
.CurrentVer() != 0 || Cache
[Pkg
].Install())
425 std::cout
<< "We could delete %s" << Pkg
.FullName(true).c_str() << std::endl
;
429 if(Pkg
.CurrentVer() != 0 &&
430 Pkg
->CurrentState
!= pkgCache::State::ConfigFiles
)
431 Cache
->MarkDelete(Pkg
, purgePkgs
, 0, false);
433 Cache
->MarkKeep(Pkg
, false, false);
437 // if the package is a new install and already garbage we don't need to
438 // install it in the first place, so nuke it instead of show it
439 if (Cache
[Pkg
].Install() == true && Pkg
.CurrentVer() == 0)
442 Cache
->MarkDelete(Pkg
, false, 0, false);
444 // only show stuff in the list that is not yet marked for removal
445 else if(hideAutoRemove
== false && Cache
[Pkg
].Delete() == false)
451 // we could have removed a new dependency of a garbage package,
452 // so check if a reverse depends is broken and if so install it again.
453 if (tooMuch
.empty() == false && (Cache
->BrokenCount() != 0 || Cache
->PolicyBrokenCount() != 0))
458 for (APT::PackageSet::iterator Pkg
= tooMuch
.begin();
459 Pkg
!= tooMuch
.end(); ++Pkg
)
463 for (pkgCache::PrvIterator Prv
= Cache
[Pkg
].CandidateVerIter(Cache
).ProvidesList();
464 Prv
.end() == false; ++Prv
)
465 too
.insert(Prv
.ParentPkg());
466 for (APT::PackageSet::const_iterator P
= too
.begin(); P
!= too
.end(); ++P
)
468 for (pkgCache::DepIterator R
= P
.RevDependsList();
469 R
.end() == false; ++R
)
471 if (R
.IsNegative() == true ||
472 Cache
->IsImportantDep(R
) == false)
474 pkgCache::PkgIterator N
= R
.ParentPkg();
475 if (N
.end() == true || (N
->CurrentVer
== 0 && (*Cache
)[N
].Install() == false))
478 std::clog
<< "Save " << APT::PrettyPkg(Cache
, Pkg
) << " as another installed garbage package depends on it" << std::endl
;
479 Cache
->MarkInstall(Pkg
, false, 0, false);
480 if (hideAutoRemove
== false)
492 } while (Changed
== true);
495 // Now see if we had destroyed anything (if we had done anything)
496 if (Cache
->BrokenCount() != 0)
498 c1out
<< _("Hmm, seems like the AutoRemover destroyed something which really\n"
499 "shouldn't happen. Please file a bug report against apt.") << std::endl
;
501 c1out
<< _("The following information may help to resolve the situation:") << std::endl
;
503 ShowBroken(c1out
,Cache
,false);
505 return _error
->Error(_("Internal Error, AutoRemover broke stuff"));
508 // if we don't remove them, we should show them!
509 if (doAutoRemove
== false && autoRemoveCount
!= 0)
511 if (smallList
== false)
513 SortedPackageUniverse
Universe(Cache
);
514 ShowList(c1out
, P_("The following package was automatically installed and is no longer required:",
515 "The following packages were automatically installed and are no longer required:",
516 autoRemoveCount
), Universe
,
517 [&Cache
](pkgCache::PkgIterator
const &Pkg
) { return (*Cache
)[Pkg
].Garbage
== true && (*Cache
)[Pkg
].Delete() == false; },
518 &PrettyFullName
, CandidateVersion(&Cache
));
521 ioprintf(c1out
, P_("%lu package was automatically installed and is no longer required.\n",
522 "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount
), autoRemoveCount
);
523 std::string autocmd
= "apt autoremove";
524 if (getenv("SUDO_USER") != nullptr)
526 auto const envsudocmd
= getenv("SUDO_COMMAND");
527 auto const envshell
= getenv("SHELL");
528 if (envsudocmd
== nullptr || envshell
== nullptr || strcmp(envsudocmd
, envshell
) != 0)
529 autocmd
= "sudo " + autocmd
;
531 ioprintf(c1out
, P_("Use '%s' to remove it.", "Use '%s' to remove them.", autoRemoveCount
), autocmd
.c_str());
537 // DoCacheManipulationFromCommandLine /*{{{*/
538 static const unsigned short MOD_REMOVE
= 1;
539 static const unsigned short MOD_INSTALL
= 2;
541 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, CacheFile
&Cache
, int UpgradeMode
)
543 std::vector
<std::string
> VolatileCmdL
;
544 return DoCacheManipulationFromCommandLine(CmdL
, VolatileCmdL
, Cache
, UpgradeMode
);
546 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, std::vector
<std::string
> &VolatileCmdL
, CacheFile
&Cache
, int UpgradeMode
)
548 std::map
<unsigned short, APT::VersionSet
> verset
;
549 return DoCacheManipulationFromCommandLine(CmdL
, VolatileCmdL
, Cache
, verset
, UpgradeMode
);
551 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, std::vector
<std::string
> &VolatileCmdL
, CacheFile
&Cache
,
552 std::map
<unsigned short, APT::VersionSet
> &verset
, int UpgradeMode
)
554 // Enter the special broken fixing mode if the user specified arguments
555 bool BrokenFix
= false;
556 if (Cache
->BrokenCount() != 0)
559 std::unique_ptr
<pkgProblemResolver
> Fix(nullptr);
560 if (_config
->FindB("APT::Get::CallResolver", true) == true)
561 Fix
.reset(new pkgProblemResolver(Cache
));
563 unsigned short fallback
= MOD_INSTALL
;
564 if (strcasecmp(CmdL
.FileList
[0],"remove") == 0)
565 fallback
= MOD_REMOVE
;
566 else if (strcasecmp(CmdL
.FileList
[0], "purge") == 0)
568 _config
->Set("APT::Get::Purge", true);
569 fallback
= MOD_REMOVE
;
571 else if (strcasecmp(CmdL
.FileList
[0], "autoremove") == 0 ||
572 strcasecmp(CmdL
.FileList
[0], "auto-remove") == 0)
574 _config
->Set("APT::Get::AutomaticRemove", "true");
575 fallback
= MOD_REMOVE
;
578 std::list
<APT::VersionSet::Modifier
> mods
;
579 mods
.push_back(APT::VersionSet::Modifier(MOD_INSTALL
, "+",
580 APT::VersionSet::Modifier::POSTFIX
, APT::CacheSetHelper::CANDIDATE
));
581 mods
.push_back(APT::VersionSet::Modifier(MOD_REMOVE
, "-",
582 APT::VersionSet::Modifier::POSTFIX
, APT::CacheSetHelper::NEWEST
));
583 CacheSetHelperAPTGet
helper(c0out
);
584 verset
= APT::VersionSet::GroupedFromCommandLine(Cache
,
585 CmdL
.FileList
+ 1, mods
, fallback
, helper
);
587 for (auto const &I
: VolatileCmdL
)
589 pkgCache::PkgIterator
const P
= Cache
->FindPkg(I
);
593 // Set any version providing the .deb as the candidate.
594 for (auto Prv
= P
.ProvidesList(); Prv
.end() == false; Prv
++)
595 Cache
.GetDepCache()->SetCandidateVersion(Prv
.OwnerVer());
597 // via cacheset to have our usual virtual handling
598 APT::VersionContainerInterface::FromPackage(&(verset
[MOD_INSTALL
]), Cache
, P
, APT::CacheSetHelper::CANDIDATE
, helper
);
601 if (_error
->PendingError() == true)
603 helper
.showVirtualPackageErrors(Cache
);
608 TryToInstall
InstallAction(Cache
, Fix
.get(), BrokenFix
);
609 TryToRemove
RemoveAction(Cache
, Fix
.get());
611 // new scope for the ActionGroup
613 pkgDepCache::ActionGroup
group(Cache
);
614 unsigned short const order
[] = { MOD_REMOVE
, MOD_INSTALL
, 0 };
616 for (unsigned short i
= 0; order
[i
] != 0; ++i
)
618 if (order
[i
] == MOD_INSTALL
)
619 InstallAction
= std::for_each(verset
[MOD_INSTALL
].begin(), verset
[MOD_INSTALL
].end(), InstallAction
);
620 else if (order
[i
] == MOD_REMOVE
)
621 RemoveAction
= std::for_each(verset
[MOD_REMOVE
].begin(), verset
[MOD_REMOVE
].end(), RemoveAction
);
624 if (Fix
!= NULL
&& _config
->FindB("APT::Get::AutoSolving", true) == true)
626 InstallAction
.propergateReleaseCandiateSwitching(helper
.selectedByRelease
, c0out
);
627 InstallAction
.doAutoInstall();
630 if (_error
->PendingError() == true)
635 /* If we are in the Broken fixing mode we do not attempt to fix the
636 problems. This is if the user invoked install without -f and gave
638 if (BrokenFix
== true && Cache
->BrokenCount() != 0)
640 c1out
<< _("You might want to run 'apt-get -f install' to correct these:") << std::endl
;
641 ShowBroken(c1out
,Cache
,false);
642 return _error
->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
647 // Call the scored problem resolver
648 OpTextProgress
Progress(*_config
);
649 bool const distUpgradeMode
= strcmp(CmdL
.FileList
[0], "dist-upgrade") == 0 || strcmp(CmdL
.FileList
[0], "full-upgrade") == 0;
651 bool resolver_fail
= false;
652 if (distUpgradeMode
== true || UpgradeMode
!= APT::Upgrade::ALLOW_EVERYTHING
)
653 resolver_fail
= APT::Upgrade::Upgrade(Cache
, UpgradeMode
, &Progress
);
655 resolver_fail
= Fix
->Resolve(true, &Progress
);
657 if (resolver_fail
== false && Cache
->BrokenCount() == 0)
661 if (CheckNothingBroken(Cache
) == false)
664 if (!DoAutomaticRemove(Cache
))
667 // if nothing changed in the cache, but only the automark information
668 // we write the StateFile here, otherwise it will be written in
670 if (InstallAction
.AutoMarkChanged
> 0 &&
671 Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
672 Cache
->BadCount() == 0 &&
673 _config
->FindB("APT::Get::Simulate",false) == false)
674 Cache
->writeStateFile(NULL
);
679 // DoInstall - Install packages from the command line /*{{{*/
680 // ---------------------------------------------------------------------
681 /* Install named packages */
682 struct PkgIsExtraInstalled
{
683 pkgCacheFile
* const Cache
;
684 APT::VersionSet
const * const verset
;
685 PkgIsExtraInstalled(pkgCacheFile
* const Cache
, APT::VersionSet
const * const Container
) : Cache(Cache
), verset(Container
) {}
686 bool operator() (pkgCache::PkgIterator
const &Pkg
)
688 if ((*Cache
)[Pkg
].Install() == false)
690 pkgCache::VerIterator
const Cand
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
691 return verset
->find(Cand
) == verset
->end();
694 bool DoInstall(CommandLine
&CmdL
)
697 std::vector
<std::string
> VolatileCmdL
;
698 Cache
.GetSourceList()->AddVolatileFiles(CmdL
, &VolatileCmdL
);
700 // then open the cache
701 if (Cache
.OpenForInstall() == false ||
702 Cache
.CheckDeps(CmdL
.FileSize() != 1) == false)
705 std::map
<unsigned short, APT::VersionSet
> verset
;
706 if(!DoCacheManipulationFromCommandLine(CmdL
, VolatileCmdL
, Cache
, verset
, 0))
709 /* Print out a list of packages that are going to be installed extra
710 to what the user asked */
711 SortedPackageUniverse
Universe(Cache
);
712 if (Cache
->InstCount() != verset
[MOD_INSTALL
].size())
713 ShowList(c1out
, _("The following additional packages will be installed:"), Universe
,
714 PkgIsExtraInstalled(&Cache
, &verset
[MOD_INSTALL
]),
715 &PrettyFullName
, CandidateVersion(&Cache
));
717 /* Print out a list of suggested and recommended packages */
719 std::list
<std::string
> Recommends
, Suggests
, SingleRecommends
, SingleSuggests
;
720 for (auto const &Pkg
: Universe
)
722 /* Just look at the ones we want to install */
723 if ((*Cache
)[Pkg
].Install() == false)
726 // get the recommends/suggests for the candidate ver
727 pkgCache::VerIterator CV
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
728 for (pkgCache::DepIterator D
= CV
.DependsList(); D
.end() == false; )
730 pkgCache::DepIterator Start
;
731 pkgCache::DepIterator End
;
732 D
.GlobOr(Start
,End
); // advances D
733 if (Start
->Type
!= pkgCache::Dep::Recommends
&& Start
->Type
!= pkgCache::Dep::Suggests
)
737 // Skip if we already saw this
739 for (pkgCache::DepIterator I
= Start
; I
!= D
; ++I
)
741 if (target
.empty() == false)
742 target
.append(" | ");
743 target
.append(I
.TargetPkg().FullName(true));
745 std::list
<std::string
> &Type
= Start
->Type
== pkgCache::Dep::Recommends
? SingleRecommends
: SingleSuggests
;
746 if (std::find(Type
.begin(), Type
.end(), target
) != Type
.end())
748 Type
.push_back(target
);
751 std::list
<std::string
> OrList
;
752 bool foundInstalledInOrGroup
= false;
753 for (pkgCache::DepIterator I
= Start
; I
!= D
; ++I
)
756 // satisfying package is installed and not marked for deletion
757 APT::VersionList installed
= APT::VersionList::FromDependency(Cache
, I
, APT::CacheSetHelper::INSTALLED
);
758 if (std::find_if(installed
.begin(), installed
.end(),
759 [&Cache
](pkgCache::VerIterator
const &Ver
) { return Cache
[Ver
.ParentPkg()].Delete() == false; }) != installed
.end())
761 foundInstalledInOrGroup
= true;
767 // satisfying package is upgraded to/new install
768 APT::VersionList upgrades
= APT::VersionList::FromDependency(Cache
, I
, APT::CacheSetHelper::CANDIDATE
);
769 if (std::find_if(upgrades
.begin(), upgrades
.end(),
770 [&Cache
](pkgCache::VerIterator
const &Ver
) { return Cache
[Ver
.ParentPkg()].Upgrade(); }) != upgrades
.end())
772 foundInstalledInOrGroup
= true;
778 OrList
.push_back(I
.TargetPkg().FullName(true));
780 OrList
.push_back("| " + I
.TargetPkg().FullName(true));
783 if(foundInstalledInOrGroup
== false)
785 std::list
<std::string
> &Type
= Start
->Type
== pkgCache::Dep::Recommends
? Recommends
: Suggests
;
786 std::move(OrList
.begin(), OrList
.end(), std::back_inserter(Type
));
790 auto always_true
= [](std::string
const&) { return true; };
791 auto string_ident
= [](std::string
const&str
) { return str
; };
792 auto verbose_show_candidate
=
793 [&Cache
](std::string str
)
795 if (APT::String::Startswith(str
, "| "))
797 pkgCache::PkgIterator
const Pkg
= Cache
->FindPkg(str
);
798 if (Pkg
.end() == true)
800 return (*Cache
)[Pkg
].CandVersion
;
802 ShowList(c1out
,_("Suggested packages:"), Suggests
,
803 always_true
, string_ident
, verbose_show_candidate
);
804 ShowList(c1out
,_("Recommended packages:"), Recommends
,
805 always_true
, string_ident
, verbose_show_candidate
);
808 // See if we need to prompt
809 // FIXME: check if really the packages in the set are going to be installed
810 if (Cache
->InstCount() == verset
[MOD_INSTALL
].size() && Cache
->DelCount() == 0)
811 return InstallPackages(Cache
,false,false);
813 return InstallPackages(Cache
,false);
817 // TryToInstall - Mark a package for installation /*{{{*/
818 void TryToInstall::operator() (pkgCache::VerIterator
const &Ver
) {
819 if (unlikely(Ver
.end()))
821 _error
->Fatal("The given version to TryToInstall is invalid!");
824 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
825 if (unlikely(Pkg
.end()))
827 _error
->Fatal("The given version to TryToInstall has an invalid parent package!");
831 Cache
->GetDepCache()->SetCandidateVersion(Ver
);
832 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
834 // Handle the no-upgrade case
835 if (_config
->FindB("APT::Get::upgrade",true) == false && Pkg
->CurrentVer
!= 0)
836 ioprintf(c1out
,_("Skipping %s, it is already installed and upgrade is not set.\n"),
837 Pkg
.FullName(true).c_str());
838 // Ignore request for install if package would be new
839 else if (_config
->FindB("APT::Get::Only-Upgrade", false) == true && Pkg
->CurrentVer
== 0)
840 ioprintf(c1out
,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
841 Pkg
.FullName(true).c_str());
847 Cache
->GetDepCache()->MarkInstall(Pkg
,false);
849 if (State
.Install() == false) {
850 if (_config
->FindB("APT::Get::ReInstall",false) == true) {
851 if (Pkg
->CurrentVer
== 0 || Pkg
.CurrentVer().Downloadable() == false)
852 ioprintf(c1out
,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
853 Pkg
.FullName(true).c_str());
855 Cache
->GetDepCache()->SetReInstall(Pkg
, true);
857 // TRANSLATORS: First string is package name, second is version
858 ioprintf(c1out
,_("%s is already the newest version (%s).\n"),
859 Pkg
.FullName(true).c_str(), Pkg
.CurrentVer().VerStr());
862 // Install it with autoinstalling enabled (if we not respect the minial
863 // required deps or the policy)
864 if (FixBroken
== false)
865 doAutoInstallLater
.insert(Pkg
);
868 // see if we need to fix the auto-mark flag
869 // e.g. apt-get install foo
870 // where foo is marked automatic
871 if (State
.Install() == false &&
872 (State
.Flags
& pkgCache::Flag::Auto
) &&
873 _config
->FindB("APT::Get::ReInstall",false) == false &&
874 _config
->FindB("APT::Get::Only-Upgrade",false) == false &&
875 _config
->FindB("APT::Get::Download-Only",false) == false)
877 ioprintf(c1out
,_("%s set to manually installed.\n"),
878 Pkg
.FullName(true).c_str());
879 Cache
->GetDepCache()->MarkAuto(Pkg
,false);
884 bool TryToInstall::propergateReleaseCandiateSwitching(std::list
<std::pair
<pkgCache::VerIterator
, std::string
> > const &start
, std::ostream
&out
)/*{{{*/
886 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
887 s
!= start
.end(); ++s
)
888 Cache
->GetDepCache()->SetCandidateVersion(s
->first
);
891 // the Changed list contains:
892 // first: "new version"
893 // second: "what-caused the change"
894 std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> > Changed
;
895 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
896 s
!= start
.end(); ++s
)
898 Changed
.push_back(std::make_pair(s
->first
, pkgCache::VerIterator(*Cache
)));
899 // We continue here even if it failed to enhance the ShowBroken output
900 Success
&= Cache
->GetDepCache()->SetCandidateRelease(s
->first
, s
->second
, Changed
);
902 for (std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> >::const_iterator c
= Changed
.begin();
903 c
!= Changed
.end(); ++c
)
905 if (c
->second
.end() == true)
906 ioprintf(out
, _("Selected version '%s' (%s) for '%s'\n"),
907 c
->first
.VerStr(), c
->first
.RelStr().c_str(), c
->first
.ParentPkg().FullName(true).c_str());
908 else if (c
->first
.ParentPkg()->Group
!= c
->second
.ParentPkg()->Group
)
910 pkgCache::VerIterator V
= (*Cache
)[c
->first
.ParentPkg()].CandidateVerIter(*Cache
);
911 ioprintf(out
, _("Selected version '%s' (%s) for '%s' because of '%s'\n"), V
.VerStr(),
912 V
.RelStr().c_str(), V
.ParentPkg().FullName(true).c_str(), c
->second
.ParentPkg().FullName(true).c_str());
918 void TryToInstall::doAutoInstall() { /*{{{*/
919 for (APT::PackageSet::const_iterator P
= doAutoInstallLater
.begin();
920 P
!= doAutoInstallLater
.end(); ++P
) {
921 pkgDepCache::StateCache
&State
= (*Cache
)[P
];
922 if (State
.InstBroken() == false && State
.InstPolicyBroken() == false)
924 Cache
->GetDepCache()->MarkInstall(P
, true);
926 doAutoInstallLater
.clear();
929 // TryToRemove - Mark a package for removal /*{{{*/
930 void TryToRemove::operator() (pkgCache::VerIterator
const &Ver
)
932 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
941 if ((Pkg
->CurrentVer
== 0 && PurgePkgs
== false) ||
942 (PurgePkgs
== true && Pkg
->CurrentState
== pkgCache::State::NotInstalled
))
944 pkgCache::GrpIterator Grp
= Pkg
.Group();
945 pkgCache::PkgIterator P
= Grp
.PackageList();
946 for (; P
.end() != true; P
= Grp
.NextPkg(P
))
950 if (P
->CurrentVer
!= 0 || (PurgePkgs
== true && P
->CurrentState
!= pkgCache::State::NotInstalled
))
952 // TRANSLATORS: Note, this is not an interactive question
953 ioprintf(c1out
,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
954 Pkg
.FullName(true).c_str(), P
.FullName(true).c_str());
959 ioprintf(c1out
,_("Package '%s' is not installed, so not removed\n"),Pkg
.FullName(true).c_str());
961 // MarkInstall refuses to install packages on hold
962 Pkg
->SelectedState
= pkgCache::State::Hold
;
965 Cache
->GetDepCache()->MarkDelete(Pkg
, PurgePkgs
);