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