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