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>
33 #include <apt-private/acqprogress.h>
34 #include <apt-private/private-install.h>
35 #include <apt-private/private-cachefile.h>
36 #include <apt-private/private-cacheset.h>
37 #include <apt-private/private-download.h>
38 #include <apt-private/private-output.h>
44 // InstallPackages - Actually download and install the packages /*{{{*/
45 // ---------------------------------------------------------------------
46 /* This displays the informative messages describing what is going to
47 happen and then calls the download routines */
48 bool InstallPackages(CacheFile
&Cache
,bool ShwKept
,bool Ask
, bool Safety
)
50 if (_config
->FindB("APT::Get::Purge",false) == true)
52 pkgCache::PkgIterator I
= Cache
->PkgBegin();
53 for (; I
.end() == false; ++I
)
55 if (I
.Purge() == false && Cache
[I
].Mode
== pkgDepCache::ModeDelete
)
56 Cache
->MarkDelete(I
,true);
61 bool Downgrade
= false;
62 bool Essential
= false;
64 // Show all the various warning indicators
68 ShowKept(c1out
,Cache
);
69 Hold
= !ShowHold(c1out
,Cache
);
70 if (_config
->FindB("APT::Get::Show-Upgraded",true) == true)
71 ShowUpgraded(c1out
,Cache
);
72 Downgrade
= !ShowDowngraded(c1out
,Cache
);
74 if (_config
->FindB("APT::Get::Download-Only",false) == false)
75 Essential
= !ShowEssential(c1out
,Cache
);
77 // All kinds of failures
78 bool Fail
= (Essential
|| Downgrade
|| Hold
);
83 if (Cache
->BrokenCount() != 0)
85 ShowBroken(c1out
,Cache
,false);
86 return _error
->Error(_("Internal error, InstallPackages was called with broken packages!"));
89 if (Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
90 Cache
->BadCount() == 0)
94 if (Cache
->DelCount() != 0 && _config
->FindB("APT::Get::Remove",true) == false)
95 return _error
->Error(_("Packages need to be removed but remove is disabled."));
98 if (_config
->FindI("quiet",0) >= 2 ||
99 _config
->FindB("APT::Get::Assume-Yes",false) == true)
101 if (_config
->FindB("APT::Get::Force-Yes",false) == true) {
102 _error
->Warning(_("--force-yes is deprecated, use one of the options starting with --allow instead."));
105 if (Fail
== true && _config
->FindB("APT::Get::Force-Yes",false) == false) {
106 if (Essential
== true && _config
->FindB("APT::Get::allow-remove-essential", false) == false)
107 return _error
->Error(_("Essential packages were removed and -y was used without --allow-remove-essential."));
108 if (Downgrade
== true && _config
->FindB("APT::Get::allow-downgrades", false) == false)
109 return _error
->Error(_("Packages were downgraded and -y was used without --allow-downgrades."));
110 if (Hold
== true && _config
->FindB("APT::Get::allow-change-held-packages", false) == false)
111 return _error
->Error(_("Held packages were changed and -y was used without --allow-change-held-packages."));
115 // Run the simulator ..
116 if (_config
->FindB("APT::Get::Simulate") == true)
118 pkgSimulate
PM(Cache
);
120 APT::Progress::PackageManager
*progress
= APT::Progress::PackageManagerProgressFactory();
121 pkgPackageManager::OrderResult Res
= PM
.DoInstall(progress
);
124 if (Res
== pkgPackageManager::Failed
)
126 if (Res
!= pkgPackageManager::Completed
)
127 return _error
->Error(_("Internal error, Ordering didn't finish"));
131 // Create the text record parser
132 pkgRecords
Recs(Cache
);
133 if (_error
->PendingError() == true)
136 // Create the download object
137 aptAcquireWithTextStatus Fetcher
;
138 if (_config
->FindB("APT::Get::Print-URIs", false) == true)
140 // force a hashsum for compatibility reasons
141 _config
->CndSet("Acquire::ForceHash", "md5sum");
143 else if (Fetcher
.GetLock(_config
->FindDir("Dir::Cache::Archives")) == false)
146 // Read the source list
147 if (Cache
.BuildSourceList() == false)
149 pkgSourceList
*List
= Cache
.GetSourceList();
151 // Create the package manager and prepare to download
152 std::unique_ptr
<pkgPackageManager
> PM(_system
->CreatePM(Cache
));
153 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false ||
154 _error
->PendingError() == true)
157 // Display statistics
158 unsigned long long FetchBytes
= Fetcher
.FetchNeeded();
159 unsigned long long FetchPBytes
= Fetcher
.PartialPresent();
160 unsigned long long DebBytes
= Fetcher
.TotalNeeded();
161 if (DebBytes
!= Cache
->DebSize())
163 c0out
<< DebBytes
<< ',' << Cache
->DebSize() << std::endl
;
164 c0out
<< _("How odd... The sizes didn't match, email apt@packages.debian.org") << std::endl
;
168 if (DebBytes
!= FetchBytes
)
169 //TRANSLATOR: The required space between number and unit is already included
170 // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
171 ioprintf(c1out
,_("Need to get %sB/%sB of archives.\n"),
172 SizeToStr(FetchBytes
).c_str(),SizeToStr(DebBytes
).c_str());
173 else if (DebBytes
!= 0)
174 //TRANSLATOR: The required space between number and unit is already included
175 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
176 ioprintf(c1out
,_("Need to get %sB of archives.\n"),
177 SizeToStr(DebBytes
).c_str());
180 if (Cache
->UsrSize() >= 0)
181 //TRANSLATOR: The required space between number and unit is already included
182 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
183 ioprintf(c1out
,_("After this operation, %sB of additional disk space will be used.\n"),
184 SizeToStr(Cache
->UsrSize()).c_str());
186 //TRANSLATOR: The required space between number and unit is already included
187 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
188 ioprintf(c1out
,_("After this operation, %sB disk space will be freed.\n"),
189 SizeToStr(-1*Cache
->UsrSize()).c_str());
191 if (_error
->PendingError() == true)
194 if (CheckFreeSpaceBeforeDownload(_config
->FindDir("Dir::Cache::Archives"), (FetchBytes
- FetchPBytes
)) == false)
197 if (Essential
== true && Safety
== true && _config
->FindB("APT::Get::allow-remove-essential", false) == false)
199 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
200 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
202 // TRANSLATOR: This string needs to be typed by the user as a confirmation, so be
203 // careful with hard to type or special characters (like non-breaking spaces)
204 const char *Prompt
= _("Yes, do as I say!");
206 _("You are about to do something potentially harmful.\n"
207 "To continue type in the phrase '%s'\n"
210 if (AnalPrompt(Prompt
) == false)
212 c2out
<< _("Abort.") << std::endl
;
218 // Prompt to continue
219 if (Ask
== true || Fail
== true)
221 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
222 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
224 if (_config
->FindI("quiet",0) < 2 &&
225 _config
->FindB("APT::Get::Assume-Yes",false) == false)
227 c2out
<< _("Do you want to continue?") << std::flush
;
228 if (YnPrompt() == false)
230 c2out
<< _("Abort.") << std::endl
;
237 // Just print out the uris an exit if the --print-uris flag was used
238 if (_config
->FindB("APT::Get::Print-URIs") == true)
240 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
241 for (; I
!= Fetcher
.UriEnd(); ++I
)
242 std::cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
243 I
->Owner
->FileSize
<< ' ' << I
->Owner
->HashSum() << std::endl
;
247 if (!CheckAuth(Fetcher
, true))
250 /* Unlock the dpkg lock if we are not going to be doing an install
252 if (_config
->FindB("APT::Get::Download-Only",false) == true)
258 bool Transient
= false;
259 if (_config
->FindB("APT::Get::Download",true) == false)
261 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
< Fetcher
.ItemsEnd();)
263 if ((*I
)->Local
== true)
269 // Close the item and check if it was found in cache
271 if ((*I
)->Complete
== false)
274 // Clear it out of the fetch list
276 I
= Fetcher
.ItemsBegin();
281 if (AcquireRun(Fetcher
, 0, &Failed
, &Transient
) == false)
284 /* If we are in no download mode and missing files and there were
285 'failures' then the user must specify -m. Furthermore, there
286 is no such thing as a transient error in no-download mode! */
287 if (Transient
== true &&
288 _config
->FindB("APT::Get::Download",true) == false)
294 if (_config
->FindB("APT::Get::Download-Only",false) == true)
296 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
297 return _error
->Error(_("Some files failed to download"));
298 c1out
<< _("Download complete and in download only mode") << std::endl
;
302 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
304 return _error
->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
307 if (Transient
== true && Failed
== true)
308 return _error
->Error(_("--fix-missing and media swapping is not currently supported"));
310 // Try to deal with missing package files
311 if (Failed
== true && PM
->FixMissing() == false)
313 c2out
<< _("Unable to correct missing packages.") << std::endl
;
314 return _error
->Error(_("Aborting install."));
319 APT::Progress::PackageManager
*progress
= APT::Progress::PackageManagerProgressFactory();
320 pkgPackageManager::OrderResult Res
= PM
->DoInstall(progress
);
323 if (Res
== pkgPackageManager::Failed
|| _error
->PendingError() == true)
325 if (Res
== pkgPackageManager::Completed
)
328 // Reload the fetcher object and loop again for media swapping
330 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false)
336 std::set
<std::string
> const disappearedPkgs
= PM
->GetDisappearedPackages();
337 if (disappearedPkgs
.empty() == false)
339 ShowList(c1out
, P_("The following package disappeared from your system as\n"
340 "all files have been overwritten by other packages:",
341 "The following packages disappeared from your system as\n"
342 "all files have been overwritten by other packages:", disappearedPkgs
.size()), disappearedPkgs
,
343 [](std::string
const &Pkg
) { return Pkg
.empty() == false; },
344 [](std::string
const &Pkg
) { return Pkg
; },
345 [](std::string
const &) { return std::string(); });
346 c0out
<< _("Note: This is done automatically and on purpose by dpkg.") << std::endl
;
349 // cleanup downloaded debs
350 if (_config
->FindB("APT::Keep-Downloaded-Packages", true) == false)
352 std::string
const archivedir
= _config
->FindDir("Dir::Cache::archives");
353 for (auto I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); ++I
)
355 if (flNotFile((*I
)->DestFile
) != archivedir
|| (*I
)->Local
)
357 RemoveFile("Keep-Downloaded-Packages=false", (*I
)->DestFile
);
364 // DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
365 // ---------------------------------------------------------------------
366 /* Remove unused automatic packages */
367 static bool DoAutomaticRemove(CacheFile
&Cache
)
369 bool Debug
= _config
->FindI("Debug::pkgAutoRemove",false);
370 bool doAutoRemove
= _config
->FindB("APT::Get::AutomaticRemove", false);
371 bool hideAutoRemove
= _config
->FindB("APT::Get::HideAutoRemove");
373 pkgDepCache::ActionGroup
group(*Cache
);
375 std::cout
<< "DoAutomaticRemove()" << std::endl
;
377 if (doAutoRemove
== true &&
378 _config
->FindB("APT::Get::Remove",true) == false)
380 c1out
<< _("We are not supposed to delete stuff, can't start "
381 "AutoRemover") << std::endl
;
385 bool purgePkgs
= _config
->FindB("APT::Get::Purge", false);
386 bool smallList
= (hideAutoRemove
== false &&
387 strcasecmp(_config
->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
389 unsigned long autoRemoveCount
= 0;
390 APT::PackageSet tooMuch
;
391 SortedPackageUniverse
Universe(Cache
);
392 // look over the cache to see what can be removed
393 for (auto const &Pkg
: Universe
)
395 if (Cache
[Pkg
].Garbage
)
397 if(Pkg
.CurrentVer() != 0 || Cache
[Pkg
].Install())
399 std::cout
<< "We could delete %s" << Pkg
.FullName(true).c_str() << std::endl
;
403 if(Pkg
.CurrentVer() != 0 &&
404 Pkg
->CurrentState
!= pkgCache::State::ConfigFiles
)
405 Cache
->MarkDelete(Pkg
, purgePkgs
, 0, false);
407 Cache
->MarkKeep(Pkg
, false, false);
411 // if the package is a new install and already garbage we don't need to
412 // install it in the first place, so nuke it instead of show it
413 if (Cache
[Pkg
].Install() == true && Pkg
.CurrentVer() == 0)
415 if (Pkg
.CandVersion() != 0)
417 Cache
->MarkDelete(Pkg
, false, 0, false);
419 // only show stuff in the list that is not yet marked for removal
420 else if(hideAutoRemove
== false && Cache
[Pkg
].Delete() == false)
426 // we could have removed a new dependency of a garbage package,
427 // so check if a reverse depends is broken and if so install it again.
428 if (tooMuch
.empty() == false && (Cache
->BrokenCount() != 0 || Cache
->PolicyBrokenCount() != 0))
433 for (APT::PackageSet::iterator Pkg
= tooMuch
.begin();
434 Pkg
!= tooMuch
.end(); ++Pkg
)
438 for (pkgCache::PrvIterator Prv
= Cache
[Pkg
].CandidateVerIter(Cache
).ProvidesList();
439 Prv
.end() == false; ++Prv
)
440 too
.insert(Prv
.ParentPkg());
441 for (APT::PackageSet::const_iterator P
= too
.begin(); P
!= too
.end(); ++P
)
443 for (pkgCache::DepIterator R
= P
.RevDependsList();
444 R
.end() == false; ++R
)
446 if (R
.IsNegative() == true ||
447 Cache
->IsImportantDep(R
) == false)
449 pkgCache::PkgIterator N
= R
.ParentPkg();
450 if (N
.end() == true || (N
->CurrentVer
== 0 && (*Cache
)[N
].Install() == false))
453 std::clog
<< "Save " << Pkg
<< " as another installed garbage package depends on it" << std::endl
;
454 Cache
->MarkInstall(Pkg
, false, 0, false);
455 if (hideAutoRemove
== false)
467 } while (Changed
== true);
470 // Now see if we had destroyed anything (if we had done anything)
471 if (Cache
->BrokenCount() != 0)
473 c1out
<< _("Hmm, seems like the AutoRemover destroyed something which really\n"
474 "shouldn't happen. Please file a bug report against apt.") << std::endl
;
476 c1out
<< _("The following information may help to resolve the situation:") << std::endl
;
478 ShowBroken(c1out
,Cache
,false);
480 return _error
->Error(_("Internal Error, AutoRemover broke stuff"));
483 // if we don't remove them, we should show them!
484 if (doAutoRemove
== false && autoRemoveCount
!= 0)
486 if (smallList
== false)
488 SortedPackageUniverse
Universe(Cache
);
489 ShowList(c1out
, P_("The following package was automatically installed and is no longer required:",
490 "The following packages were automatically installed and are no longer required:",
491 autoRemoveCount
), Universe
,
492 [&Cache
](pkgCache::PkgIterator
const &Pkg
) { return (*Cache
)[Pkg
].Garbage
== true && (*Cache
)[Pkg
].Delete() == false; },
493 &PrettyFullName
, CandidateVersion(&Cache
));
496 ioprintf(c1out
, P_("%lu package was automatically installed and is no longer required.\n",
497 "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount
), autoRemoveCount
);
498 std::string autocmd
= "apt autoremove";
499 if (getenv("SUDO_USER") != NULL
)
500 autocmd
= "sudo " + autocmd
;
501 ioprintf(c1out
, P_("Use '%s' to remove it.", "Use '%s' to remove them.", autoRemoveCount
), autocmd
.c_str());
507 // DoCacheManipulationFromCommandLine /*{{{*/
508 static const unsigned short MOD_REMOVE
= 1;
509 static const unsigned short MOD_INSTALL
= 2;
511 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, CacheFile
&Cache
, int UpgradeMode
)
513 std::vector
<const char*> VolatileCmdL
;
514 return DoCacheManipulationFromCommandLine(CmdL
, VolatileCmdL
, Cache
, UpgradeMode
);
516 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, std::vector
<const char*> &VolatileCmdL
, CacheFile
&Cache
, int UpgradeMode
)
518 std::map
<unsigned short, APT::VersionSet
> verset
;
519 return DoCacheManipulationFromCommandLine(CmdL
, VolatileCmdL
, Cache
, verset
, UpgradeMode
);
521 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, std::vector
<const char*> &VolatileCmdL
, CacheFile
&Cache
,
522 std::map
<unsigned short, APT::VersionSet
> &verset
, int UpgradeMode
)
524 // Enter the special broken fixing mode if the user specified arguments
525 bool BrokenFix
= false;
526 if (Cache
->BrokenCount() != 0)
529 std::unique_ptr
<pkgProblemResolver
> Fix(nullptr);
530 if (_config
->FindB("APT::Get::CallResolver", true) == true)
531 Fix
.reset(new pkgProblemResolver(Cache
));
533 unsigned short fallback
= MOD_INSTALL
;
534 if (strcasecmp(CmdL
.FileList
[0],"remove") == 0)
535 fallback
= MOD_REMOVE
;
536 else if (strcasecmp(CmdL
.FileList
[0], "purge") == 0)
538 _config
->Set("APT::Get::Purge", true);
539 fallback
= MOD_REMOVE
;
541 else if (strcasecmp(CmdL
.FileList
[0], "autoremove") == 0 ||
542 strcasecmp(CmdL
.FileList
[0], "auto-remove") == 0)
544 _config
->Set("APT::Get::AutomaticRemove", "true");
545 fallback
= MOD_REMOVE
;
548 std::list
<APT::VersionSet::Modifier
> mods
;
549 mods
.push_back(APT::VersionSet::Modifier(MOD_INSTALL
, "+",
550 APT::VersionSet::Modifier::POSTFIX
, APT::CacheSetHelper::CANDIDATE
));
551 mods
.push_back(APT::VersionSet::Modifier(MOD_REMOVE
, "-",
552 APT::VersionSet::Modifier::POSTFIX
, APT::CacheSetHelper::NEWEST
));
553 CacheSetHelperAPTGet
helper(c0out
);
554 verset
= APT::VersionSet::GroupedFromCommandLine(Cache
,
555 CmdL
.FileList
+ 1, mods
, fallback
, helper
);
557 for (auto const &I
: VolatileCmdL
)
559 pkgCache::PkgIterator
const P
= Cache
->FindPkg(I
);
563 // Set any version providing the .deb as the candidate.
564 for (auto Prv
= P
.ProvidesList(); Prv
.end() == false; Prv
++)
565 Cache
.GetDepCache()->SetCandidateVersion(Prv
.OwnerVer());
567 // via cacheset to have our usual virtual handling
568 APT::VersionContainerInterface::FromPackage(&(verset
[MOD_INSTALL
]), Cache
, P
, APT::CacheSetHelper::CANDIDATE
, helper
);
571 if (_error
->PendingError() == true)
573 helper
.showVirtualPackageErrors(Cache
);
578 TryToInstall
InstallAction(Cache
, Fix
.get(), BrokenFix
);
579 TryToRemove
RemoveAction(Cache
, Fix
.get());
581 // new scope for the ActionGroup
583 pkgDepCache::ActionGroup
group(Cache
);
584 unsigned short const order
[] = { MOD_REMOVE
, MOD_INSTALL
, 0 };
586 for (unsigned short i
= 0; order
[i
] != 0; ++i
)
588 if (order
[i
] == MOD_INSTALL
)
589 InstallAction
= std::for_each(verset
[MOD_INSTALL
].begin(), verset
[MOD_INSTALL
].end(), InstallAction
);
590 else if (order
[i
] == MOD_REMOVE
)
591 RemoveAction
= std::for_each(verset
[MOD_REMOVE
].begin(), verset
[MOD_REMOVE
].end(), RemoveAction
);
594 if (Fix
!= NULL
&& _config
->FindB("APT::Get::AutoSolving", true) == true)
596 InstallAction
.propergateReleaseCandiateSwitching(helper
.selectedByRelease
, c0out
);
597 InstallAction
.doAutoInstall();
600 if (_error
->PendingError() == true)
605 /* If we are in the Broken fixing mode we do not attempt to fix the
606 problems. This is if the user invoked install without -f and gave
608 if (BrokenFix
== true && Cache
->BrokenCount() != 0)
610 c1out
<< _("You might want to run 'apt-get -f install' to correct these:") << std::endl
;
611 ShowBroken(c1out
,Cache
,false);
612 return _error
->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
617 // Call the scored problem resolver
618 OpTextProgress
Progress(*_config
);
619 bool const distUpgradeMode
= strcmp(CmdL
.FileList
[0], "dist-upgrade") == 0 || strcmp(CmdL
.FileList
[0], "full-upgrade") == 0;
621 bool resolver_fail
= false;
622 if (distUpgradeMode
== true || UpgradeMode
!= APT::Upgrade::ALLOW_EVERYTHING
)
623 resolver_fail
= APT::Upgrade::Upgrade(Cache
, UpgradeMode
, &Progress
);
625 resolver_fail
= Fix
->Resolve(true, &Progress
);
627 if (resolver_fail
== false && Cache
->BrokenCount() == 0)
631 // Now we check the state of the packages,
632 if (Cache
->BrokenCount() != 0)
635 _("Some packages could not be installed. This may mean that you have\n"
636 "requested an impossible situation or if you are using the unstable\n"
637 "distribution that some required packages have not yet been created\n"
638 "or been moved out of Incoming.") << std::endl
;
644 _("Since you only requested a single operation it is extremely likely that\n"
645 "the package is simply not installable and a bug report against\n"
646 "that package should be filed.") << std::endl;
650 c1out
<< _("The following information may help to resolve the situation:") << std::endl
;
652 ShowBroken(c1out
,Cache
,false);
653 if (_error
->PendingError() == true)
656 return _error
->Error(_("Broken packages"));
659 if (!DoAutomaticRemove(Cache
))
662 // if nothing changed in the cache, but only the automark information
663 // we write the StateFile here, otherwise it will be written in
665 if (InstallAction
.AutoMarkChanged
> 0 &&
666 Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
667 Cache
->BadCount() == 0 &&
668 _config
->FindB("APT::Get::Simulate",false) == false)
669 Cache
->writeStateFile(NULL
);
674 // DoInstall - Install packages from the command line /*{{{*/
675 // ---------------------------------------------------------------------
676 /* Install named packages */
677 struct PkgIsExtraInstalled
{
678 pkgCacheFile
* const Cache
;
679 APT::VersionSet
const * const verset
;
680 PkgIsExtraInstalled(pkgCacheFile
* const Cache
, APT::VersionSet
const * const Container
) : Cache(Cache
), verset(Container
) {}
681 bool operator() (pkgCache::PkgIterator
const &Pkg
)
683 if ((*Cache
)[Pkg
].Install() == false)
685 pkgCache::VerIterator
const Cand
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
686 return verset
->find(Cand
) == verset
->end();
689 bool DoInstall(CommandLine
&CmdL
)
692 std::vector
<char const *> VolatileCmdL
;
693 Cache
.GetSourceList()->AddVolatileFiles(CmdL
, &VolatileCmdL
);
695 // then open the cache
696 if (Cache
.OpenForInstall() == false ||
697 Cache
.CheckDeps(CmdL
.FileSize() != 1) == false)
700 std::map
<unsigned short, APT::VersionSet
> verset
;
701 if(!DoCacheManipulationFromCommandLine(CmdL
, VolatileCmdL
, Cache
, verset
, 0))
704 /* Print out a list of packages that are going to be installed extra
705 to what the user asked */
706 SortedPackageUniverse
Universe(Cache
);
707 if (Cache
->InstCount() != verset
[MOD_INSTALL
].size())
708 ShowList(c1out
, _("The following additional packages will be installed:"), Universe
,
709 PkgIsExtraInstalled(&Cache
, &verset
[MOD_INSTALL
]),
710 &PrettyFullName
, CandidateVersion(&Cache
));
712 /* Print out a list of suggested and recommended packages */
714 std::list
<std::string
> Recommends
, Suggests
, SingleRecommends
, SingleSuggests
;
715 for (auto const &Pkg
: Universe
)
717 /* Just look at the ones we want to install */
718 if ((*Cache
)[Pkg
].Install() == false)
721 // get the recommends/suggests for the candidate ver
722 pkgCache::VerIterator CV
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
723 for (pkgCache::DepIterator D
= CV
.DependsList(); D
.end() == false; )
725 pkgCache::DepIterator Start
;
726 pkgCache::DepIterator End
;
727 D
.GlobOr(Start
,End
); // advances D
728 if (Start
->Type
!= pkgCache::Dep::Recommends
&& Start
->Type
!= pkgCache::Dep::Suggests
)
732 // Skip if we already saw this
734 for (pkgCache::DepIterator I
= Start
; I
!= D
; ++I
)
736 if (target
.empty() == false)
737 target
.append(" | ");
738 target
.append(I
.TargetPkg().FullName(true));
740 std::list
<std::string
> &Type
= Start
->Type
== pkgCache::Dep::Recommends
? SingleRecommends
: SingleSuggests
;
741 if (std::find(Type
.begin(), Type
.end(), target
) != Type
.end())
743 Type
.push_back(target
);
746 std::list
<std::string
> OrList
;
747 bool foundInstalledInOrGroup
= false;
748 for (pkgCache::DepIterator I
= Start
; I
!= D
; ++I
)
751 // satisfying package is installed and not marked for deletion
752 APT::VersionList installed
= APT::VersionList::FromDependency(Cache
, I
, APT::CacheSetHelper::INSTALLED
);
753 if (std::find_if(installed
.begin(), installed
.end(),
754 [&Cache
](pkgCache::VerIterator
const &Ver
) { return Cache
[Ver
.ParentPkg()].Delete() == false; }) != installed
.end())
756 foundInstalledInOrGroup
= true;
762 // satisfying package is upgraded to/new install
763 APT::VersionList upgrades
= APT::VersionList::FromDependency(Cache
, I
, APT::CacheSetHelper::CANDIDATE
);
764 if (std::find_if(upgrades
.begin(), upgrades
.end(),
765 [&Cache
](pkgCache::VerIterator
const &Ver
) { return Cache
[Ver
.ParentPkg()].Upgrade(); }) != upgrades
.end())
767 foundInstalledInOrGroup
= true;
773 OrList
.push_back(I
.TargetPkg().FullName(true));
775 OrList
.push_back("| " + I
.TargetPkg().FullName(true));
778 if(foundInstalledInOrGroup
== false)
780 std::list
<std::string
> &Type
= Start
->Type
== pkgCache::Dep::Recommends
? Recommends
: Suggests
;
781 std::move(OrList
.begin(), OrList
.end(), std::back_inserter(Type
));
785 auto always_true
= [](std::string
const&) { return true; };
786 auto string_ident
= [](std::string
const&str
) { return str
; };
787 auto verbose_show_candidate
=
788 [&Cache
](std::string str
)
790 if (APT::String::Startswith(str
, "| "))
792 pkgCache::PkgIterator
const Pkg
= Cache
->FindPkg(str
);
793 if (Pkg
.end() == true)
795 return (*Cache
)[Pkg
].CandVersion
;
797 ShowList(c1out
,_("Suggested packages:"), Suggests
,
798 always_true
, string_ident
, verbose_show_candidate
);
799 ShowList(c1out
,_("Recommended packages:"), Recommends
,
800 always_true
, string_ident
, verbose_show_candidate
);
803 // See if we need to prompt
804 // FIXME: check if really the packages in the set are going to be installed
805 if (Cache
->InstCount() == verset
[MOD_INSTALL
].size() && Cache
->DelCount() == 0)
806 return InstallPackages(Cache
,false,false);
808 return InstallPackages(Cache
,false);
812 // TryToInstall - Mark a package for installation /*{{{*/
813 void TryToInstall::operator() (pkgCache::VerIterator
const &Ver
) {
814 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
816 Cache
->GetDepCache()->SetCandidateVersion(Ver
);
817 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
819 // Handle the no-upgrade case
820 if (_config
->FindB("APT::Get::upgrade",true) == false && Pkg
->CurrentVer
!= 0)
821 ioprintf(c1out
,_("Skipping %s, it is already installed and upgrade is not set.\n"),
822 Pkg
.FullName(true).c_str());
823 // Ignore request for install if package would be new
824 else if (_config
->FindB("APT::Get::Only-Upgrade", false) == true && Pkg
->CurrentVer
== 0)
825 ioprintf(c1out
,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
826 Pkg
.FullName(true).c_str());
832 Cache
->GetDepCache()->MarkInstall(Pkg
,false);
834 if (State
.Install() == false) {
835 if (_config
->FindB("APT::Get::ReInstall",false) == true) {
836 if (Pkg
->CurrentVer
== 0 || Pkg
.CurrentVer().Downloadable() == false)
837 ioprintf(c1out
,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
838 Pkg
.FullName(true).c_str());
840 Cache
->GetDepCache()->SetReInstall(Pkg
, true);
842 // TRANSLATORS: First string is package name, second is version
843 ioprintf(c1out
,_("%s is already the newest version (%s).\n"),
844 Pkg
.FullName(true).c_str(), Pkg
.CurrentVer().VerStr());
847 // Install it with autoinstalling enabled (if we not respect the minial
848 // required deps or the policy)
849 if (FixBroken
== false)
850 doAutoInstallLater
.insert(Pkg
);
853 // see if we need to fix the auto-mark flag
854 // e.g. apt-get install foo
855 // where foo is marked automatic
856 if (State
.Install() == false &&
857 (State
.Flags
& pkgCache::Flag::Auto
) &&
858 _config
->FindB("APT::Get::ReInstall",false) == false &&
859 _config
->FindB("APT::Get::Only-Upgrade",false) == false &&
860 _config
->FindB("APT::Get::Download-Only",false) == false)
862 ioprintf(c1out
,_("%s set to manually installed.\n"),
863 Pkg
.FullName(true).c_str());
864 Cache
->GetDepCache()->MarkAuto(Pkg
,false);
869 bool TryToInstall::propergateReleaseCandiateSwitching(std::list
<std::pair
<pkgCache::VerIterator
, std::string
> > const &start
, std::ostream
&out
)/*{{{*/
871 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
872 s
!= start
.end(); ++s
)
873 Cache
->GetDepCache()->SetCandidateVersion(s
->first
);
876 // the Changed list contains:
877 // first: "new version"
878 // second: "what-caused the change"
879 std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> > Changed
;
880 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
881 s
!= start
.end(); ++s
)
883 Changed
.push_back(std::make_pair(s
->first
, pkgCache::VerIterator(*Cache
)));
884 // We continue here even if it failed to enhance the ShowBroken output
885 Success
&= Cache
->GetDepCache()->SetCandidateRelease(s
->first
, s
->second
, Changed
);
887 for (std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> >::const_iterator c
= Changed
.begin();
888 c
!= Changed
.end(); ++c
)
890 if (c
->second
.end() == true)
891 ioprintf(out
, _("Selected version '%s' (%s) for '%s'\n"),
892 c
->first
.VerStr(), c
->first
.RelStr().c_str(), c
->first
.ParentPkg().FullName(true).c_str());
893 else if (c
->first
.ParentPkg()->Group
!= c
->second
.ParentPkg()->Group
)
895 pkgCache::VerIterator V
= (*Cache
)[c
->first
.ParentPkg()].CandidateVerIter(*Cache
);
896 ioprintf(out
, _("Selected version '%s' (%s) for '%s' because of '%s'\n"), V
.VerStr(),
897 V
.RelStr().c_str(), V
.ParentPkg().FullName(true).c_str(), c
->second
.ParentPkg().FullName(true).c_str());
903 void TryToInstall::doAutoInstall() { /*{{{*/
904 for (APT::PackageSet::const_iterator P
= doAutoInstallLater
.begin();
905 P
!= doAutoInstallLater
.end(); ++P
) {
906 pkgDepCache::StateCache
&State
= (*Cache
)[P
];
907 if (State
.InstBroken() == false && State
.InstPolicyBroken() == false)
909 Cache
->GetDepCache()->MarkInstall(P
, true);
911 doAutoInstallLater
.clear();
914 // TryToRemove - Mark a package for removal /*{{{*/
915 void TryToRemove::operator() (pkgCache::VerIterator
const &Ver
)
917 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
926 if ((Pkg
->CurrentVer
== 0 && PurgePkgs
== false) ||
927 (PurgePkgs
== true && Pkg
->CurrentState
== pkgCache::State::NotInstalled
))
929 pkgCache::GrpIterator Grp
= Pkg
.Group();
930 pkgCache::PkgIterator P
= Grp
.PackageList();
931 for (; P
.end() != true; P
= Grp
.NextPkg(P
))
935 if (P
->CurrentVer
!= 0 || (PurgePkgs
== true && P
->CurrentState
!= pkgCache::State::NotInstalled
))
937 // TRANSLATORS: Note, this is not an interactive question
938 ioprintf(c1out
,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
939 Pkg
.FullName(true).c_str(), P
.FullName(true).c_str());
944 ioprintf(c1out
,_("Package '%s' is not installed, so not removed\n"),Pkg
.FullName(true).c_str());
946 // MarkInstall refuses to install packages on hold
947 Pkg
->SelectedState
= pkgCache::State::Hold
;
950 Cache
->GetDepCache()->MarkDelete(Pkg
, PurgePkgs
);