]> git.saurik.com Git - apt.git/blame - apt-private/private-install.cc
prepare-release: travis: Ignore build profiles in build-depends
[apt.git] / apt-private / private-install.cc
CommitLineData
b9179170
MV
1// Include Files /*{{{*/
2#include <config.h>
3
453b82a3 4#include <apt-pkg/acquire.h>
b9179170 5#include <apt-pkg/acquire-item.h>
453b82a3 6#include <apt-pkg/algorithms.h>
b9179170
MV
7#include <apt-pkg/cachefile.h>
8#include <apt-pkg/cacheset.h>
453b82a3
DK
9#include <apt-pkg/cmndline.h>
10#include <apt-pkg/depcache.h>
11#include <apt-pkg/error.h>
12#include <apt-pkg/fileutl.h>
b9179170 13#include <apt-pkg/pkgrecords.h>
453b82a3
DK
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>
172947cd 22#include <apt-pkg/upgrade.h>
b58f28d4 23#include <apt-pkg/install-progress.h>
0d29b9d4 24
453b82a3
DK
25#include <stdlib.h>
26#include <string.h>
453b82a3
DK
27#include <algorithm>
28#include <iostream>
29#include <set>
30#include <vector>
eafc5435 31#include <map>
b9179170 32
453b82a3
DK
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>
b9179170
MV
39
40#include <apti18n.h>
41 /*}}}*/
453b82a3 42class pkgSourceList;
b9179170 43
b9179170
MV
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 */
48bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
49{
50 if (_config->FindB("APT::Get::Purge",false) == true)
51 {
52 pkgCache::PkgIterator I = Cache->PkgBegin();
53 for (; I.end() == false; ++I)
54 {
55 if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
56 Cache->MarkDelete(I,true);
57 }
58 }
59
b381a482
JAK
60 bool Hold = false;
61 bool Downgrade = false;
b9179170
MV
62 bool Essential = false;
63
64 // Show all the various warning indicators
65 ShowDel(c1out,Cache);
66 ShowNew(c1out,Cache);
67 if (ShwKept == true)
68 ShowKept(c1out,Cache);
b381a482 69 Hold = !ShowHold(c1out,Cache);
b9179170
MV
70 if (_config->FindB("APT::Get::Show-Upgraded",true) == true)
71 ShowUpgraded(c1out,Cache);
b381a482
JAK
72 Downgrade = !ShowDowngraded(c1out,Cache);
73
b9179170
MV
74 if (_config->FindB("APT::Get::Download-Only",false) == false)
75 Essential = !ShowEssential(c1out,Cache);
b381a482
JAK
76
77 // All kinds of failures
78 bool Fail = (Essential || Downgrade || Hold);
79
b9179170
MV
80 Stats(c1out,Cache);
81
82 // Sanity check
83 if (Cache->BrokenCount() != 0)
84 {
85 ShowBroken(c1out,Cache,false);
86 return _error->Error(_("Internal error, InstallPackages was called with broken packages!"));
87 }
88
89 if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
90 Cache->BadCount() == 0)
91 return true;
92
93 // No remove flag
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."));
b381a482
JAK
96
97 // Fail safe check
98 if (_config->FindI("quiet",0) >= 2 ||
99 _config->FindB("APT::Get::Assume-Yes",false) == true)
100 {
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."));
103 }
104
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."));
112 }
113 }
114
b9179170
MV
115 // Run the simulator ..
116 if (_config->FindB("APT::Get::Simulate") == true)
117 {
118 pkgSimulate PM(Cache);
5e9458e2 119
bd5f39b3 120 APT::Progress::PackageManager *progress = APT::Progress::PackageManagerProgressFactory();
e6ad8031
MV
121 pkgPackageManager::OrderResult Res = PM.DoInstall(progress);
122 delete progress;
5e9458e2 123
b9179170
MV
124 if (Res == pkgPackageManager::Failed)
125 return false;
126 if (Res != pkgPackageManager::Completed)
127 return _error->Error(_("Internal error, Ordering didn't finish"));
128 return true;
129 }
130
131 // Create the text record parser
132 pkgRecords Recs(Cache);
133 if (_error->PendingError() == true)
134 return false;
135
136 // Create the download object
2b0660b5 137 aptAcquireWithTextStatus Fetcher;
b9179170
MV
138 if (_config->FindB("APT::Get::Print-URIs", false) == true)
139 {
140 // force a hashsum for compatibility reasons
141 _config->CndSet("Acquire::ForceHash", "md5sum");
142 }
04a54261 143 else if (Fetcher.GetLock(_config->FindDir("Dir::Cache::Archives")) == false)
b9179170
MV
144 return false;
145
146 // Read the source list
147 if (Cache.BuildSourceList() == false)
148 return false;
149 pkgSourceList *List = Cache.GetSourceList();
150
151 // Create the package manager and prepare to download
6c413b18 152 std::unique_ptr<pkgPackageManager> PM(_system->CreatePM(Cache));
b9179170
MV
153 if (PM->GetArchives(&Fetcher,List,&Recs) == false ||
154 _error->PendingError() == true)
155 return false;
156
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())
162 {
163 c0out << DebBytes << ',' << Cache->DebSize() << std::endl;
1166ea79 164 c0out << _("How odd... The sizes didn't match, email apt@packages.debian.org") << std::endl;
b9179170
MV
165 }
166
167 // Number of bytes
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());
178
179 // Size delta
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());
185 else
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());
190
191 if (_error->PendingError() == true)
192 return false;
193
9c81f8de
DK
194 if (CheckFreeSpaceBeforeDownload(_config->FindDir("Dir::Cache::Archives"), (FetchBytes - FetchPBytes)) == false)
195 return false;
196
b381a482 197 if (Essential == true && Safety == true && _config->FindB("APT::Get::allow-remove-essential", false) == false)
b9179170
MV
198 {
199 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
200 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
201
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!");
205 ioprintf(c2out,
206 _("You are about to do something potentially harmful.\n"
207 "To continue type in the phrase '%s'\n"
208 " ?] "),Prompt);
209 c2out << std::flush;
210 if (AnalPrompt(Prompt) == false)
211 {
212 c2out << _("Abort.") << std::endl;
213 exit(1);
214 }
215 }
216 else
217 {
218 // Prompt to continue
219 if (Ask == true || Fail == true)
220 {
221 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
222 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
223
224 if (_config->FindI("quiet",0) < 2 &&
225 _config->FindB("APT::Get::Assume-Yes",false) == false)
226 {
227 c2out << _("Do you want to continue?") << std::flush;
228 if (YnPrompt() == false)
229 {
230 c2out << _("Abort.") << std::endl;
231 exit(1);
232 }
233 }
234 }
235 }
236
237 // Just print out the uris an exit if the --print-uris flag was used
238 if (_config->FindB("APT::Get::Print-URIs") == true)
239 {
240 pkgAcquire::UriIterator I = Fetcher.UriBegin();
241 for (; I != Fetcher.UriEnd(); ++I)
ac69a4d8 242 std::cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
b9179170
MV
243 I->Owner->FileSize << ' ' << I->Owner->HashSum() << std::endl;
244 return true;
245 }
246
866893a6 247 if (!CheckAuth(Fetcher, true))
b9179170
MV
248 return false;
249
250 /* Unlock the dpkg lock if we are not going to be doing an install
251 after. */
252 if (_config->FindB("APT::Get::Download-Only",false) == true)
253 _system->UnLock();
254
255 // Run it
256 while (1)
257 {
258 bool Transient = false;
259 if (_config->FindB("APT::Get::Download",true) == false)
260 {
261 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
262 {
263 if ((*I)->Local == true)
264 {
265 ++I;
266 continue;
267 }
268
269 // Close the item and check if it was found in cache
270 (*I)->Finished();
271 if ((*I)->Complete == false)
272 Transient = true;
273
274 // Clear it out of the fetch list
275 delete *I;
276 I = Fetcher.ItemsBegin();
277 }
278 }
b9179170 279
866893a6
DK
280 bool Failed = false;
281 if (AcquireRun(Fetcher, 0, &Failed, &Transient) == false)
282 return false;
b9179170
MV
283
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)
289 {
290 Transient = false;
291 Failed = true;
292 }
293
294 if (_config->FindB("APT::Get::Download-Only",false) == true)
295 {
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;
299 return true;
300 }
301
302 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
303 {
304 return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
305 }
306
307 if (Transient == true && Failed == true)
308 return _error->Error(_("--fix-missing and media swapping is not currently supported"));
309
310 // Try to deal with missing package files
311 if (Failed == true && PM->FixMissing() == false)
312 {
313 c2out << _("Unable to correct missing packages.") << std::endl;
314 return _error->Error(_("Aborting install."));
315 }
316
317 _system->UnLock();
ccf6bdb3 318
bd5f39b3 319 APT::Progress::PackageManager *progress = APT::Progress::PackageManagerProgressFactory();
e6ad8031
MV
320 pkgPackageManager::OrderResult Res = PM->DoInstall(progress);
321 delete progress;
322
b9179170
MV
323 if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
324 return false;
325 if (Res == pkgPackageManager::Completed)
326 break;
327
328 // Reload the fetcher object and loop again for media swapping
329 Fetcher.Shutdown();
330 if (PM->GetArchives(&Fetcher,List,&Recs) == false)
331 return false;
332
333 _system->Lock();
334 }
335
336 std::set<std::string> const disappearedPkgs = PM->GetDisappearedPackages();
9112f777
DK
337 if (disappearedPkgs.empty() == false)
338 {
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;
347 }
b9179170 348
ee02b5b3
MV
349 // cleanup downloaded debs
350 if (_config->FindB("APT::Keep-Downloaded-Packages", true) == false)
351 {
352 std::string const archivedir = _config->FindDir("Dir::Cache::archives");
353 for (auto I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); ++I)
354 {
355 if (flNotFile((*I)->DestFile) != archivedir || (*I)->Local)
356 continue;
357 RemoveFile("Keep-Downloaded-Packages=false", (*I)->DestFile);
358 }
359 }
360
b9179170
MV
361 return true;
362}
363 /*}}}*/
b9179170
MV
364// DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
365// ---------------------------------------------------------------------
366/* Remove unused automatic packages */
c3ccac92 367static bool DoAutomaticRemove(CacheFile &Cache)
b9179170
MV
368{
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");
372
373 pkgDepCache::ActionGroup group(*Cache);
374 if(Debug)
375 std::cout << "DoAutomaticRemove()" << std::endl;
376
377 if (doAutoRemove == true &&
378 _config->FindB("APT::Get::Remove",true) == false)
379 {
380 c1out << _("We are not supposed to delete stuff, can't start "
381 "AutoRemover") << std::endl;
382 return false;
383 }
384
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);
388
389 unsigned long autoRemoveCount = 0;
390 APT::PackageSet tooMuch;
a0c19a21 391 SortedPackageUniverse Universe(Cache);
b9179170 392 // look over the cache to see what can be removed
a0c19a21 393 for (auto const &Pkg: Universe)
b9179170 394 {
b9179170
MV
395 if (Cache[Pkg].Garbage)
396 {
397 if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
398 if(Debug)
399 std::cout << "We could delete %s" << Pkg.FullName(true).c_str() << std::endl;
400
401 if (doAutoRemove)
402 {
403 if(Pkg.CurrentVer() != 0 &&
404 Pkg->CurrentState != pkgCache::State::ConfigFiles)
405 Cache->MarkDelete(Pkg, purgePkgs, 0, false);
406 else
407 Cache->MarkKeep(Pkg, false, false);
408 }
409 else
410 {
b9179170
MV
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)
414 {
415 if (Pkg.CandVersion() != 0)
416 tooMuch.insert(Pkg);
417 Cache->MarkDelete(Pkg, false, 0, false);
418 }
419 // only show stuff in the list that is not yet marked for removal
420 else if(hideAutoRemove == false && Cache[Pkg].Delete() == false)
421 ++autoRemoveCount;
422 }
423 }
424 }
425
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))
429 {
430 bool Changed;
431 do {
432 Changed = false;
ffb081b7 433 for (APT::PackageSet::iterator Pkg = tooMuch.begin();
3a7a206f 434 Pkg != tooMuch.end(); ++Pkg)
b9179170
MV
435 {
436 APT::PackageSet too;
437 too.insert(*Pkg);
438 for (pkgCache::PrvIterator Prv = Cache[Pkg].CandidateVerIter(Cache).ProvidesList();
439 Prv.end() == false; ++Prv)
440 too.insert(Prv.ParentPkg());
3a7a206f
DK
441 for (APT::PackageSet::const_iterator P = too.begin(); P != too.end(); ++P)
442 {
b9179170
MV
443 for (pkgCache::DepIterator R = P.RevDependsList();
444 R.end() == false; ++R)
445 {
446 if (R.IsNegative() == true ||
447 Cache->IsImportantDep(R) == false)
448 continue;
449 pkgCache::PkgIterator N = R.ParentPkg();
450 if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
451 continue;
452 if (Debug == true)
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)
456 ++autoRemoveCount;
457 tooMuch.erase(Pkg);
458 Changed = true;
459 break;
460 }
3a7a206f
DK
461 if (Changed == true)
462 break;
b9179170 463 }
3a7a206f
DK
464 if (Changed == true)
465 break;
b9179170
MV
466 }
467 } while (Changed == true);
468 }
469
b9179170
MV
470 // Now see if we had destroyed anything (if we had done anything)
471 if (Cache->BrokenCount() != 0)
472 {
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;
475 c1out << std::endl;
476 c1out << _("The following information may help to resolve the situation:") << std::endl;
477 c1out << std::endl;
478 ShowBroken(c1out,Cache,false);
479
480 return _error->Error(_("Internal Error, AutoRemover broke stuff"));
481 }
482
483 // if we don't remove them, we should show them!
a0c19a21 484 if (doAutoRemove == false && autoRemoveCount != 0)
b9179170
MV
485 {
486 if (smallList == false)
a0c19a21
DK
487 {
488 SortedPackageUniverse Universe(Cache);
b9179170
MV
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:",
a0c19a21
DK
491 autoRemoveCount), Universe,
492 [&Cache](pkgCache::PkgIterator const &Pkg) { return (*Cache)[Pkg].Garbage == true && (*Cache)[Pkg].Delete() == false; },
493 &PrettyFullName, CandidateVersion(&Cache));
494 }
b9179170
MV
495 else
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);
73fe49f9
DK
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());
502 c1out << std::endl;
b9179170
MV
503 }
504 return true;
505}
506 /*}}}*/
ee0167c4 507// DoCacheManipulationFromCommandLine /*{{{*/
d8a8f9d7
MV
508static const unsigned short MOD_REMOVE = 1;
509static const unsigned short MOD_INSTALL = 2;
b9179170 510
172947cd 511bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, int UpgradeMode)
14341a7e
DK
512{
513 std::vector<const char*> VolatileCmdL;
514 return DoCacheManipulationFromCommandLine(CmdL, VolatileCmdL, Cache, UpgradeMode);
515}
516bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<const char*> &VolatileCmdL, CacheFile &Cache, int UpgradeMode)
d8a8f9d7
MV
517{
518 std::map<unsigned short, APT::VersionSet> verset;
14341a7e 519 return DoCacheManipulationFromCommandLine(CmdL, VolatileCmdL, Cache, verset, UpgradeMode);
d8a8f9d7 520}
14341a7e 521bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<const char*> &VolatileCmdL, CacheFile &Cache,
172947cd 522 std::map<unsigned short, APT::VersionSet> &verset, int UpgradeMode)
b9179170 523{
b9179170
MV
524 // Enter the special broken fixing mode if the user specified arguments
525 bool BrokenFix = false;
526 if (Cache->BrokenCount() != 0)
527 BrokenFix = true;
528
6c413b18 529 std::unique_ptr<pkgProblemResolver> Fix(nullptr);
b9179170 530 if (_config->FindB("APT::Get::CallResolver", true) == true)
6c413b18 531 Fix.reset(new pkgProblemResolver(Cache));
b9179170 532
b9179170
MV
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)
537 {
538 _config->Set("APT::Get::Purge", true);
539 fallback = MOD_REMOVE;
540 }
f66738d7
JAK
541 else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0 ||
542 strcasecmp(CmdL.FileList[0], "auto-remove") == 0)
b9179170
MV
543 {
544 _config->Set("APT::Get::AutomaticRemove", "true");
545 fallback = MOD_REMOVE;
546 }
547
548 std::list<APT::VersionSet::Modifier> mods;
549 mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+",
e6f0c9bc 550 APT::VersionSet::Modifier::POSTFIX, APT::CacheSetHelper::CANDIDATE));
b9179170 551 mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-",
e6f0c9bc 552 APT::VersionSet::Modifier::POSTFIX, APT::CacheSetHelper::NEWEST));
b9179170 553 CacheSetHelperAPTGet helper(c0out);
d8a8f9d7 554 verset = APT::VersionSet::GroupedFromCommandLine(Cache,
b9179170
MV
555 CmdL.FileList + 1, mods, fallback, helper);
556
14341a7e
DK
557 for (auto const &I: VolatileCmdL)
558 {
559 pkgCache::PkgIterator const P = Cache->FindPkg(I);
560 if (P.end())
561 continue;
562
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());
566
567 // via cacheset to have our usual virtual handling
568 APT::VersionContainerInterface::FromPackage(&(verset[MOD_INSTALL]), Cache, P, APT::CacheSetHelper::CANDIDATE, helper);
569 }
570
b9179170
MV
571 if (_error->PendingError() == true)
572 {
573 helper.showVirtualPackageErrors(Cache);
b9179170
MV
574 return false;
575 }
576
577
6c413b18
JAK
578 TryToInstall InstallAction(Cache, Fix.get(), BrokenFix);
579 TryToRemove RemoveAction(Cache, Fix.get());
b9179170
MV
580
581 // new scope for the ActionGroup
582 {
583 pkgDepCache::ActionGroup group(Cache);
584 unsigned short const order[] = { MOD_REMOVE, MOD_INSTALL, 0 };
585
586 for (unsigned short i = 0; order[i] != 0; ++i)
587 {
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);
592 }
593
594 if (Fix != NULL && _config->FindB("APT::Get::AutoSolving", true) == true)
595 {
9777639e
DK
596 InstallAction.propergateReleaseCandiateSwitching(helper.selectedByRelease, c0out);
597 InstallAction.doAutoInstall();
b9179170
MV
598 }
599
600 if (_error->PendingError() == true)
601 {
b9179170
MV
602 return false;
603 }
604
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
607 packages */
608 if (BrokenFix == true && Cache->BrokenCount() != 0)
609 {
610 c1out << _("You might want to run 'apt-get -f install' to correct these:") << std::endl;
611 ShowBroken(c1out,Cache,false);
b9179170
MV
612 return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
613 }
614
615 if (Fix != NULL)
616 {
617 // Call the scored problem resolver
2a884c61
DK
618 OpTextProgress Progress(*_config);
619 bool const distUpgradeMode = strcmp(CmdL.FileList[0], "dist-upgrade") == 0 || strcmp(CmdL.FileList[0], "full-upgrade") == 0;
620
67caa2e6
DK
621 bool resolver_fail = false;
622 if (distUpgradeMode == true || UpgradeMode != APT::Upgrade::ALLOW_EVERYTHING)
2a884c61 623 resolver_fail = APT::Upgrade::Upgrade(Cache, UpgradeMode, &Progress);
67caa2e6
DK
624 else
625 resolver_fail = Fix->Resolve(true, &Progress);
172947cd
DK
626
627 if (resolver_fail == false && Cache->BrokenCount() == 0)
58377ceb 628 return false;
b9179170
MV
629 }
630
631 // Now we check the state of the packages,
632 if (Cache->BrokenCount() != 0)
633 {
634 c1out <<
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;
639 /*
640 if (Packages == 1)
641 {
642 c1out << std::endl;
643 c1out <<
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;
647 }
648 */
649
650 c1out << _("The following information may help to resolve the situation:") << std::endl;
651 c1out << std::endl;
652 ShowBroken(c1out,Cache,false);
653 if (_error->PendingError() == true)
654 return false;
655 else
656 return _error->Error(_("Broken packages"));
657 }
658 }
659 if (!DoAutomaticRemove(Cache))
660 return false;
661
d8a8f9d7
MV
662 // if nothing changed in the cache, but only the automark information
663 // we write the StateFile here, otherwise it will be written in
664 // cache.commit()
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);
670
671 return true;
672}
ee0167c4 673 /*}}}*/
d8a8f9d7
MV
674// DoInstall - Install packages from the command line /*{{{*/
675// ---------------------------------------------------------------------
676/* Install named packages */
a0c19a21
DK
677struct 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) {}
258b9e51 681 bool operator() (pkgCache::PkgIterator const &Pkg)
a0c19a21
DK
682 {
683 if ((*Cache)[Pkg].Install() == false)
684 return false;
685 pkgCache::VerIterator const Cand = (*Cache)[Pkg].CandidateVerIter(*Cache);
686 return verset->find(Cand) == verset->end();
687 }
688};
d8a8f9d7
MV
689bool DoInstall(CommandLine &CmdL)
690{
691 CacheFile Cache;
14341a7e
DK
692 std::vector<char const *> VolatileCmdL;
693 Cache.GetSourceList()->AddVolatileFiles(CmdL, &VolatileCmdL);
0d29b9d4
MV
694
695 // then open the cache
d8a8f9d7
MV
696 if (Cache.OpenForInstall() == false ||
697 Cache.CheckDeps(CmdL.FileSize() != 1) == false)
698 return false;
848fd2a6 699
14341a7e
DK
700 std::map<unsigned short, APT::VersionSet> verset;
701 if(!DoCacheManipulationFromCommandLine(CmdL, VolatileCmdL, Cache, verset, 0))
d8a8f9d7
MV
702 return false;
703
b9179170
MV
704 /* Print out a list of packages that are going to be installed extra
705 to what the user asked */
a0c19a21 706 SortedPackageUniverse Universe(Cache);
b9179170 707 if (Cache->InstCount() != verset[MOD_INSTALL].size())
1040dc88 708 ShowList(c1out, _("The following additional packages will be installed:"), Universe,
a0c19a21
DK
709 PkgIsExtraInstalled(&Cache, &verset[MOD_INSTALL]),
710 &PrettyFullName, CandidateVersion(&Cache));
b9179170
MV
711
712 /* Print out a list of suggested and recommended packages */
713 {
9112f777 714 std::list<std::string> Recommends, Suggests, SingleRecommends, SingleSuggests;
a0c19a21 715 for (auto const &Pkg: Universe)
b9179170 716 {
b9179170
MV
717 /* Just look at the ones we want to install */
718 if ((*Cache)[Pkg].Install() == false)
719 continue;
720
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; )
724 {
725 pkgCache::DepIterator Start;
726 pkgCache::DepIterator End;
727 D.GlobOr(Start,End); // advances D
9112f777
DK
728 if (Start->Type != pkgCache::Dep::Recommends && Start->Type != pkgCache::Dep::Suggests)
729 continue;
b9179170 730
b9179170 731 {
9112f777
DK
732 // Skip if we already saw this
733 std::string target;
734 for (pkgCache::DepIterator I = Start; I != D; ++I)
b9179170 735 {
9112f777
DK
736 if (target.empty() == false)
737 target.append(" | ");
738 target.append(I.TargetPkg().FullName(true));
b9179170 739 }
9112f777
DK
740 std::list<std::string> &Type = Start->Type == pkgCache::Dep::Recommends ? SingleRecommends : SingleSuggests;
741 if (std::find(Type.begin(), Type.end(), target) != Type.end())
742 continue;
743 Type.push_back(target);
744 }
b9179170 745
9112f777
DK
746 std::list<std::string> OrList;
747 bool foundInstalledInOrGroup = false;
748 for (pkgCache::DepIterator I = Start; I != D; ++I)
749 {
b9179170 750 {
9112f777
DK
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())
b9179170 755 {
9112f777
DK
756 foundInstalledInOrGroup = true;
757 break;
b9179170
MV
758 }
759 }
760
b9179170 761 {
9112f777
DK
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())
766 {
767 foundInstalledInOrGroup = true;
768 break;
769 }
b9179170
MV
770 }
771
9112f777
DK
772 if (OrList.empty())
773 OrList.push_back(I.TargetPkg().FullName(true));
774 else
775 OrList.push_back("| " + I.TargetPkg().FullName(true));
b9179170 776 }
9112f777 777
b9179170
MV
778 if(foundInstalledInOrGroup == false)
779 {
9112f777
DK
780 std::list<std::string> &Type = Start->Type == pkgCache::Dep::Recommends ? Recommends : Suggests;
781 std::move(OrList.begin(), OrList.end(), std::back_inserter(Type));
b9179170 782 }
b9179170
MV
783 }
784 }
9112f777
DK
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)
789 {
790 if (APT::String::Startswith(str, "| "))
791 str.erase(0, 2);
792 pkgCache::PkgIterator const Pkg = Cache->FindPkg(str);
793 if (Pkg.end() == true)
794 return "";
795 return (*Cache)[Pkg].CandVersion;
796 };
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);
b9179170
MV
801 }
802
b9179170
MV
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);
807
9112f777 808 return InstallPackages(Cache,false);
b9179170
MV
809}
810 /*}}}*/
4d695011
DK
811
812// TryToInstall - Mark a package for installation /*{{{*/
813void TryToInstall::operator() (pkgCache::VerIterator const &Ver) {
814 pkgCache::PkgIterator Pkg = Ver.ParentPkg();
815
816 Cache->GetDepCache()->SetCandidateVersion(Ver);
817 pkgDepCache::StateCache &State = (*Cache)[Pkg];
818
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());
827 else {
828 if (Fix != NULL) {
829 Fix->Clear(Pkg);
830 Fix->Protect(Pkg);
831 }
832 Cache->GetDepCache()->MarkInstall(Pkg,false);
833
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());
839 else
840 Cache->GetDepCache()->SetReInstall(Pkg, true);
841 } else
3b9eaca8
JAK
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());
4d695011
DK
845 }
846
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);
851 }
852
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)
861 {
862 ioprintf(c1out,_("%s set to manually installed.\n"),
863 Pkg.FullName(true).c_str());
864 Cache->GetDepCache()->MarkAuto(Pkg,false);
865 AutoMarkChanged++;
866 }
867}
868 /*}}}*/
869bool TryToInstall::propergateReleaseCandiateSwitching(std::list<std::pair<pkgCache::VerIterator, std::string> > const &start, std::ostream &out)/*{{{*/
870{
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);
874
875 bool Success = true;
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)
882 {
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);
886 }
887 for (std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::const_iterator c = Changed.begin();
888 c != Changed.end(); ++c)
889 {
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)
894 {
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());
898 }
899 }
900 return Success;
901}
902 /*}}}*/
903void 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)
908 continue;
909 Cache->GetDepCache()->MarkInstall(P, true);
910 }
911 doAutoInstallLater.clear();
912}
913 /*}}}*/
914// TryToRemove - Mark a package for removal /*{{{*/
915void TryToRemove::operator() (pkgCache::VerIterator const &Ver)
916{
917 pkgCache::PkgIterator Pkg = Ver.ParentPkg();
918
919 if (Fix != NULL)
920 {
921 Fix->Clear(Pkg);
922 Fix->Protect(Pkg);
923 Fix->Remove(Pkg);
924 }
925
926 if ((Pkg->CurrentVer == 0 && PurgePkgs == false) ||
927 (PurgePkgs == true && Pkg->CurrentState == pkgCache::State::NotInstalled))
928 {
929 pkgCache::GrpIterator Grp = Pkg.Group();
930 pkgCache::PkgIterator P = Grp.PackageList();
931 for (; P.end() != true; P = Grp.NextPkg(P))
932 {
933 if (P == Pkg)
934 continue;
935 if (P->CurrentVer != 0 || (PurgePkgs == true && P->CurrentState != pkgCache::State::NotInstalled))
936 {
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());
940 break;
941 }
942 }
943 if (P.end() == true)
944 ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str());
945
946 // MarkInstall refuses to install packages on hold
947 Pkg->SelectedState = pkgCache::State::Hold;
948 }
949 else
950 Cache->GetDepCache()->MarkDelete(Pkg, PurgePkgs);
951}
952 /*}}}*/