]> git.saurik.com Git - apt.git/blob - apt-private/private-install.cc
edsp: try 2 to read responses even if writing failed
[apt.git] / apt-private / private-install.cc
1 // Include Files /*{{{*/
2 #include <config.h>
3
4 #include <apt-pkg/acquire.h>
5 #include <apt-pkg/acquire-item.h>
6 #include <apt-pkg/algorithms.h>
7 #include <apt-pkg/cachefile.h>
8 #include <apt-pkg/cacheset.h>
9 #include <apt-pkg/cmndline.h>
10 #include <apt-pkg/depcache.h>
11 #include <apt-pkg/error.h>
12 #include <apt-pkg/fileutl.h>
13 #include <apt-pkg/pkgrecords.h>
14 #include <apt-pkg/pkgsystem.h>
15 #include <apt-pkg/sptr.h>
16 #include <apt-pkg/strutl.h>
17 #include <apt-pkg/cacheiterators.h>
18 #include <apt-pkg/configuration.h>
19 #include <apt-pkg/macros.h>
20 #include <apt-pkg/packagemanager.h>
21 #include <apt-pkg/pkgcache.h>
22 #include <apt-pkg/upgrade.h>
23 #include <apt-pkg/install-progress.h>
24 #include <apt-pkg/prettyprinters.h>
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <algorithm>
29 #include <iostream>
30 #include <set>
31 #include <vector>
32 #include <map>
33
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>
40
41 #include <apti18n.h>
42 /*}}}*/
43 class pkgSourceList;
44
45 bool CheckNothingBroken(CacheFile &Cache) /*{{{*/
46 {
47 // Now we check the state of the packages,
48 if (Cache->BrokenCount() == 0)
49 return true;
50
51 // FIXME: if an external solver showed an error, we shouldn't show one here
52 if (_error->PendingError() && _config->Find("APT::Solver") == "dump")
53 return false;
54
55 c1out <<
56 _("Some packages could not be installed. This may mean that you have\n"
57 "requested an impossible situation or if you are using the unstable\n"
58 "distribution that some required packages have not yet been created\n"
59 "or been moved out of Incoming.") << std::endl;
60 /*
61 if (Packages == 1)
62 {
63 c1out << std::endl;
64 c1out <<
65 _("Since you only requested a single operation it is extremely likely that\n"
66 "the package is simply not installable and a bug report against\n"
67 "that package should be filed.") << std::endl;
68 }
69 */
70
71 c1out << _("The following information may help to resolve the situation:") << std::endl;
72 c1out << std::endl;
73 ShowBroken(c1out,Cache,false);
74 if (_error->PendingError() == true)
75 return false;
76 else
77 return _error->Error(_("Broken packages"));
78 }
79 /*}}}*/
80 // InstallPackages - Actually download and install the packages /*{{{*/
81 // ---------------------------------------------------------------------
82 /* This displays the informative messages describing what is going to
83 happen and then calls the download routines */
84 static void RemoveDownloadNeedingItemsFromFetcher(pkgAcquire &Fetcher, bool &Transient)
85 {
86 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
87 {
88 if ((*I)->Local == true)
89 {
90 ++I;
91 continue;
92 }
93
94 // Close the item and check if it was found in cache
95 (*I)->Finished();
96 if ((*I)->Complete == false)
97 Transient = true;
98
99 // Clear it out of the fetch list
100 delete *I;
101 I = Fetcher.ItemsBegin();
102 }
103 }
104 bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
105 {
106 if (_config->FindB("APT::Get::Purge", false) == true)
107 for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; ++I)
108 if (Cache[I].Delete() == true && Cache[I].Purge() == false)
109 Cache->MarkDelete(I,true);
110
111 // Create the download object
112 aptAcquireWithTextStatus Fetcher;
113 if (_config->FindB("APT::Get::Print-URIs", false) == true)
114 {
115 // force a hashsum for compatibility reasons
116 _config->CndSet("Acquire::ForceHash", "md5sum");
117 }
118 else if (_config->FindB("APT::Get::Simulate") == true)
119 ;
120 else if (Fetcher.GetLock(_config->FindDir("Dir::Cache::Archives")) == false)
121 return false;
122
123 // Read the source list
124 if (Cache.BuildSourceList() == false)
125 return false;
126 pkgSourceList * const List = Cache.GetSourceList();
127
128 // Create the text record parser
129 pkgRecords Recs(Cache);
130 if (_error->PendingError() == true)
131 return false;
132
133 // Create the package manager and prepare to download
134 std::unique_ptr<pkgPackageManager> PM(_system->CreatePM(Cache));
135 if (PM->GetArchives(&Fetcher,List,&Recs) == false ||
136 _error->PendingError() == true)
137 return false;
138
139 if (_config->FindB("APT::Get::Fix-Missing",false) == true &&
140 _config->FindB("APT::Get::Download",true) == false)
141 {
142 bool Missing = false;
143 RemoveDownloadNeedingItemsFromFetcher(Fetcher, Missing);
144 if (Missing)
145 PM->FixMissing();
146 Fetcher.Shutdown();
147 if (PM->GetArchives(&Fetcher,List,&Recs) == false ||
148 _error->PendingError() == true)
149 return false;
150 }
151
152 // Show all the various warning indicators
153 ShowDel(c1out,Cache);
154 ShowNew(c1out,Cache);
155 if (ShwKept == true)
156 ShowKept(c1out,Cache);
157 bool const Hold = !ShowHold(c1out,Cache);
158 if (_config->FindB("APT::Get::Show-Upgraded",true) == true)
159 ShowUpgraded(c1out,Cache);
160 bool const Downgrade = !ShowDowngraded(c1out,Cache);
161
162 bool Essential = false;
163 if (_config->FindB("APT::Get::Download-Only",false) == false)
164 Essential = !ShowEssential(c1out,Cache);
165
166 Stats(c1out,Cache);
167
168 // Sanity check
169 if (Cache->BrokenCount() != 0)
170 {
171 ShowBroken(c1out,Cache,false);
172 return _error->Error(_("Internal error, InstallPackages was called with broken packages!"));
173 }
174
175 if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
176 Cache->BadCount() == 0)
177 return true;
178
179 // No remove flag
180 if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
181 return _error->Error(_("Packages need to be removed but remove is disabled."));
182
183 // Fail safe check
184 bool const Fail = (Essential || Downgrade || Hold);
185 if (_config->FindI("quiet",0) >= 2 ||
186 _config->FindB("APT::Get::Assume-Yes",false) == true)
187 {
188 if (_config->FindB("APT::Get::Force-Yes",false) == true) {
189 _error->Warning(_("--force-yes is deprecated, use one of the options starting with --allow instead."));
190 }
191
192 if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false) {
193 if (Essential == true && _config->FindB("APT::Get::allow-remove-essential", false) == false)
194 return _error->Error(_("Essential packages were removed and -y was used without --allow-remove-essential."));
195 if (Downgrade == true && _config->FindB("APT::Get::allow-downgrades", false) == false)
196 return _error->Error(_("Packages were downgraded and -y was used without --allow-downgrades."));
197 if (Hold == true && _config->FindB("APT::Get::allow-change-held-packages", false) == false)
198 return _error->Error(_("Held packages were changed and -y was used without --allow-change-held-packages."));
199 }
200 }
201
202 // Run the simulator ..
203 if (_config->FindB("APT::Get::Simulate") == true)
204 {
205 pkgSimulate PM(Cache);
206
207 APT::Progress::PackageManager *progress = APT::Progress::PackageManagerProgressFactory();
208 pkgPackageManager::OrderResult Res = PM.DoInstall(progress);
209 delete progress;
210
211 if (Res == pkgPackageManager::Failed)
212 return false;
213 if (Res != pkgPackageManager::Completed)
214 return _error->Error(_("Internal error, Ordering didn't finish"));
215 return true;
216 }
217
218 // Display statistics
219 auto const FetchBytes = Fetcher.FetchNeeded();
220 auto const FetchPBytes = Fetcher.PartialPresent();
221 auto const DebBytes = Fetcher.TotalNeeded();
222 if (DebBytes != Cache->DebSize())
223 {
224 c0out << DebBytes << ',' << Cache->DebSize() << std::endl;
225 c0out << _("How odd... The sizes didn't match, email apt@packages.debian.org") << std::endl;
226 }
227
228 // Number of bytes
229 if (DebBytes != FetchBytes)
230 //TRANSLATOR: The required space between number and unit is already included
231 // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
232 ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"),
233 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
234 else if (DebBytes != 0)
235 //TRANSLATOR: The required space between number and unit is already included
236 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
237 ioprintf(c1out,_("Need to get %sB of archives.\n"),
238 SizeToStr(DebBytes).c_str());
239
240 // Size delta
241 if (Cache->UsrSize() >= 0)
242 //TRANSLATOR: The required space between number and unit is already included
243 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
244 ioprintf(c1out,_("After this operation, %sB of additional disk space will be used.\n"),
245 SizeToStr(Cache->UsrSize()).c_str());
246 else
247 //TRANSLATOR: The required space between number and unit is already included
248 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
249 ioprintf(c1out,_("After this operation, %sB disk space will be freed.\n"),
250 SizeToStr(-1*Cache->UsrSize()).c_str());
251
252 if (CheckFreeSpaceBeforeDownload(_config->FindDir("Dir::Cache::Archives"), (FetchBytes - FetchPBytes)) == false)
253 return false;
254
255 if (_error->PendingError() == true)
256 return false;
257
258 // Just print out the uris an exit if the --print-uris flag was used
259 if (_config->FindB("APT::Get::Print-URIs") == true)
260 {
261 pkgAcquire::UriIterator I = Fetcher.UriBegin();
262 for (; I != Fetcher.UriEnd(); ++I)
263 std::cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
264 std::to_string(I->Owner->FileSize) << ' ' << I->Owner->HashSum() << std::endl;
265 return true;
266 }
267
268 if (Essential == true && Safety == true && _config->FindB("APT::Get::allow-remove-essential", false) == false)
269 {
270 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
271 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
272
273 // TRANSLATOR: This string needs to be typed by the user as a confirmation, so be
274 // careful with hard to type or special characters (like non-breaking spaces)
275 const char *Prompt = _("Yes, do as I say!");
276 std::string question;
277 strprintf(question,
278 _("You are about to do something potentially harmful.\n"
279 "To continue type in the phrase '%s'\n"
280 " ?] "),Prompt);
281 if (AnalPrompt(question, Prompt) == false)
282 {
283 c2out << _("Abort.") << std::endl;
284 exit(1);
285 }
286 }
287 else
288 {
289 // Prompt to continue
290 if (Ask == true || Fail == true)
291 {
292 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
293 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
294
295 if (_config->FindI("quiet",0) < 2 &&
296 _config->FindB("APT::Get::Assume-Yes",false) == false)
297 {
298 if (YnPrompt(_("Do you want to continue?")) == false)
299 {
300 c2out << _("Abort.") << std::endl;
301 exit(1);
302 }
303 }
304 }
305 }
306
307 if (!CheckAuth(Fetcher, true))
308 return false;
309
310 /* Unlock the dpkg lock if we are not going to be doing an install
311 after. */
312 if (_config->FindB("APT::Get::Download-Only",false) == true)
313 _system->UnLock();
314
315 // Run it
316 bool Failed = false;
317 while (1)
318 {
319 bool Transient = false;
320 if (AcquireRun(Fetcher, 0, &Failed, &Transient) == false)
321 return false;
322
323 if (_config->FindB("APT::Get::Download-Only",false) == true)
324 {
325 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
326 return _error->Error(_("Some files failed to download"));
327 c1out << _("Download complete and in download only mode") << std::endl;
328 return true;
329 }
330
331 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
332 return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
333
334 if (Transient == true && Failed == true)
335 return _error->Error(_("--fix-missing and media swapping is not currently supported"));
336
337 // Try to deal with missing package files
338 if (Failed == true && PM->FixMissing() == false)
339 {
340 c2out << _("Unable to correct missing packages.") << std::endl;
341 return _error->Error(_("Aborting install."));
342 }
343
344 auto const progress = APT::Progress::PackageManagerProgressFactory();
345 _system->UnLock();
346 pkgPackageManager::OrderResult const Res = PM->DoInstall(progress);
347 delete progress;
348
349 if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
350 return false;
351 if (Res == pkgPackageManager::Completed)
352 break;
353
354 _system->Lock();
355
356 // Reload the fetcher object and loop again for media swapping
357 Fetcher.Shutdown();
358 if (PM->GetArchives(&Fetcher,List,&Recs) == false)
359 return false;
360
361 Failed = false;
362 if (_config->FindB("APT::Get::Download",true) == false)
363 RemoveDownloadNeedingItemsFromFetcher(Fetcher, Failed);
364 }
365
366 std::set<std::string> const disappearedPkgs = PM->GetDisappearedPackages();
367 if (disappearedPkgs.empty() == false)
368 {
369 ShowList(c1out, P_("The following package disappeared from your system as\n"
370 "all files have been overwritten by other packages:",
371 "The following packages disappeared from your system as\n"
372 "all files have been overwritten by other packages:", disappearedPkgs.size()), disappearedPkgs,
373 [](std::string const &Pkg) { return Pkg.empty() == false; },
374 [](std::string const &Pkg) { return Pkg; },
375 [](std::string const &) { return std::string(); });
376 c0out << _("Note: This is done automatically and on purpose by dpkg.") << std::endl;
377 }
378
379 // cleanup downloaded debs
380 if (_config->FindB("APT::Keep-Downloaded-Packages", true) == false)
381 {
382 std::string const archivedir = _config->FindDir("Dir::Cache::archives");
383 for (auto I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); ++I)
384 {
385 if (flNotFile((*I)->DestFile) != archivedir || (*I)->Local)
386 continue;
387 RemoveFile("Keep-Downloaded-Packages=false", (*I)->DestFile);
388 }
389 }
390
391 return true;
392 }
393 /*}}}*/
394 // DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
395 // ---------------------------------------------------------------------
396 /* Remove unused automatic packages */
397 bool DoAutomaticRemove(CacheFile &Cache)
398 {
399 bool Debug = _config->FindI("Debug::pkgAutoRemove",false);
400 bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false);
401 bool hideAutoRemove = _config->FindB("APT::Get::HideAutoRemove");
402
403 pkgDepCache::ActionGroup group(*Cache);
404 if(Debug)
405 std::cout << "DoAutomaticRemove()" << std::endl;
406
407 if (doAutoRemove == true &&
408 _config->FindB("APT::Get::Remove",true) == false)
409 {
410 c1out << _("We are not supposed to delete stuff, can't start "
411 "AutoRemover") << std::endl;
412 return false;
413 }
414
415 bool purgePkgs = _config->FindB("APT::Get::Purge", false);
416 bool smallList = (hideAutoRemove == false &&
417 strcasecmp(_config->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
418
419 unsigned long autoRemoveCount = 0;
420 APT::PackageSet tooMuch;
421 SortedPackageUniverse Universe(Cache);
422 // look over the cache to see what can be removed
423 for (auto const &Pkg: Universe)
424 {
425 if (Cache[Pkg].Garbage)
426 {
427 if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
428 if(Debug)
429 std::cout << "We could delete %s" << Pkg.FullName(true).c_str() << std::endl;
430
431 if (doAutoRemove)
432 {
433 if(Pkg.CurrentVer() != 0 &&
434 Pkg->CurrentState != pkgCache::State::ConfigFiles)
435 Cache->MarkDelete(Pkg, purgePkgs, 0, false);
436 else
437 Cache->MarkKeep(Pkg, false, false);
438 }
439 else
440 {
441 // if the package is a new install and already garbage we don't need to
442 // install it in the first place, so nuke it instead of show it
443 if (Cache[Pkg].Install() == true && Pkg.CurrentVer() == 0)
444 {
445 tooMuch.insert(Pkg);
446 Cache->MarkDelete(Pkg, false, 0, false);
447 }
448 // only show stuff in the list that is not yet marked for removal
449 else if(hideAutoRemove == false && Cache[Pkg].Delete() == false)
450 ++autoRemoveCount;
451 }
452 }
453 }
454
455 // we could have removed a new dependency of a garbage package,
456 // so check if a reverse depends is broken and if so install it again.
457 if (tooMuch.empty() == false && (Cache->BrokenCount() != 0 || Cache->PolicyBrokenCount() != 0))
458 {
459 bool Changed;
460 do {
461 Changed = false;
462 for (APT::PackageSet::iterator Pkg = tooMuch.begin();
463 Pkg != tooMuch.end(); ++Pkg)
464 {
465 APT::PackageSet too;
466 too.insert(*Pkg);
467 for (pkgCache::PrvIterator Prv = Cache[Pkg].CandidateVerIter(Cache).ProvidesList();
468 Prv.end() == false; ++Prv)
469 too.insert(Prv.ParentPkg());
470 for (APT::PackageSet::const_iterator P = too.begin(); P != too.end(); ++P)
471 {
472 for (pkgCache::DepIterator R = P.RevDependsList();
473 R.end() == false; ++R)
474 {
475 if (R.IsNegative() == true ||
476 Cache->IsImportantDep(R) == false)
477 continue;
478 pkgCache::PkgIterator N = R.ParentPkg();
479 if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
480 continue;
481 if (Debug == true)
482 std::clog << "Save " << APT::PrettyPkg(Cache, Pkg) << " as another installed garbage package depends on it" << std::endl;
483 Cache->MarkInstall(Pkg, false, 0, false);
484 if (hideAutoRemove == false)
485 ++autoRemoveCount;
486 tooMuch.erase(Pkg);
487 Changed = true;
488 break;
489 }
490 if (Changed == true)
491 break;
492 }
493 if (Changed == true)
494 break;
495 }
496 } while (Changed == true);
497 }
498
499 // Now see if we had destroyed anything (if we had done anything)
500 if (Cache->BrokenCount() != 0)
501 {
502 c1out << _("Hmm, seems like the AutoRemover destroyed something which really\n"
503 "shouldn't happen. Please file a bug report against apt.") << std::endl;
504 c1out << std::endl;
505 c1out << _("The following information may help to resolve the situation:") << std::endl;
506 c1out << std::endl;
507 ShowBroken(c1out,Cache,false);
508
509 return _error->Error(_("Internal Error, AutoRemover broke stuff"));
510 }
511
512 // if we don't remove them, we should show them!
513 if (doAutoRemove == false && autoRemoveCount != 0)
514 {
515 if (smallList == false)
516 {
517 SortedPackageUniverse Universe(Cache);
518 ShowList(c1out, P_("The following package was automatically installed and is no longer required:",
519 "The following packages were automatically installed and are no longer required:",
520 autoRemoveCount), Universe,
521 [&Cache](pkgCache::PkgIterator const &Pkg) { return (*Cache)[Pkg].Garbage == true && (*Cache)[Pkg].Delete() == false; },
522 &PrettyFullName, CandidateVersion(&Cache));
523 }
524 else
525 ioprintf(c1out, P_("%lu package was automatically installed and is no longer required.\n",
526 "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount), autoRemoveCount);
527 std::string autocmd = "apt autoremove";
528 if (getenv("SUDO_USER") != nullptr)
529 {
530 auto const envsudocmd = getenv("SUDO_COMMAND");
531 auto const envshell = getenv("SHELL");
532 if (envsudocmd == nullptr || envshell == nullptr || strcmp(envsudocmd, envshell) != 0)
533 autocmd = "sudo " + autocmd;
534 }
535 ioprintf(c1out, P_("Use '%s' to remove it.", "Use '%s' to remove them.", autoRemoveCount), autocmd.c_str());
536 c1out << std::endl;
537 }
538 return true;
539 }
540 /*}}}*/
541 // DoCacheManipulationFromCommandLine /*{{{*/
542 static const unsigned short MOD_REMOVE = 1;
543 static const unsigned short MOD_INSTALL = 2;
544
545 bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, int UpgradeMode)
546 {
547 std::vector<std::string> VolatileCmdL;
548 return DoCacheManipulationFromCommandLine(CmdL, VolatileCmdL, Cache, UpgradeMode);
549 }
550 bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<std::string> &VolatileCmdL, CacheFile &Cache, int UpgradeMode)
551 {
552 std::map<unsigned short, APT::VersionSet> verset;
553 return DoCacheManipulationFromCommandLine(CmdL, VolatileCmdL, Cache, verset, UpgradeMode);
554 }
555 bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vector<std::string> &VolatileCmdL, CacheFile &Cache,
556 std::map<unsigned short, APT::VersionSet> &verset, int UpgradeMode)
557 {
558 // Enter the special broken fixing mode if the user specified arguments
559 bool BrokenFix = false;
560 if (Cache->BrokenCount() != 0)
561 BrokenFix = true;
562
563 std::unique_ptr<pkgProblemResolver> Fix(nullptr);
564 if (_config->FindB("APT::Get::CallResolver", true) == true)
565 Fix.reset(new pkgProblemResolver(Cache));
566
567 unsigned short fallback = MOD_INSTALL;
568 if (strcasecmp(CmdL.FileList[0],"remove") == 0)
569 fallback = MOD_REMOVE;
570 else if (strcasecmp(CmdL.FileList[0], "purge") == 0)
571 {
572 _config->Set("APT::Get::Purge", true);
573 fallback = MOD_REMOVE;
574 }
575 else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0 ||
576 strcasecmp(CmdL.FileList[0], "auto-remove") == 0)
577 {
578 _config->Set("APT::Get::AutomaticRemove", "true");
579 fallback = MOD_REMOVE;
580 }
581
582 std::list<APT::VersionSet::Modifier> mods;
583 mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+",
584 APT::VersionSet::Modifier::POSTFIX, APT::CacheSetHelper::CANDIDATE));
585 mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-",
586 APT::VersionSet::Modifier::POSTFIX, APT::CacheSetHelper::NEWEST));
587 CacheSetHelperAPTGet helper(c0out);
588 verset = APT::VersionSet::GroupedFromCommandLine(Cache,
589 CmdL.FileList + 1, mods, fallback, helper);
590
591 for (auto const &I: VolatileCmdL)
592 {
593 pkgCache::PkgIterator const P = Cache->FindPkg(I);
594 if (P.end())
595 continue;
596
597 // Set any version providing the .deb as the candidate.
598 for (auto Prv = P.ProvidesList(); Prv.end() == false; Prv++)
599 Cache.GetDepCache()->SetCandidateVersion(Prv.OwnerVer());
600
601 // via cacheset to have our usual virtual handling
602 APT::VersionContainerInterface::FromPackage(&(verset[MOD_INSTALL]), Cache, P, APT::CacheSetHelper::CANDIDATE, helper);
603 }
604
605 if (_error->PendingError() == true)
606 {
607 helper.showVirtualPackageErrors(Cache);
608 return false;
609 }
610
611
612 TryToInstall InstallAction(Cache, Fix.get(), BrokenFix);
613 TryToRemove RemoveAction(Cache, Fix.get());
614
615 // new scope for the ActionGroup
616 {
617 pkgDepCache::ActionGroup group(Cache);
618 unsigned short const order[] = { MOD_REMOVE, MOD_INSTALL, 0 };
619
620 for (unsigned short i = 0; order[i] != 0; ++i)
621 {
622 if (order[i] == MOD_INSTALL)
623 InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction);
624 else if (order[i] == MOD_REMOVE)
625 RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction);
626 }
627
628 if (Fix != NULL && _config->FindB("APT::Get::AutoSolving", true) == true)
629 {
630 InstallAction.propergateReleaseCandiateSwitching(helper.selectedByRelease, c0out);
631 InstallAction.doAutoInstall();
632 }
633
634 if (_error->PendingError() == true)
635 {
636 return false;
637 }
638
639 /* If we are in the Broken fixing mode we do not attempt to fix the
640 problems. This is if the user invoked install without -f and gave
641 packages */
642 if (BrokenFix == true && Cache->BrokenCount() != 0)
643 {
644 c1out << _("You might want to run 'apt-get -f install' to correct these:") << std::endl;
645 ShowBroken(c1out,Cache,false);
646 return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
647 }
648
649 if (Fix != NULL)
650 {
651 // Call the scored problem resolver
652 OpTextProgress Progress(*_config);
653 bool const distUpgradeMode = strcmp(CmdL.FileList[0], "dist-upgrade") == 0 || strcmp(CmdL.FileList[0], "full-upgrade") == 0;
654
655 bool resolver_fail = false;
656 if (distUpgradeMode == true || UpgradeMode != APT::Upgrade::ALLOW_EVERYTHING)
657 resolver_fail = APT::Upgrade::Upgrade(Cache, UpgradeMode, &Progress);
658 else
659 resolver_fail = Fix->Resolve(true, &Progress);
660
661 if (resolver_fail == false && Cache->BrokenCount() == 0)
662 return false;
663 }
664
665 if (CheckNothingBroken(Cache) == false)
666 return false;
667 }
668 if (!DoAutomaticRemove(Cache))
669 return false;
670
671 // if nothing changed in the cache, but only the automark information
672 // we write the StateFile here, otherwise it will be written in
673 // cache.commit()
674 if (InstallAction.AutoMarkChanged > 0 &&
675 Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
676 Cache->BadCount() == 0 &&
677 _config->FindB("APT::Get::Simulate",false) == false)
678 Cache->writeStateFile(NULL);
679
680 return true;
681 }
682 /*}}}*/
683 // DoInstall - Install packages from the command line /*{{{*/
684 // ---------------------------------------------------------------------
685 /* Install named packages */
686 struct PkgIsExtraInstalled {
687 pkgCacheFile * const Cache;
688 APT::VersionSet const * const verset;
689 PkgIsExtraInstalled(pkgCacheFile * const Cache, APT::VersionSet const * const Container) : Cache(Cache), verset(Container) {}
690 bool operator() (pkgCache::PkgIterator const &Pkg)
691 {
692 if ((*Cache)[Pkg].Install() == false)
693 return false;
694 pkgCache::VerIterator const Cand = (*Cache)[Pkg].CandidateVerIter(*Cache);
695 return verset->find(Cand) == verset->end();
696 }
697 };
698 bool DoInstall(CommandLine &CmdL)
699 {
700 CacheFile Cache;
701 std::vector<std::string> VolatileCmdL;
702 Cache.GetSourceList()->AddVolatileFiles(CmdL, &VolatileCmdL);
703
704 // then open the cache
705 if (Cache.OpenForInstall() == false ||
706 Cache.CheckDeps(CmdL.FileSize() != 1) == false)
707 return false;
708
709 std::map<unsigned short, APT::VersionSet> verset;
710 if(!DoCacheManipulationFromCommandLine(CmdL, VolatileCmdL, Cache, verset, 0))
711 return false;
712
713 /* Print out a list of packages that are going to be installed extra
714 to what the user asked */
715 SortedPackageUniverse Universe(Cache);
716 if (Cache->InstCount() != verset[MOD_INSTALL].size())
717 ShowList(c1out, _("The following additional packages will be installed:"), Universe,
718 PkgIsExtraInstalled(&Cache, &verset[MOD_INSTALL]),
719 &PrettyFullName, CandidateVersion(&Cache));
720
721 /* Print out a list of suggested and recommended packages */
722 {
723 std::list<std::string> Recommends, Suggests, SingleRecommends, SingleSuggests;
724 for (auto const &Pkg: Universe)
725 {
726 /* Just look at the ones we want to install */
727 if ((*Cache)[Pkg].Install() == false)
728 continue;
729
730 // get the recommends/suggests for the candidate ver
731 pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
732 for (pkgCache::DepIterator D = CV.DependsList(); D.end() == false; )
733 {
734 pkgCache::DepIterator Start;
735 pkgCache::DepIterator End;
736 D.GlobOr(Start,End); // advances D
737 if (Start->Type != pkgCache::Dep::Recommends && Start->Type != pkgCache::Dep::Suggests)
738 continue;
739
740 {
741 // Skip if we already saw this
742 std::string target;
743 for (pkgCache::DepIterator I = Start; I != D; ++I)
744 {
745 if (target.empty() == false)
746 target.append(" | ");
747 target.append(I.TargetPkg().FullName(true));
748 }
749 std::list<std::string> &Type = Start->Type == pkgCache::Dep::Recommends ? SingleRecommends : SingleSuggests;
750 if (std::find(Type.begin(), Type.end(), target) != Type.end())
751 continue;
752 Type.push_back(target);
753 }
754
755 std::list<std::string> OrList;
756 bool foundInstalledInOrGroup = false;
757 for (pkgCache::DepIterator I = Start; I != D; ++I)
758 {
759 {
760 // satisfying package is installed and not marked for deletion
761 APT::VersionList installed = APT::VersionList::FromDependency(Cache, I, APT::CacheSetHelper::INSTALLED);
762 if (std::find_if(installed.begin(), installed.end(),
763 [&Cache](pkgCache::VerIterator const &Ver) { return Cache[Ver.ParentPkg()].Delete() == false; }) != installed.end())
764 {
765 foundInstalledInOrGroup = true;
766 break;
767 }
768 }
769
770 {
771 // satisfying package is upgraded to/new install
772 APT::VersionList upgrades = APT::VersionList::FromDependency(Cache, I, APT::CacheSetHelper::CANDIDATE);
773 if (std::find_if(upgrades.begin(), upgrades.end(),
774 [&Cache](pkgCache::VerIterator const &Ver) { return Cache[Ver.ParentPkg()].Upgrade(); }) != upgrades.end())
775 {
776 foundInstalledInOrGroup = true;
777 break;
778 }
779 }
780
781 if (OrList.empty())
782 OrList.push_back(I.TargetPkg().FullName(true));
783 else
784 OrList.push_back("| " + I.TargetPkg().FullName(true));
785 }
786
787 if(foundInstalledInOrGroup == false)
788 {
789 std::list<std::string> &Type = Start->Type == pkgCache::Dep::Recommends ? Recommends : Suggests;
790 std::move(OrList.begin(), OrList.end(), std::back_inserter(Type));
791 }
792 }
793 }
794 auto always_true = [](std::string const&) { return true; };
795 auto string_ident = [](std::string const&str) { return str; };
796 auto verbose_show_candidate =
797 [&Cache](std::string str)
798 {
799 if (APT::String::Startswith(str, "| "))
800 str.erase(0, 2);
801 pkgCache::PkgIterator const Pkg = Cache->FindPkg(str);
802 if (Pkg.end() == true)
803 return "";
804 return (*Cache)[Pkg].CandVersion;
805 };
806 ShowList(c1out,_("Suggested packages:"), Suggests,
807 always_true, string_ident, verbose_show_candidate);
808 ShowList(c1out,_("Recommended packages:"), Recommends,
809 always_true, string_ident, verbose_show_candidate);
810 }
811
812 // See if we need to prompt
813 // FIXME: check if really the packages in the set are going to be installed
814 if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0)
815 return InstallPackages(Cache,false,false);
816
817 return InstallPackages(Cache,false);
818 }
819 /*}}}*/
820
821 // TryToInstall - Mark a package for installation /*{{{*/
822 void TryToInstall::operator() (pkgCache::VerIterator const &Ver) {
823 if (unlikely(Ver.end()))
824 {
825 _error->Fatal("The given version to TryToInstall is invalid!");
826 return;
827 }
828 pkgCache::PkgIterator Pkg = Ver.ParentPkg();
829 if (unlikely(Pkg.end()))
830 {
831 _error->Fatal("The given version to TryToInstall has an invalid parent package!");
832 return;
833 }
834
835 Cache->GetDepCache()->SetCandidateVersion(Ver);
836 pkgDepCache::StateCache &State = (*Cache)[Pkg];
837
838 // Handle the no-upgrade case
839 if (_config->FindB("APT::Get::upgrade",true) == false && Pkg->CurrentVer != 0)
840 ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
841 Pkg.FullName(true).c_str());
842 // Ignore request for install if package would be new
843 else if (_config->FindB("APT::Get::Only-Upgrade", false) == true && Pkg->CurrentVer == 0)
844 ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
845 Pkg.FullName(true).c_str());
846 else {
847 if (Fix != NULL) {
848 Fix->Clear(Pkg);
849 Fix->Protect(Pkg);
850 }
851 Cache->GetDepCache()->MarkInstall(Pkg,false);
852
853 if (State.Install() == false) {
854 if (_config->FindB("APT::Get::ReInstall",false) == true) {
855 if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
856 ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
857 Pkg.FullName(true).c_str());
858 else
859 Cache->GetDepCache()->SetReInstall(Pkg, true);
860 } else
861 // TRANSLATORS: First string is package name, second is version
862 ioprintf(c1out,_("%s is already the newest version (%s).\n"),
863 Pkg.FullName(true).c_str(), Pkg.CurrentVer().VerStr());
864 }
865
866 // Install it with autoinstalling enabled (if we not respect the minial
867 // required deps or the policy)
868 if (FixBroken == false)
869 doAutoInstallLater.insert(Pkg);
870 }
871
872 // see if we need to fix the auto-mark flag
873 // e.g. apt-get install foo
874 // where foo is marked automatic
875 if (State.Install() == false &&
876 (State.Flags & pkgCache::Flag::Auto) &&
877 _config->FindB("APT::Get::ReInstall",false) == false &&
878 _config->FindB("APT::Get::Only-Upgrade",false) == false &&
879 _config->FindB("APT::Get::Download-Only",false) == false)
880 {
881 ioprintf(c1out,_("%s set to manually installed.\n"),
882 Pkg.FullName(true).c_str());
883 Cache->GetDepCache()->MarkAuto(Pkg,false);
884 AutoMarkChanged++;
885 }
886 }
887 /*}}}*/
888 bool TryToInstall::propergateReleaseCandiateSwitching(std::list<std::pair<pkgCache::VerIterator, std::string> > const &start, std::ostream &out)/*{{{*/
889 {
890 for (std::list<std::pair<pkgCache::VerIterator, std::string> >::const_iterator s = start.begin();
891 s != start.end(); ++s)
892 Cache->GetDepCache()->SetCandidateVersion(s->first);
893
894 bool Success = true;
895 // the Changed list contains:
896 // first: "new version"
897 // second: "what-caused the change"
898 std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > Changed;
899 for (std::list<std::pair<pkgCache::VerIterator, std::string> >::const_iterator s = start.begin();
900 s != start.end(); ++s)
901 {
902 Changed.push_back(std::make_pair(s->first, pkgCache::VerIterator(*Cache)));
903 // We continue here even if it failed to enhance the ShowBroken output
904 Success &= Cache->GetDepCache()->SetCandidateRelease(s->first, s->second, Changed);
905 }
906 for (std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::const_iterator c = Changed.begin();
907 c != Changed.end(); ++c)
908 {
909 if (c->second.end() == true)
910 ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"),
911 c->first.VerStr(), c->first.RelStr().c_str(), c->first.ParentPkg().FullName(true).c_str());
912 else if (c->first.ParentPkg()->Group != c->second.ParentPkg()->Group)
913 {
914 pkgCache::VerIterator V = (*Cache)[c->first.ParentPkg()].CandidateVerIter(*Cache);
915 ioprintf(out, _("Selected version '%s' (%s) for '%s' because of '%s'\n"), V.VerStr(),
916 V.RelStr().c_str(), V.ParentPkg().FullName(true).c_str(), c->second.ParentPkg().FullName(true).c_str());
917 }
918 }
919 return Success;
920 }
921 /*}}}*/
922 void TryToInstall::doAutoInstall() { /*{{{*/
923 for (APT::PackageSet::const_iterator P = doAutoInstallLater.begin();
924 P != doAutoInstallLater.end(); ++P) {
925 pkgDepCache::StateCache &State = (*Cache)[P];
926 if (State.InstBroken() == false && State.InstPolicyBroken() == false)
927 continue;
928 Cache->GetDepCache()->MarkInstall(P, true);
929 }
930 doAutoInstallLater.clear();
931 }
932 /*}}}*/
933 // TryToRemove - Mark a package for removal /*{{{*/
934 void TryToRemove::operator() (pkgCache::VerIterator const &Ver)
935 {
936 pkgCache::PkgIterator Pkg = Ver.ParentPkg();
937
938 if (Fix != NULL)
939 {
940 Fix->Clear(Pkg);
941 Fix->Protect(Pkg);
942 Fix->Remove(Pkg);
943 }
944
945 if ((Pkg->CurrentVer == 0 && PurgePkgs == false) ||
946 (PurgePkgs == true && Pkg->CurrentState == pkgCache::State::NotInstalled))
947 {
948 pkgCache::GrpIterator Grp = Pkg.Group();
949 pkgCache::PkgIterator P = Grp.PackageList();
950 for (; P.end() != true; P = Grp.NextPkg(P))
951 {
952 if (P == Pkg)
953 continue;
954 if (P->CurrentVer != 0 || (PurgePkgs == true && P->CurrentState != pkgCache::State::NotInstalled))
955 {
956 // TRANSLATORS: Note, this is not an interactive question
957 ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
958 Pkg.FullName(true).c_str(), P.FullName(true).c_str());
959 break;
960 }
961 }
962 if (P.end() == true)
963 ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str());
964
965 // MarkInstall refuses to install packages on hold
966 Pkg->SelectedState = pkgCache::State::Hold;
967 }
968 else
969 Cache->GetDepCache()->MarkDelete(Pkg, PurgePkgs);
970 }
971 /*}}}*/