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 bool InstallPackages(CacheFile
&Cache
,bool ShwKept
,bool Ask
, bool Safety
)
82 if (_config
->FindB("APT::Get::Purge",false) == true)
84 pkgCache::PkgIterator I
= Cache
->PkgBegin();
85 for (; I
.end() == false; ++I
)
87 if (I
.Purge() == false && Cache
[I
].Mode
== pkgDepCache::ModeDelete
)
88 Cache
->MarkDelete(I
,true);
93 bool Downgrade
= false;
94 bool Essential
= false;
96 // Show all the various warning indicators
100 ShowKept(c1out
,Cache
);
101 Hold
= !ShowHold(c1out
,Cache
);
102 if (_config
->FindB("APT::Get::Show-Upgraded",true) == true)
103 ShowUpgraded(c1out
,Cache
);
104 Downgrade
= !ShowDowngraded(c1out
,Cache
);
106 if (_config
->FindB("APT::Get::Download-Only",false) == false)
107 Essential
= !ShowEssential(c1out
,Cache
);
109 // All kinds of failures
110 bool Fail
= (Essential
|| Downgrade
|| Hold
);
115 if (Cache
->BrokenCount() != 0)
117 ShowBroken(c1out
,Cache
,false);
118 return _error
->Error(_("Internal error, InstallPackages was called with broken packages!"));
121 if (Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
122 Cache
->BadCount() == 0)
126 if (Cache
->DelCount() != 0 && _config
->FindB("APT::Get::Remove",true) == false)
127 return _error
->Error(_("Packages need to be removed but remove is disabled."));
130 if (_config
->FindI("quiet",0) >= 2 ||
131 _config
->FindB("APT::Get::Assume-Yes",false) == true)
133 if (_config
->FindB("APT::Get::Force-Yes",false) == true) {
134 _error
->Warning(_("--force-yes is deprecated, use one of the options starting with --allow instead."));
137 if (Fail
== true && _config
->FindB("APT::Get::Force-Yes",false) == false) {
138 if (Essential
== true && _config
->FindB("APT::Get::allow-remove-essential", false) == false)
139 return _error
->Error(_("Essential packages were removed and -y was used without --allow-remove-essential."));
140 if (Downgrade
== true && _config
->FindB("APT::Get::allow-downgrades", false) == false)
141 return _error
->Error(_("Packages were downgraded and -y was used without --allow-downgrades."));
142 if (Hold
== true && _config
->FindB("APT::Get::allow-change-held-packages", false) == false)
143 return _error
->Error(_("Held packages were changed and -y was used without --allow-change-held-packages."));
147 // Run the simulator ..
148 if (_config
->FindB("APT::Get::Simulate") == true)
150 pkgSimulate
PM(Cache
);
152 APT::Progress::PackageManager
*progress
= APT::Progress::PackageManagerProgressFactory();
153 pkgPackageManager::OrderResult Res
= PM
.DoInstall(progress
);
156 if (Res
== pkgPackageManager::Failed
)
158 if (Res
!= pkgPackageManager::Completed
)
159 return _error
->Error(_("Internal error, Ordering didn't finish"));
163 // Create the text record parser
164 pkgRecords
Recs(Cache
);
165 if (_error
->PendingError() == true)
168 // Create the download object
169 aptAcquireWithTextStatus Fetcher
;
170 if (_config
->FindB("APT::Get::Print-URIs", false) == true)
172 // force a hashsum for compatibility reasons
173 _config
->CndSet("Acquire::ForceHash", "md5sum");
175 else if (Fetcher
.GetLock(_config
->FindDir("Dir::Cache::Archives")) == false)
178 // Read the source list
179 if (Cache
.BuildSourceList() == false)
181 pkgSourceList
*List
= Cache
.GetSourceList();
183 // Create the package manager and prepare to download
184 std::unique_ptr
<pkgPackageManager
> PM(_system
->CreatePM(Cache
));
185 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false ||
186 _error
->PendingError() == true)
189 // Display statistics
190 unsigned long long FetchBytes
= Fetcher
.FetchNeeded();
191 unsigned long long FetchPBytes
= Fetcher
.PartialPresent();
192 unsigned long long DebBytes
= Fetcher
.TotalNeeded();
193 if (DebBytes
!= Cache
->DebSize())
195 c0out
<< DebBytes
<< ',' << Cache
->DebSize() << std::endl
;
196 c0out
<< _("How odd... The sizes didn't match, email apt@packages.debian.org") << std::endl
;
200 if (DebBytes
!= FetchBytes
)
201 //TRANSLATOR: The required space between number and unit is already included
202 // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
203 ioprintf(c1out
,_("Need to get %sB/%sB of archives.\n"),
204 SizeToStr(FetchBytes
).c_str(),SizeToStr(DebBytes
).c_str());
205 else if (DebBytes
!= 0)
206 //TRANSLATOR: The required space between number and unit is already included
207 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
208 ioprintf(c1out
,_("Need to get %sB of archives.\n"),
209 SizeToStr(DebBytes
).c_str());
212 if (Cache
->UsrSize() >= 0)
213 //TRANSLATOR: The required space between number and unit is already included
214 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
215 ioprintf(c1out
,_("After this operation, %sB of additional disk space will be used.\n"),
216 SizeToStr(Cache
->UsrSize()).c_str());
218 //TRANSLATOR: The required space between number and unit is already included
219 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
220 ioprintf(c1out
,_("After this operation, %sB disk space will be freed.\n"),
221 SizeToStr(-1*Cache
->UsrSize()).c_str());
223 if (_error
->PendingError() == true)
226 if (CheckFreeSpaceBeforeDownload(_config
->FindDir("Dir::Cache::Archives"), (FetchBytes
- FetchPBytes
)) == false)
229 if (Essential
== true && Safety
== true && _config
->FindB("APT::Get::allow-remove-essential", false) == false)
231 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
232 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
234 // TRANSLATOR: This string needs to be typed by the user as a confirmation, so be
235 // careful with hard to type or special characters (like non-breaking spaces)
236 const char *Prompt
= _("Yes, do as I say!");
238 _("You are about to do something potentially harmful.\n"
239 "To continue type in the phrase '%s'\n"
242 if (AnalPrompt(Prompt
) == false)
244 c2out
<< _("Abort.") << std::endl
;
250 // Prompt to continue
251 if (Ask
== true || Fail
== true)
253 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
254 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
256 if (_config
->FindI("quiet",0) < 2 &&
257 _config
->FindB("APT::Get::Assume-Yes",false) == false)
259 c2out
<< _("Do you want to continue?") << std::flush
;
260 if (YnPrompt() == false)
262 c2out
<< _("Abort.") << std::endl
;
269 // Just print out the uris an exit if the --print-uris flag was used
270 if (_config
->FindB("APT::Get::Print-URIs") == true)
272 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
273 for (; I
!= Fetcher
.UriEnd(); ++I
)
274 std::cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
275 I
->Owner
->FileSize
<< ' ' << I
->Owner
->HashSum() << std::endl
;
279 if (!CheckAuth(Fetcher
, true))
282 /* Unlock the dpkg lock if we are not going to be doing an install
284 if (_config
->FindB("APT::Get::Download-Only",false) == true)
290 bool Transient
= false;
291 if (_config
->FindB("APT::Get::Download",true) == false)
293 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
< Fetcher
.ItemsEnd();)
295 if ((*I
)->Local
== true)
301 // Close the item and check if it was found in cache
303 if ((*I
)->Complete
== false)
306 // Clear it out of the fetch list
308 I
= Fetcher
.ItemsBegin();
313 if (AcquireRun(Fetcher
, 0, &Failed
, &Transient
) == false)
316 /* If we are in no download mode and missing files and there were
317 'failures' then the user must specify -m. Furthermore, there
318 is no such thing as a transient error in no-download mode! */
319 if (Transient
== true &&
320 _config
->FindB("APT::Get::Download",true) == false)
326 if (_config
->FindB("APT::Get::Download-Only",false) == true)
328 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
329 return _error
->Error(_("Some files failed to download"));
330 c1out
<< _("Download complete and in download only mode") << std::endl
;
334 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
336 return _error
->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
339 if (Transient
== true && Failed
== true)
340 return _error
->Error(_("--fix-missing and media swapping is not currently supported"));
342 // Try to deal with missing package files
343 if (Failed
== true && PM
->FixMissing() == false)
345 c2out
<< _("Unable to correct missing packages.") << std::endl
;
346 return _error
->Error(_("Aborting install."));
351 APT::Progress::PackageManager
*progress
= APT::Progress::PackageManagerProgressFactory();
352 pkgPackageManager::OrderResult Res
= PM
->DoInstall(progress
);
355 if (Res
== pkgPackageManager::Failed
|| _error
->PendingError() == true)
357 if (Res
== pkgPackageManager::Completed
)
360 // Reload the fetcher object and loop again for media swapping
362 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false)
368 std::set
<std::string
> const disappearedPkgs
= PM
->GetDisappearedPackages();
369 if (disappearedPkgs
.empty() == false)
371 ShowList(c1out
, P_("The following package disappeared from your system as\n"
372 "all files have been overwritten by other packages:",
373 "The following packages disappeared from your system as\n"
374 "all files have been overwritten by other packages:", disappearedPkgs
.size()), disappearedPkgs
,
375 [](std::string
const &Pkg
) { return Pkg
.empty() == false; },
376 [](std::string
const &Pkg
) { return Pkg
; },
377 [](std::string
const &) { return std::string(); });
378 c0out
<< _("Note: This is done automatically and on purpose by dpkg.") << std::endl
;
381 // cleanup downloaded debs
382 if (_config
->FindB("APT::Keep-Downloaded-Packages", true) == false)
384 std::string
const archivedir
= _config
->FindDir("Dir::Cache::archives");
385 for (auto I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); ++I
)
387 if (flNotFile((*I
)->DestFile
) != archivedir
|| (*I
)->Local
)
389 RemoveFile("Keep-Downloaded-Packages=false", (*I
)->DestFile
);
396 // DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
397 // ---------------------------------------------------------------------
398 /* Remove unused automatic packages */
399 bool DoAutomaticRemove(CacheFile
&Cache
)
401 bool Debug
= _config
->FindI("Debug::pkgAutoRemove",false);
402 bool doAutoRemove
= _config
->FindB("APT::Get::AutomaticRemove", false);
403 bool hideAutoRemove
= _config
->FindB("APT::Get::HideAutoRemove");
405 pkgDepCache::ActionGroup
group(*Cache
);
407 std::cout
<< "DoAutomaticRemove()" << std::endl
;
409 if (doAutoRemove
== true &&
410 _config
->FindB("APT::Get::Remove",true) == false)
412 c1out
<< _("We are not supposed to delete stuff, can't start "
413 "AutoRemover") << std::endl
;
417 bool purgePkgs
= _config
->FindB("APT::Get::Purge", false);
418 bool smallList
= (hideAutoRemove
== false &&
419 strcasecmp(_config
->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
421 unsigned long autoRemoveCount
= 0;
422 APT::PackageSet tooMuch
;
423 SortedPackageUniverse
Universe(Cache
);
424 // look over the cache to see what can be removed
425 for (auto const &Pkg
: Universe
)
427 if (Cache
[Pkg
].Garbage
)
429 if(Pkg
.CurrentVer() != 0 || Cache
[Pkg
].Install())
431 std::cout
<< "We could delete %s" << Pkg
.FullName(true).c_str() << std::endl
;
435 if(Pkg
.CurrentVer() != 0 &&
436 Pkg
->CurrentState
!= pkgCache::State::ConfigFiles
)
437 Cache
->MarkDelete(Pkg
, purgePkgs
, 0, false);
439 Cache
->MarkKeep(Pkg
, false, false);
443 // if the package is a new install and already garbage we don't need to
444 // install it in the first place, so nuke it instead of show it
445 if (Cache
[Pkg
].Install() == true && Pkg
.CurrentVer() == 0)
448 Cache
->MarkDelete(Pkg
, false, 0, false);
450 // only show stuff in the list that is not yet marked for removal
451 else if(hideAutoRemove
== false && Cache
[Pkg
].Delete() == false)
457 // we could have removed a new dependency of a garbage package,
458 // so check if a reverse depends is broken and if so install it again.
459 if (tooMuch
.empty() == false && (Cache
->BrokenCount() != 0 || Cache
->PolicyBrokenCount() != 0))
464 for (APT::PackageSet::iterator Pkg
= tooMuch
.begin();
465 Pkg
!= tooMuch
.end(); ++Pkg
)
469 for (pkgCache::PrvIterator Prv
= Cache
[Pkg
].CandidateVerIter(Cache
).ProvidesList();
470 Prv
.end() == false; ++Prv
)
471 too
.insert(Prv
.ParentPkg());
472 for (APT::PackageSet::const_iterator P
= too
.begin(); P
!= too
.end(); ++P
)
474 for (pkgCache::DepIterator R
= P
.RevDependsList();
475 R
.end() == false; ++R
)
477 if (R
.IsNegative() == true ||
478 Cache
->IsImportantDep(R
) == false)
480 pkgCache::PkgIterator N
= R
.ParentPkg();
481 if (N
.end() == true || (N
->CurrentVer
== 0 && (*Cache
)[N
].Install() == false))
484 std::clog
<< "Save " << APT::PrettyPkg(Cache
, Pkg
) << " as another installed garbage package depends on it" << std::endl
;
485 Cache
->MarkInstall(Pkg
, false, 0, false);
486 if (hideAutoRemove
== false)
498 } while (Changed
== true);
501 // Now see if we had destroyed anything (if we had done anything)
502 if (Cache
->BrokenCount() != 0)
504 c1out
<< _("Hmm, seems like the AutoRemover destroyed something which really\n"
505 "shouldn't happen. Please file a bug report against apt.") << std::endl
;
507 c1out
<< _("The following information may help to resolve the situation:") << std::endl
;
509 ShowBroken(c1out
,Cache
,false);
511 return _error
->Error(_("Internal Error, AutoRemover broke stuff"));
514 // if we don't remove them, we should show them!
515 if (doAutoRemove
== false && autoRemoveCount
!= 0)
517 if (smallList
== false)
519 SortedPackageUniverse
Universe(Cache
);
520 ShowList(c1out
, P_("The following package was automatically installed and is no longer required:",
521 "The following packages were automatically installed and are no longer required:",
522 autoRemoveCount
), Universe
,
523 [&Cache
](pkgCache::PkgIterator
const &Pkg
) { return (*Cache
)[Pkg
].Garbage
== true && (*Cache
)[Pkg
].Delete() == false; },
524 &PrettyFullName
, CandidateVersion(&Cache
));
527 ioprintf(c1out
, P_("%lu package was automatically installed and is no longer required.\n",
528 "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount
), autoRemoveCount
);
529 std::string autocmd
= "apt autoremove";
530 if (getenv("SUDO_USER") != NULL
)
531 autocmd
= "sudo " + autocmd
;
532 ioprintf(c1out
, P_("Use '%s' to remove it.", "Use '%s' to remove them.", autoRemoveCount
), autocmd
.c_str());
538 // DoCacheManipulationFromCommandLine /*{{{*/
539 static const unsigned short MOD_REMOVE
= 1;
540 static const unsigned short MOD_INSTALL
= 2;
542 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, CacheFile
&Cache
, int UpgradeMode
)
544 std::vector
<const char*> VolatileCmdL
;
545 return DoCacheManipulationFromCommandLine(CmdL
, VolatileCmdL
, Cache
, UpgradeMode
);
547 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, std::vector
<const char*> &VolatileCmdL
, CacheFile
&Cache
, int UpgradeMode
)
549 std::map
<unsigned short, APT::VersionSet
> verset
;
550 return DoCacheManipulationFromCommandLine(CmdL
, VolatileCmdL
, Cache
, verset
, UpgradeMode
);
552 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, std::vector
<const char*> &VolatileCmdL
, CacheFile
&Cache
,
553 std::map
<unsigned short, APT::VersionSet
> &verset
, int UpgradeMode
)
555 // Enter the special broken fixing mode if the user specified arguments
556 bool BrokenFix
= false;
557 if (Cache
->BrokenCount() != 0)
560 std::unique_ptr
<pkgProblemResolver
> Fix(nullptr);
561 if (_config
->FindB("APT::Get::CallResolver", true) == true)
562 Fix
.reset(new pkgProblemResolver(Cache
));
564 unsigned short fallback
= MOD_INSTALL
;
565 if (strcasecmp(CmdL
.FileList
[0],"remove") == 0)
566 fallback
= MOD_REMOVE
;
567 else if (strcasecmp(CmdL
.FileList
[0], "purge") == 0)
569 _config
->Set("APT::Get::Purge", true);
570 fallback
= MOD_REMOVE
;
572 else if (strcasecmp(CmdL
.FileList
[0], "autoremove") == 0 ||
573 strcasecmp(CmdL
.FileList
[0], "auto-remove") == 0)
575 _config
->Set("APT::Get::AutomaticRemove", "true");
576 fallback
= MOD_REMOVE
;
579 std::list
<APT::VersionSet::Modifier
> mods
;
580 mods
.push_back(APT::VersionSet::Modifier(MOD_INSTALL
, "+",
581 APT::VersionSet::Modifier::POSTFIX
, APT::CacheSetHelper::CANDIDATE
));
582 mods
.push_back(APT::VersionSet::Modifier(MOD_REMOVE
, "-",
583 APT::VersionSet::Modifier::POSTFIX
, APT::CacheSetHelper::NEWEST
));
584 CacheSetHelperAPTGet
helper(c0out
);
585 verset
= APT::VersionSet::GroupedFromCommandLine(Cache
,
586 CmdL
.FileList
+ 1, mods
, fallback
, helper
);
588 for (auto const &I
: VolatileCmdL
)
590 pkgCache::PkgIterator
const P
= Cache
->FindPkg(I
);
594 // Set any version providing the .deb as the candidate.
595 for (auto Prv
= P
.ProvidesList(); Prv
.end() == false; Prv
++)
596 Cache
.GetDepCache()->SetCandidateVersion(Prv
.OwnerVer());
598 // via cacheset to have our usual virtual handling
599 APT::VersionContainerInterface::FromPackage(&(verset
[MOD_INSTALL
]), Cache
, P
, APT::CacheSetHelper::CANDIDATE
, helper
);
602 if (_error
->PendingError() == true)
604 helper
.showVirtualPackageErrors(Cache
);
609 TryToInstall
InstallAction(Cache
, Fix
.get(), BrokenFix
);
610 TryToRemove
RemoveAction(Cache
, Fix
.get());
612 // new scope for the ActionGroup
614 pkgDepCache::ActionGroup
group(Cache
);
615 unsigned short const order
[] = { MOD_REMOVE
, MOD_INSTALL
, 0 };
617 for (unsigned short i
= 0; order
[i
] != 0; ++i
)
619 if (order
[i
] == MOD_INSTALL
)
620 InstallAction
= std::for_each(verset
[MOD_INSTALL
].begin(), verset
[MOD_INSTALL
].end(), InstallAction
);
621 else if (order
[i
] == MOD_REMOVE
)
622 RemoveAction
= std::for_each(verset
[MOD_REMOVE
].begin(), verset
[MOD_REMOVE
].end(), RemoveAction
);
625 if (Fix
!= NULL
&& _config
->FindB("APT::Get::AutoSolving", true) == true)
627 InstallAction
.propergateReleaseCandiateSwitching(helper
.selectedByRelease
, c0out
);
628 InstallAction
.doAutoInstall();
631 if (_error
->PendingError() == true)
636 /* If we are in the Broken fixing mode we do not attempt to fix the
637 problems. This is if the user invoked install without -f and gave
639 if (BrokenFix
== true && Cache
->BrokenCount() != 0)
641 c1out
<< _("You might want to run 'apt-get -f install' to correct these:") << std::endl
;
642 ShowBroken(c1out
,Cache
,false);
643 return _error
->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
648 // Call the scored problem resolver
649 OpTextProgress
Progress(*_config
);
650 bool const distUpgradeMode
= strcmp(CmdL
.FileList
[0], "dist-upgrade") == 0 || strcmp(CmdL
.FileList
[0], "full-upgrade") == 0;
652 bool resolver_fail
= false;
653 if (distUpgradeMode
== true || UpgradeMode
!= APT::Upgrade::ALLOW_EVERYTHING
)
654 resolver_fail
= APT::Upgrade::Upgrade(Cache
, UpgradeMode
, &Progress
);
656 resolver_fail
= Fix
->Resolve(true, &Progress
);
658 if (resolver_fail
== false && Cache
->BrokenCount() == 0)
662 if (CheckNothingBroken(Cache
) == false)
665 if (!DoAutomaticRemove(Cache
))
668 // if nothing changed in the cache, but only the automark information
669 // we write the StateFile here, otherwise it will be written in
671 if (InstallAction
.AutoMarkChanged
> 0 &&
672 Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
673 Cache
->BadCount() == 0 &&
674 _config
->FindB("APT::Get::Simulate",false) == false)
675 Cache
->writeStateFile(NULL
);
680 // DoInstall - Install packages from the command line /*{{{*/
681 // ---------------------------------------------------------------------
682 /* Install named packages */
683 struct PkgIsExtraInstalled
{
684 pkgCacheFile
* const Cache
;
685 APT::VersionSet
const * const verset
;
686 PkgIsExtraInstalled(pkgCacheFile
* const Cache
, APT::VersionSet
const * const Container
) : Cache(Cache
), verset(Container
) {}
687 bool operator() (pkgCache::PkgIterator
const &Pkg
)
689 if ((*Cache
)[Pkg
].Install() == false)
691 pkgCache::VerIterator
const Cand
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
692 return verset
->find(Cand
) == verset
->end();
695 bool DoInstall(CommandLine
&CmdL
)
698 std::vector
<char const *> VolatileCmdL
;
699 Cache
.GetSourceList()->AddVolatileFiles(CmdL
, &VolatileCmdL
);
701 // then open the cache
702 if (Cache
.OpenForInstall() == false ||
703 Cache
.CheckDeps(CmdL
.FileSize() != 1) == false)
706 std::map
<unsigned short, APT::VersionSet
> verset
;
707 if(!DoCacheManipulationFromCommandLine(CmdL
, VolatileCmdL
, Cache
, verset
, 0))
710 /* Print out a list of packages that are going to be installed extra
711 to what the user asked */
712 SortedPackageUniverse
Universe(Cache
);
713 if (Cache
->InstCount() != verset
[MOD_INSTALL
].size())
714 ShowList(c1out
, _("The following additional packages will be installed:"), Universe
,
715 PkgIsExtraInstalled(&Cache
, &verset
[MOD_INSTALL
]),
716 &PrettyFullName
, CandidateVersion(&Cache
));
718 /* Print out a list of suggested and recommended packages */
720 std::list
<std::string
> Recommends
, Suggests
, SingleRecommends
, SingleSuggests
;
721 for (auto const &Pkg
: Universe
)
723 /* Just look at the ones we want to install */
724 if ((*Cache
)[Pkg
].Install() == false)
727 // get the recommends/suggests for the candidate ver
728 pkgCache::VerIterator CV
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
729 for (pkgCache::DepIterator D
= CV
.DependsList(); D
.end() == false; )
731 pkgCache::DepIterator Start
;
732 pkgCache::DepIterator End
;
733 D
.GlobOr(Start
,End
); // advances D
734 if (Start
->Type
!= pkgCache::Dep::Recommends
&& Start
->Type
!= pkgCache::Dep::Suggests
)
738 // Skip if we already saw this
740 for (pkgCache::DepIterator I
= Start
; I
!= D
; ++I
)
742 if (target
.empty() == false)
743 target
.append(" | ");
744 target
.append(I
.TargetPkg().FullName(true));
746 std::list
<std::string
> &Type
= Start
->Type
== pkgCache::Dep::Recommends
? SingleRecommends
: SingleSuggests
;
747 if (std::find(Type
.begin(), Type
.end(), target
) != Type
.end())
749 Type
.push_back(target
);
752 std::list
<std::string
> OrList
;
753 bool foundInstalledInOrGroup
= false;
754 for (pkgCache::DepIterator I
= Start
; I
!= D
; ++I
)
757 // satisfying package is installed and not marked for deletion
758 APT::VersionList installed
= APT::VersionList::FromDependency(Cache
, I
, APT::CacheSetHelper::INSTALLED
);
759 if (std::find_if(installed
.begin(), installed
.end(),
760 [&Cache
](pkgCache::VerIterator
const &Ver
) { return Cache
[Ver
.ParentPkg()].Delete() == false; }) != installed
.end())
762 foundInstalledInOrGroup
= true;
768 // satisfying package is upgraded to/new install
769 APT::VersionList upgrades
= APT::VersionList::FromDependency(Cache
, I
, APT::CacheSetHelper::CANDIDATE
);
770 if (std::find_if(upgrades
.begin(), upgrades
.end(),
771 [&Cache
](pkgCache::VerIterator
const &Ver
) { return Cache
[Ver
.ParentPkg()].Upgrade(); }) != upgrades
.end())
773 foundInstalledInOrGroup
= true;
779 OrList
.push_back(I
.TargetPkg().FullName(true));
781 OrList
.push_back("| " + I
.TargetPkg().FullName(true));
784 if(foundInstalledInOrGroup
== false)
786 std::list
<std::string
> &Type
= Start
->Type
== pkgCache::Dep::Recommends
? Recommends
: Suggests
;
787 std::move(OrList
.begin(), OrList
.end(), std::back_inserter(Type
));
791 auto always_true
= [](std::string
const&) { return true; };
792 auto string_ident
= [](std::string
const&str
) { return str
; };
793 auto verbose_show_candidate
=
794 [&Cache
](std::string str
)
796 if (APT::String::Startswith(str
, "| "))
798 pkgCache::PkgIterator
const Pkg
= Cache
->FindPkg(str
);
799 if (Pkg
.end() == true)
801 return (*Cache
)[Pkg
].CandVersion
;
803 ShowList(c1out
,_("Suggested packages:"), Suggests
,
804 always_true
, string_ident
, verbose_show_candidate
);
805 ShowList(c1out
,_("Recommended packages:"), Recommends
,
806 always_true
, string_ident
, verbose_show_candidate
);
809 // See if we need to prompt
810 // FIXME: check if really the packages in the set are going to be installed
811 if (Cache
->InstCount() == verset
[MOD_INSTALL
].size() && Cache
->DelCount() == 0)
812 return InstallPackages(Cache
,false,false);
814 return InstallPackages(Cache
,false);
818 // TryToInstall - Mark a package for installation /*{{{*/
819 void TryToInstall::operator() (pkgCache::VerIterator
const &Ver
) {
820 if (unlikely(Ver
.end()))
822 _error
->Fatal("The given version to TryToInstall is invalid!");
825 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
826 if (unlikely(Pkg
.end()))
828 _error
->Fatal("The given version to TryToInstall has an invalid parent package!");
832 Cache
->GetDepCache()->SetCandidateVersion(Ver
);
833 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
835 // Handle the no-upgrade case
836 if (_config
->FindB("APT::Get::upgrade",true) == false && Pkg
->CurrentVer
!= 0)
837 ioprintf(c1out
,_("Skipping %s, it is already installed and upgrade is not set.\n"),
838 Pkg
.FullName(true).c_str());
839 // Ignore request for install if package would be new
840 else if (_config
->FindB("APT::Get::Only-Upgrade", false) == true && Pkg
->CurrentVer
== 0)
841 ioprintf(c1out
,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
842 Pkg
.FullName(true).c_str());
848 Cache
->GetDepCache()->MarkInstall(Pkg
,false);
850 if (State
.Install() == false) {
851 if (_config
->FindB("APT::Get::ReInstall",false) == true) {
852 if (Pkg
->CurrentVer
== 0 || Pkg
.CurrentVer().Downloadable() == false)
853 ioprintf(c1out
,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
854 Pkg
.FullName(true).c_str());
856 Cache
->GetDepCache()->SetReInstall(Pkg
, true);
858 // TRANSLATORS: First string is package name, second is version
859 ioprintf(c1out
,_("%s is already the newest version (%s).\n"),
860 Pkg
.FullName(true).c_str(), Pkg
.CurrentVer().VerStr());
863 // Install it with autoinstalling enabled (if we not respect the minial
864 // required deps or the policy)
865 if (FixBroken
== false)
866 doAutoInstallLater
.insert(Pkg
);
869 // see if we need to fix the auto-mark flag
870 // e.g. apt-get install foo
871 // where foo is marked automatic
872 if (State
.Install() == false &&
873 (State
.Flags
& pkgCache::Flag::Auto
) &&
874 _config
->FindB("APT::Get::ReInstall",false) == false &&
875 _config
->FindB("APT::Get::Only-Upgrade",false) == false &&
876 _config
->FindB("APT::Get::Download-Only",false) == false)
878 ioprintf(c1out
,_("%s set to manually installed.\n"),
879 Pkg
.FullName(true).c_str());
880 Cache
->GetDepCache()->MarkAuto(Pkg
,false);
885 bool TryToInstall::propergateReleaseCandiateSwitching(std::list
<std::pair
<pkgCache::VerIterator
, std::string
> > const &start
, std::ostream
&out
)/*{{{*/
887 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
888 s
!= start
.end(); ++s
)
889 Cache
->GetDepCache()->SetCandidateVersion(s
->first
);
892 // the Changed list contains:
893 // first: "new version"
894 // second: "what-caused the change"
895 std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> > Changed
;
896 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
897 s
!= start
.end(); ++s
)
899 Changed
.push_back(std::make_pair(s
->first
, pkgCache::VerIterator(*Cache
)));
900 // We continue here even if it failed to enhance the ShowBroken output
901 Success
&= Cache
->GetDepCache()->SetCandidateRelease(s
->first
, s
->second
, Changed
);
903 for (std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> >::const_iterator c
= Changed
.begin();
904 c
!= Changed
.end(); ++c
)
906 if (c
->second
.end() == true)
907 ioprintf(out
, _("Selected version '%s' (%s) for '%s'\n"),
908 c
->first
.VerStr(), c
->first
.RelStr().c_str(), c
->first
.ParentPkg().FullName(true).c_str());
909 else if (c
->first
.ParentPkg()->Group
!= c
->second
.ParentPkg()->Group
)
911 pkgCache::VerIterator V
= (*Cache
)[c
->first
.ParentPkg()].CandidateVerIter(*Cache
);
912 ioprintf(out
, _("Selected version '%s' (%s) for '%s' because of '%s'\n"), V
.VerStr(),
913 V
.RelStr().c_str(), V
.ParentPkg().FullName(true).c_str(), c
->second
.ParentPkg().FullName(true).c_str());
919 void TryToInstall::doAutoInstall() { /*{{{*/
920 for (APT::PackageSet::const_iterator P
= doAutoInstallLater
.begin();
921 P
!= doAutoInstallLater
.end(); ++P
) {
922 pkgDepCache::StateCache
&State
= (*Cache
)[P
];
923 if (State
.InstBroken() == false && State
.InstPolicyBroken() == false)
925 Cache
->GetDepCache()->MarkInstall(P
, true);
927 doAutoInstallLater
.clear();
930 // TryToRemove - Mark a package for removal /*{{{*/
931 void TryToRemove::operator() (pkgCache::VerIterator
const &Ver
)
933 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
942 if ((Pkg
->CurrentVer
== 0 && PurgePkgs
== false) ||
943 (PurgePkgs
== true && Pkg
->CurrentState
== pkgCache::State::NotInstalled
))
945 pkgCache::GrpIterator Grp
= Pkg
.Group();
946 pkgCache::PkgIterator P
= Grp
.PackageList();
947 for (; P
.end() != true; P
= Grp
.NextPkg(P
))
951 if (P
->CurrentVer
!= 0 || (PurgePkgs
== true && P
->CurrentState
!= pkgCache::State::NotInstalled
))
953 // TRANSLATORS: Note, this is not an interactive question
954 ioprintf(c1out
,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
955 Pkg
.FullName(true).c_str(), P
.FullName(true).c_str());
960 ioprintf(c1out
,_("Package '%s' is not installed, so not removed\n"),Pkg
.FullName(true).c_str());
962 // MarkInstall refuses to install packages on hold
963 Pkg
->SelectedState
= pkgCache::State::Hold
;
966 Cache
->GetDepCache()->MarkDelete(Pkg
, PurgePkgs
);