]>
git.saurik.com Git - apt.git/blob - apt-private/private-install.cc
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/debindexfile.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 // InstallPackages - Actually download and install the packages /*{{{*/
46 // ---------------------------------------------------------------------
47 /* This displays the informative messages describing what is going to
48 happen and then calls the download routines */
49 bool InstallPackages(CacheFile
&Cache
,bool ShwKept
,bool Ask
, bool Safety
)
51 if (_config
->FindB("APT::Get::Purge",false) == true)
53 pkgCache::PkgIterator I
= Cache
->PkgBegin();
54 for (; I
.end() == false; ++I
)
56 if (I
.Purge() == false && Cache
[I
].Mode
== pkgDepCache::ModeDelete
)
57 Cache
->MarkDelete(I
,true);
62 bool Essential
= false;
64 // Show all the various warning indicators
68 ShowKept(c1out
,Cache
);
69 Fail
|= !ShowHold(c1out
,Cache
);
70 if (_config
->FindB("APT::Get::Show-Upgraded",true) == true)
71 ShowUpgraded(c1out
,Cache
);
72 Fail
|= !ShowDowngraded(c1out
,Cache
);
73 if (_config
->FindB("APT::Get::Download-Only",false) == false)
74 Essential
= !ShowEssential(c1out
,Cache
);
79 if (Cache
->BrokenCount() != 0)
81 ShowBroken(c1out
,Cache
,false);
82 return _error
->Error(_("Internal error, InstallPackages was called with broken packages!"));
85 if (Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
86 Cache
->BadCount() == 0)
90 if (Cache
->DelCount() != 0 && _config
->FindB("APT::Get::Remove",true) == false)
91 return _error
->Error(_("Packages need to be removed but remove is disabled."));
93 // Run the simulator ..
94 if (_config
->FindB("APT::Get::Simulate") == true)
96 pkgSimulate
PM(Cache
);
98 APT::Progress::PackageManager
*progress
= APT::Progress::PackageManagerProgressFactory();
99 pkgPackageManager::OrderResult Res
= PM
.DoInstall(progress
);
102 if (Res
== pkgPackageManager::Failed
)
104 if (Res
!= pkgPackageManager::Completed
)
105 return _error
->Error(_("Internal error, Ordering didn't finish"));
109 // Create the text record parser
110 pkgRecords
Recs(Cache
);
111 if (_error
->PendingError() == true)
114 // Create the download object
115 AcqTextStatus
Stat(std::cout
, ScreenWidth
,_config
->FindI("quiet",0));
116 pkgAcquire
Fetcher(&Stat
);
117 if (_config
->FindB("APT::Get::Print-URIs", false) == true)
119 // force a hashsum for compatibility reasons
120 _config
->CndSet("Acquire::ForceHash", "md5sum");
122 else if (Fetcher
.GetLock(_config
->FindDir("Dir::Cache::Archives")) == false)
125 // Read the source list
126 if (Cache
.BuildSourceList() == false)
128 pkgSourceList
*List
= Cache
.GetSourceList();
130 // Create the package manager and prepare to download
131 std::unique_ptr
<pkgPackageManager
> PM(_system
->CreatePM(Cache
));
132 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false ||
133 _error
->PendingError() == true)
136 // Display statistics
137 unsigned long long FetchBytes
= Fetcher
.FetchNeeded();
138 unsigned long long FetchPBytes
= Fetcher
.PartialPresent();
139 unsigned long long DebBytes
= Fetcher
.TotalNeeded();
140 if (DebBytes
!= Cache
->DebSize())
142 c0out
<< DebBytes
<< ',' << Cache
->DebSize() << std::endl
;
143 c0out
<< _("How odd... The sizes didn't match, email apt@packages.debian.org") << std::endl
;
147 if (DebBytes
!= FetchBytes
)
148 //TRANSLATOR: The required space between number and unit is already included
149 // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
150 ioprintf(c1out
,_("Need to get %sB/%sB of archives.\n"),
151 SizeToStr(FetchBytes
).c_str(),SizeToStr(DebBytes
).c_str());
152 else if (DebBytes
!= 0)
153 //TRANSLATOR: The required space between number and unit is already included
154 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
155 ioprintf(c1out
,_("Need to get %sB of archives.\n"),
156 SizeToStr(DebBytes
).c_str());
159 if (Cache
->UsrSize() >= 0)
160 //TRANSLATOR: The required space between number and unit is already included
161 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
162 ioprintf(c1out
,_("After this operation, %sB of additional disk space will be used.\n"),
163 SizeToStr(Cache
->UsrSize()).c_str());
165 //TRANSLATOR: The required space between number and unit is already included
166 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
167 ioprintf(c1out
,_("After this operation, %sB disk space will be freed.\n"),
168 SizeToStr(-1*Cache
->UsrSize()).c_str());
170 if (_error
->PendingError() == true)
173 if (CheckFreeSpaceBeforeDownload(_config
->FindDir("Dir::Cache::Archives"), (FetchBytes
- FetchPBytes
)) == false)
177 if (_config
->FindI("quiet",0) >= 2 ||
178 _config
->FindB("APT::Get::Assume-Yes",false) == true)
180 if (Fail
== true && _config
->FindB("APT::Get::Force-Yes",false) == false)
181 return _error
->Error(_("There are problems and -y was used without --force-yes"));
184 if (Essential
== true && Safety
== true)
186 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
187 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
189 // TRANSLATOR: This string needs to be typed by the user as a confirmation, so be
190 // careful with hard to type or special characters (like non-breaking spaces)
191 const char *Prompt
= _("Yes, do as I say!");
193 _("You are about to do something potentially harmful.\n"
194 "To continue type in the phrase '%s'\n"
197 if (AnalPrompt(Prompt
) == false)
199 c2out
<< _("Abort.") << std::endl
;
205 // Prompt to continue
206 if (Ask
== true || Fail
== true)
208 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
209 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
211 if (_config
->FindI("quiet",0) < 2 &&
212 _config
->FindB("APT::Get::Assume-Yes",false) == false)
214 c2out
<< _("Do you want to continue?") << std::flush
;
215 if (YnPrompt() == false)
217 c2out
<< _("Abort.") << std::endl
;
224 // Just print out the uris an exit if the --print-uris flag was used
225 if (_config
->FindB("APT::Get::Print-URIs") == true)
227 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
228 for (; I
!= Fetcher
.UriEnd(); ++I
)
229 std::cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
230 I
->Owner
->FileSize
<< ' ' << I
->Owner
->HashSum() << std::endl
;
234 if (!CheckAuth(Fetcher
, true))
237 /* Unlock the dpkg lock if we are not going to be doing an install
239 if (_config
->FindB("APT::Get::Download-Only",false) == true)
245 bool Transient
= false;
246 if (_config
->FindB("APT::Get::Download",true) == false)
248 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
< Fetcher
.ItemsEnd();)
250 if ((*I
)->Local
== true)
256 // Close the item and check if it was found in cache
258 if ((*I
)->Complete
== false)
261 // Clear it out of the fetch list
263 I
= Fetcher
.ItemsBegin();
268 if (AcquireRun(Fetcher
, 0, &Failed
, &Transient
) == false)
271 /* If we are in no download mode and missing files and there were
272 'failures' then the user must specify -m. Furthermore, there
273 is no such thing as a transient error in no-download mode! */
274 if (Transient
== true &&
275 _config
->FindB("APT::Get::Download",true) == false)
281 if (_config
->FindB("APT::Get::Download-Only",false) == true)
283 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
284 return _error
->Error(_("Some files failed to download"));
285 c1out
<< _("Download complete and in download only mode") << std::endl
;
289 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
291 return _error
->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
294 if (Transient
== true && Failed
== true)
295 return _error
->Error(_("--fix-missing and media swapping is not currently supported"));
297 // Try to deal with missing package files
298 if (Failed
== true && PM
->FixMissing() == false)
300 c2out
<< _("Unable to correct missing packages.") << std::endl
;
301 return _error
->Error(_("Aborting install."));
306 APT::Progress::PackageManager
*progress
= APT::Progress::PackageManagerProgressFactory();
307 pkgPackageManager::OrderResult Res
= PM
->DoInstall(progress
);
310 if (Res
== pkgPackageManager::Failed
|| _error
->PendingError() == true)
312 if (Res
== pkgPackageManager::Completed
)
315 // Reload the fetcher object and loop again for media swapping
317 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false)
323 std::set
<std::string
> const disappearedPkgs
= PM
->GetDisappearedPackages();
324 if (disappearedPkgs
.empty() == false)
326 ShowList(c1out
, P_("The following package disappeared from your system as\n"
327 "all files have been overwritten by other packages:",
328 "The following packages disappeared from your system as\n"
329 "all files have been overwritten by other packages:", disappearedPkgs
.size()), disappearedPkgs
,
330 [](std::string
const &Pkg
) { return Pkg
.empty() == false; },
331 [](std::string
const &Pkg
) { return Pkg
; },
332 [](std::string
const &) { return std::string(); });
333 c0out
<< _("Note: This is done automatically and on purpose by dpkg.") << std::endl
;
339 // DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
340 // ---------------------------------------------------------------------
341 /* Remove unused automatic packages */
342 static bool DoAutomaticRemove(CacheFile
&Cache
)
344 bool Debug
= _config
->FindI("Debug::pkgAutoRemove",false);
345 bool doAutoRemove
= _config
->FindB("APT::Get::AutomaticRemove", false);
346 bool hideAutoRemove
= _config
->FindB("APT::Get::HideAutoRemove");
348 pkgDepCache::ActionGroup
group(*Cache
);
350 std::cout
<< "DoAutomaticRemove()" << std::endl
;
352 if (doAutoRemove
== true &&
353 _config
->FindB("APT::Get::Remove",true) == false)
355 c1out
<< _("We are not supposed to delete stuff, can't start "
356 "AutoRemover") << std::endl
;
360 bool purgePkgs
= _config
->FindB("APT::Get::Purge", false);
361 bool smallList
= (hideAutoRemove
== false &&
362 strcasecmp(_config
->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
364 unsigned long autoRemoveCount
= 0;
365 APT::PackageSet tooMuch
;
366 SortedPackageUniverse
Universe(Cache
);
367 // look over the cache to see what can be removed
368 for (auto const &Pkg
: Universe
)
370 if (Cache
[Pkg
].Garbage
)
372 if(Pkg
.CurrentVer() != 0 || Cache
[Pkg
].Install())
374 std::cout
<< "We could delete %s" << Pkg
.FullName(true).c_str() << std::endl
;
378 if(Pkg
.CurrentVer() != 0 &&
379 Pkg
->CurrentState
!= pkgCache::State::ConfigFiles
)
380 Cache
->MarkDelete(Pkg
, purgePkgs
, 0, false);
382 Cache
->MarkKeep(Pkg
, false, false);
386 // if the package is a new install and already garbage we don't need to
387 // install it in the first place, so nuke it instead of show it
388 if (Cache
[Pkg
].Install() == true && Pkg
.CurrentVer() == 0)
390 if (Pkg
.CandVersion() != 0)
392 Cache
->MarkDelete(Pkg
, false, 0, false);
394 // only show stuff in the list that is not yet marked for removal
395 else if(hideAutoRemove
== false && Cache
[Pkg
].Delete() == false)
401 // we could have removed a new dependency of a garbage package,
402 // so check if a reverse depends is broken and if so install it again.
403 if (tooMuch
.empty() == false && (Cache
->BrokenCount() != 0 || Cache
->PolicyBrokenCount() != 0))
408 for (APT::PackageSet::iterator Pkg
= tooMuch
.begin();
409 Pkg
!= tooMuch
.end(); ++Pkg
)
413 for (pkgCache::PrvIterator Prv
= Cache
[Pkg
].CandidateVerIter(Cache
).ProvidesList();
414 Prv
.end() == false; ++Prv
)
415 too
.insert(Prv
.ParentPkg());
416 for (APT::PackageSet::const_iterator P
= too
.begin(); P
!= too
.end(); ++P
)
418 for (pkgCache::DepIterator R
= P
.RevDependsList();
419 R
.end() == false; ++R
)
421 if (R
.IsNegative() == true ||
422 Cache
->IsImportantDep(R
) == false)
424 pkgCache::PkgIterator N
= R
.ParentPkg();
425 if (N
.end() == true || (N
->CurrentVer
== 0 && (*Cache
)[N
].Install() == false))
428 std::clog
<< "Save " << Pkg
<< " as another installed garbage package depends on it" << std::endl
;
429 Cache
->MarkInstall(Pkg
, false, 0, false);
430 if (hideAutoRemove
== false)
442 } while (Changed
== true);
445 // Now see if we had destroyed anything (if we had done anything)
446 if (Cache
->BrokenCount() != 0)
448 c1out
<< _("Hmm, seems like the AutoRemover destroyed something which really\n"
449 "shouldn't happen. Please file a bug report against apt.") << std::endl
;
451 c1out
<< _("The following information may help to resolve the situation:") << std::endl
;
453 ShowBroken(c1out
,Cache
,false);
455 return _error
->Error(_("Internal Error, AutoRemover broke stuff"));
458 // if we don't remove them, we should show them!
459 if (doAutoRemove
== false && autoRemoveCount
!= 0)
461 if (smallList
== false)
463 SortedPackageUniverse
Universe(Cache
);
464 ShowList(c1out
, P_("The following package was automatically installed and is no longer required:",
465 "The following packages were automatically installed and are no longer required:",
466 autoRemoveCount
), Universe
,
467 [&Cache
](pkgCache::PkgIterator
const &Pkg
) { return (*Cache
)[Pkg
].Garbage
== true && (*Cache
)[Pkg
].Delete() == false; },
468 &PrettyFullName
, CandidateVersion(&Cache
));
471 ioprintf(c1out
, P_("%lu package was automatically installed and is no longer required.\n",
472 "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount
), autoRemoveCount
);
473 c1out
<< P_("Use 'apt-get autoremove' to remove it.", "Use 'apt-get autoremove' to remove them.", autoRemoveCount
) << std::endl
;
478 // DoCacheManipulationFromCommandLine /*{{{*/
479 static const unsigned short MOD_REMOVE
= 1;
480 static const unsigned short MOD_INSTALL
= 2;
482 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, CacheFile
&Cache
, int UpgradeMode
)
484 std::map
<unsigned short, APT::VersionSet
> verset
;
485 return DoCacheManipulationFromCommandLine(CmdL
, Cache
, verset
, UpgradeMode
);
487 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, CacheFile
&Cache
,
488 std::map
<unsigned short, APT::VersionSet
> &verset
, int UpgradeMode
)
490 // Enter the special broken fixing mode if the user specified arguments
491 bool BrokenFix
= false;
492 if (Cache
->BrokenCount() != 0)
495 std::unique_ptr
<pkgProblemResolver
> Fix(nullptr);
496 if (_config
->FindB("APT::Get::CallResolver", true) == true)
497 Fix
.reset(new pkgProblemResolver(Cache
));
499 unsigned short fallback
= MOD_INSTALL
;
500 if (strcasecmp(CmdL
.FileList
[0],"remove") == 0)
501 fallback
= MOD_REMOVE
;
502 else if (strcasecmp(CmdL
.FileList
[0], "purge") == 0)
504 _config
->Set("APT::Get::Purge", true);
505 fallback
= MOD_REMOVE
;
507 else if (strcasecmp(CmdL
.FileList
[0], "autoremove") == 0)
509 _config
->Set("APT::Get::AutomaticRemove", "true");
510 fallback
= MOD_REMOVE
;
513 std::list
<APT::VersionSet::Modifier
> mods
;
514 mods
.push_back(APT::VersionSet::Modifier(MOD_INSTALL
, "+",
515 APT::VersionSet::Modifier::POSTFIX
, APT::CacheSetHelper::CANDIDATE
));
516 mods
.push_back(APT::VersionSet::Modifier(MOD_REMOVE
, "-",
517 APT::VersionSet::Modifier::POSTFIX
, APT::CacheSetHelper::NEWEST
));
518 CacheSetHelperAPTGet
helper(c0out
);
519 verset
= APT::VersionSet::GroupedFromCommandLine(Cache
,
520 CmdL
.FileList
+ 1, mods
, fallback
, helper
);
522 if (_error
->PendingError() == true)
524 helper
.showVirtualPackageErrors(Cache
);
529 TryToInstall
InstallAction(Cache
, Fix
.get(), BrokenFix
);
530 TryToRemove
RemoveAction(Cache
, Fix
.get());
532 // new scope for the ActionGroup
534 pkgDepCache::ActionGroup
group(Cache
);
535 unsigned short const order
[] = { MOD_REMOVE
, MOD_INSTALL
, 0 };
537 for (unsigned short i
= 0; order
[i
] != 0; ++i
)
539 if (order
[i
] == MOD_INSTALL
)
540 InstallAction
= std::for_each(verset
[MOD_INSTALL
].begin(), verset
[MOD_INSTALL
].end(), InstallAction
);
541 else if (order
[i
] == MOD_REMOVE
)
542 RemoveAction
= std::for_each(verset
[MOD_REMOVE
].begin(), verset
[MOD_REMOVE
].end(), RemoveAction
);
545 if (Fix
!= NULL
&& _config
->FindB("APT::Get::AutoSolving", true) == true)
547 for (unsigned short i
= 0; order
[i
] != 0; ++i
)
549 if (order
[i
] != MOD_INSTALL
)
551 InstallAction
.propergateReleaseCandiateSwitching(helper
.selectedByRelease
, c0out
);
552 InstallAction
.doAutoInstall();
556 if (_error
->PendingError() == true)
561 /* If we are in the Broken fixing mode we do not attempt to fix the
562 problems. This is if the user invoked install without -f and gave
564 if (BrokenFix
== true && Cache
->BrokenCount() != 0)
566 c1out
<< _("You might want to run 'apt-get -f install' to correct these:") << std::endl
;
567 ShowBroken(c1out
,Cache
,false);
568 return _error
->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
573 // Call the scored problem resolver
574 OpTextProgress
Progress(*_config
);
575 bool const distUpgradeMode
= strcmp(CmdL
.FileList
[0], "dist-upgrade") == 0 || strcmp(CmdL
.FileList
[0], "full-upgrade") == 0;
577 bool resolver_fail
= false;
578 if (distUpgradeMode
== true || UpgradeMode
!= APT::Upgrade::ALLOW_EVERYTHING
)
579 resolver_fail
= APT::Upgrade::Upgrade(Cache
, UpgradeMode
, &Progress
);
581 resolver_fail
= Fix
->Resolve(true, &Progress
);
583 if (resolver_fail
== false && Cache
->BrokenCount() == 0)
587 // Now we check the state of the packages,
588 if (Cache
->BrokenCount() != 0)
591 _("Some packages could not be installed. This may mean that you have\n"
592 "requested an impossible situation or if you are using the unstable\n"
593 "distribution that some required packages have not yet been created\n"
594 "or been moved out of Incoming.") << std::endl
;
600 _("Since you only requested a single operation it is extremely likely that\n"
601 "the package is simply not installable and a bug report against\n"
602 "that package should be filed.") << std::endl;
606 c1out
<< _("The following information may help to resolve the situation:") << std::endl
;
608 ShowBroken(c1out
,Cache
,false);
609 if (_error
->PendingError() == true)
612 return _error
->Error(_("Broken packages"));
615 if (!DoAutomaticRemove(Cache
))
618 // if nothing changed in the cache, but only the automark information
619 // we write the StateFile here, otherwise it will be written in
621 if (InstallAction
.AutoMarkChanged
> 0 &&
622 Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
623 Cache
->BadCount() == 0 &&
624 _config
->FindB("APT::Get::Simulate",false) == false)
625 Cache
->writeStateFile(NULL
);
630 // DoInstall - Install packages from the command line /*{{{*/
631 // ---------------------------------------------------------------------
632 /* Install named packages */
633 struct PkgIsExtraInstalled
{
634 pkgCacheFile
* const Cache
;
635 APT::VersionSet
const * const verset
;
636 PkgIsExtraInstalled(pkgCacheFile
* const Cache
, APT::VersionSet
const * const Container
) : Cache(Cache
), verset(Container
) {}
637 bool operator() (pkgCache::PkgIterator
const Pkg
)
639 if ((*Cache
)[Pkg
].Install() == false)
641 pkgCache::VerIterator
const Cand
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
642 return verset
->find(Cand
) == verset
->end();
645 bool DoInstall(CommandLine
&CmdL
)
648 // first check for local pkgs and add them to the cache
649 for (const char **I
= CmdL
.FileList
; *I
!= 0; I
++)
651 if(FileExists(*I
) && flExtension(*I
) == "deb")
652 Cache
.GetSourceList()->AddVolatileFile(new debDebPkgFileIndex(*I
));
655 // then open the cache
656 if (Cache
.OpenForInstall() == false ||
657 Cache
.CheckDeps(CmdL
.FileSize() != 1) == false)
660 std::map
<unsigned short, APT::VersionSet
> verset
;
662 if(!DoCacheManipulationFromCommandLine(CmdL
, Cache
, verset
, 0))
665 /* Print out a list of packages that are going to be installed extra
666 to what the user asked */
667 SortedPackageUniverse
Universe(Cache
);
668 if (Cache
->InstCount() != verset
[MOD_INSTALL
].size())
669 ShowList(c1out
, _("The following extra packages will be installed:"), Universe
,
670 PkgIsExtraInstalled(&Cache
, &verset
[MOD_INSTALL
]),
671 &PrettyFullName
, CandidateVersion(&Cache
));
673 /* Print out a list of suggested and recommended packages */
675 std::list
<std::string
> Recommends
, Suggests
, SingleRecommends
, SingleSuggests
;
676 for (auto const &Pkg
: Universe
)
678 /* Just look at the ones we want to install */
679 if ((*Cache
)[Pkg
].Install() == false)
682 // get the recommends/suggests for the candidate ver
683 pkgCache::VerIterator CV
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
684 for (pkgCache::DepIterator D
= CV
.DependsList(); D
.end() == false; )
686 pkgCache::DepIterator Start
;
687 pkgCache::DepIterator End
;
688 D
.GlobOr(Start
,End
); // advances D
689 if (Start
->Type
!= pkgCache::Dep::Recommends
&& Start
->Type
!= pkgCache::Dep::Suggests
)
693 // Skip if we already saw this
695 for (pkgCache::DepIterator I
= Start
; I
!= D
; ++I
)
697 if (target
.empty() == false)
698 target
.append(" | ");
699 target
.append(I
.TargetPkg().FullName(true));
701 std::list
<std::string
> &Type
= Start
->Type
== pkgCache::Dep::Recommends
? SingleRecommends
: SingleSuggests
;
702 if (std::find(Type
.begin(), Type
.end(), target
) != Type
.end())
704 Type
.push_back(target
);
707 std::list
<std::string
> OrList
;
708 bool foundInstalledInOrGroup
= false;
709 for (pkgCache::DepIterator I
= Start
; I
!= D
; ++I
)
712 // satisfying package is installed and not marked for deletion
713 APT::VersionList installed
= APT::VersionList::FromDependency(Cache
, I
, APT::CacheSetHelper::INSTALLED
);
714 if (std::find_if(installed
.begin(), installed
.end(),
715 [&Cache
](pkgCache::VerIterator
const &Ver
) { return Cache
[Ver
.ParentPkg()].Delete() == false; }) != installed
.end())
717 foundInstalledInOrGroup
= true;
723 // satisfying package is upgraded to/new install
724 APT::VersionList upgrades
= APT::VersionList::FromDependency(Cache
, I
, APT::CacheSetHelper::CANDIDATE
);
725 if (std::find_if(upgrades
.begin(), upgrades
.end(),
726 [&Cache
](pkgCache::VerIterator
const &Ver
) { return Cache
[Ver
.ParentPkg()].Upgrade(); }) != upgrades
.end())
728 foundInstalledInOrGroup
= true;
734 OrList
.push_back(I
.TargetPkg().FullName(true));
736 OrList
.push_back("| " + I
.TargetPkg().FullName(true));
739 if(foundInstalledInOrGroup
== false)
741 std::list
<std::string
> &Type
= Start
->Type
== pkgCache::Dep::Recommends
? Recommends
: Suggests
;
742 std::move(OrList
.begin(), OrList
.end(), std::back_inserter(Type
));
746 auto always_true
= [](std::string
const&) { return true; };
747 auto string_ident
= [](std::string
const&str
) { return str
; };
748 auto verbose_show_candidate
=
749 [&Cache
](std::string str
)
751 if (APT::String::Startswith(str
, "| "))
753 pkgCache::PkgIterator
const Pkg
= Cache
->FindPkg(str
);
754 if (Pkg
.end() == true)
756 return (*Cache
)[Pkg
].CandVersion
;
758 ShowList(c1out
,_("Suggested packages:"), Suggests
,
759 always_true
, string_ident
, verbose_show_candidate
);
760 ShowList(c1out
,_("Recommended packages:"), Recommends
,
761 always_true
, string_ident
, verbose_show_candidate
);
764 // See if we need to prompt
765 // FIXME: check if really the packages in the set are going to be installed
766 if (Cache
->InstCount() == verset
[MOD_INSTALL
].size() && Cache
->DelCount() == 0)
767 return InstallPackages(Cache
,false,false);
769 return InstallPackages(Cache
,false);
773 // TryToInstall - Mark a package for installation /*{{{*/
774 void TryToInstall::operator() (pkgCache::VerIterator
const &Ver
) {
775 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
777 Cache
->GetDepCache()->SetCandidateVersion(Ver
);
778 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
780 // Handle the no-upgrade case
781 if (_config
->FindB("APT::Get::upgrade",true) == false && Pkg
->CurrentVer
!= 0)
782 ioprintf(c1out
,_("Skipping %s, it is already installed and upgrade is not set.\n"),
783 Pkg
.FullName(true).c_str());
784 // Ignore request for install if package would be new
785 else if (_config
->FindB("APT::Get::Only-Upgrade", false) == true && Pkg
->CurrentVer
== 0)
786 ioprintf(c1out
,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
787 Pkg
.FullName(true).c_str());
793 Cache
->GetDepCache()->MarkInstall(Pkg
,false);
795 if (State
.Install() == false) {
796 if (_config
->FindB("APT::Get::ReInstall",false) == true) {
797 if (Pkg
->CurrentVer
== 0 || Pkg
.CurrentVer().Downloadable() == false)
798 ioprintf(c1out
,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
799 Pkg
.FullName(true).c_str());
801 Cache
->GetDepCache()->SetReInstall(Pkg
, true);
803 ioprintf(c1out
,_("%s is already the newest version.\n"),
804 Pkg
.FullName(true).c_str());
807 // Install it with autoinstalling enabled (if we not respect the minial
808 // required deps or the policy)
809 if (FixBroken
== false)
810 doAutoInstallLater
.insert(Pkg
);
813 // see if we need to fix the auto-mark flag
814 // e.g. apt-get install foo
815 // where foo is marked automatic
816 if (State
.Install() == false &&
817 (State
.Flags
& pkgCache::Flag::Auto
) &&
818 _config
->FindB("APT::Get::ReInstall",false) == false &&
819 _config
->FindB("APT::Get::Only-Upgrade",false) == false &&
820 _config
->FindB("APT::Get::Download-Only",false) == false)
822 ioprintf(c1out
,_("%s set to manually installed.\n"),
823 Pkg
.FullName(true).c_str());
824 Cache
->GetDepCache()->MarkAuto(Pkg
,false);
829 bool TryToInstall::propergateReleaseCandiateSwitching(std::list
<std::pair
<pkgCache::VerIterator
, std::string
> > const &start
, std::ostream
&out
)/*{{{*/
831 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
832 s
!= start
.end(); ++s
)
833 Cache
->GetDepCache()->SetCandidateVersion(s
->first
);
836 // the Changed list contains:
837 // first: "new version"
838 // second: "what-caused the change"
839 std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> > Changed
;
840 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
841 s
!= start
.end(); ++s
)
843 Changed
.push_back(std::make_pair(s
->first
, pkgCache::VerIterator(*Cache
)));
844 // We continue here even if it failed to enhance the ShowBroken output
845 Success
&= Cache
->GetDepCache()->SetCandidateRelease(s
->first
, s
->second
, Changed
);
847 for (std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> >::const_iterator c
= Changed
.begin();
848 c
!= Changed
.end(); ++c
)
850 if (c
->second
.end() == true)
851 ioprintf(out
, _("Selected version '%s' (%s) for '%s'\n"),
852 c
->first
.VerStr(), c
->first
.RelStr().c_str(), c
->first
.ParentPkg().FullName(true).c_str());
853 else if (c
->first
.ParentPkg()->Group
!= c
->second
.ParentPkg()->Group
)
855 pkgCache::VerIterator V
= (*Cache
)[c
->first
.ParentPkg()].CandidateVerIter(*Cache
);
856 ioprintf(out
, _("Selected version '%s' (%s) for '%s' because of '%s'\n"), V
.VerStr(),
857 V
.RelStr().c_str(), V
.ParentPkg().FullName(true).c_str(), c
->second
.ParentPkg().FullName(true).c_str());
863 void TryToInstall::doAutoInstall() { /*{{{*/
864 for (APT::PackageSet::const_iterator P
= doAutoInstallLater
.begin();
865 P
!= doAutoInstallLater
.end(); ++P
) {
866 pkgDepCache::StateCache
&State
= (*Cache
)[P
];
867 if (State
.InstBroken() == false && State
.InstPolicyBroken() == false)
869 Cache
->GetDepCache()->MarkInstall(P
, true);
871 doAutoInstallLater
.clear();
874 // TryToRemove - Mark a package for removal /*{{{*/
875 void TryToRemove::operator() (pkgCache::VerIterator
const &Ver
)
877 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
886 if ((Pkg
->CurrentVer
== 0 && PurgePkgs
== false) ||
887 (PurgePkgs
== true && Pkg
->CurrentState
== pkgCache::State::NotInstalled
))
889 pkgCache::GrpIterator Grp
= Pkg
.Group();
890 pkgCache::PkgIterator P
= Grp
.PackageList();
891 for (; P
.end() != true; P
= Grp
.NextPkg(P
))
895 if (P
->CurrentVer
!= 0 || (PurgePkgs
== true && P
->CurrentState
!= pkgCache::State::NotInstalled
))
897 // TRANSLATORS: Note, this is not an interactive question
898 ioprintf(c1out
,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
899 Pkg
.FullName(true).c_str(), P
.FullName(true).c_str());
904 ioprintf(c1out
,_("Package '%s' is not installed, so not removed\n"),Pkg
.FullName(true).c_str());
906 // MarkInstall refuses to install packages on hold
907 Pkg
->SelectedState
= pkgCache::State::Hold
;
910 Cache
->GetDepCache()->MarkDelete(Pkg
, PurgePkgs
);