1 // Include Files /*{{{*/
4 #include <apt-pkg/acquire.h>
5 #include <apt-pkg/acquire-item.h>
6 #include <apt-pkg/algorithms.h>
7 #include <apt-pkg/cachefile.h>
8 #include <apt-pkg/cacheset.h>
9 #include <apt-pkg/cmndline.h>
10 #include <apt-pkg/depcache.h>
11 #include <apt-pkg/error.h>
12 #include <apt-pkg/fileutl.h>
13 #include <apt-pkg/pkgrecords.h>
14 #include <apt-pkg/pkgsystem.h>
15 #include <apt-pkg/sptr.h>
16 #include <apt-pkg/strutl.h>
17 #include <apt-pkg/cacheiterators.h>
18 #include <apt-pkg/configuration.h>
19 #include <apt-pkg/macros.h>
20 #include <apt-pkg/packagemanager.h>
21 #include <apt-pkg/pkgcache.h>
22 #include <apt-pkg/upgrade.h>
23 #include <apt-pkg/install-progress.h>
33 #include <apt-private/acqprogress.h>
34 #include <apt-private/private-install.h>
35 #include <apt-private/private-cachefile.h>
36 #include <apt-private/private-cacheset.h>
37 #include <apt-private/private-download.h>
38 #include <apt-private/private-output.h>
44 // InstallPackages - Actually download and install the packages /*{{{*/
45 // ---------------------------------------------------------------------
46 /* This displays the informative messages describing what is going to
47 happen and then calls the download routines */
48 bool InstallPackages(CacheFile
&Cache
,bool ShwKept
,bool Ask
, bool Safety
)
50 if (_config
->FindB("APT::Get::Purge",false) == true)
52 pkgCache::PkgIterator I
= Cache
->PkgBegin();
53 for (; I
.end() == false; ++I
)
55 if (I
.Purge() == false && Cache
[I
].Mode
== pkgDepCache::ModeDelete
)
56 Cache
->MarkDelete(I
,true);
61 bool Essential
= false;
63 // Show all the various warning indicators
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
);
78 if (Cache
->BrokenCount() != 0)
80 ShowBroken(c1out
,Cache
,false);
81 return _error
->Error(_("Internal error, InstallPackages was called with broken packages!"));
84 if (Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
85 Cache
->BadCount() == 0)
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."));
92 // Run the simulator ..
93 if (_config
->FindB("APT::Get::Simulate") == true)
95 pkgSimulate
PM(Cache
);
97 #if APT_PKG_ABI >= 413
98 APT::Progress::PackageManager
*progress
= APT::Progress::PackageManagerProgressFactory();
99 pkgPackageManager::OrderResult Res
= PM
.DoInstall(progress
);
102 int status_fd
= _config
->FindI("APT::Status-Fd",-1);
103 pkgPackageManager::OrderResult Res
= PM
.DoInstall(status_fd
);
106 if (Res
== pkgPackageManager::Failed
)
108 if (Res
!= pkgPackageManager::Completed
)
109 return _error
->Error(_("Internal error, Ordering didn't finish"));
113 // Create the text record parser
114 pkgRecords
Recs(Cache
);
115 if (_error
->PendingError() == true)
118 // Create the download object
119 AcqTextStatus
Stat(std::cout
, ScreenWidth
,_config
->FindI("quiet",0));
120 pkgAcquire
Fetcher(&Stat
);
121 if (_config
->FindB("APT::Get::Print-URIs", false) == true)
123 // force a hashsum for compatibility reasons
124 _config
->CndSet("Acquire::ForceHash", "md5sum");
126 else if (Fetcher
.GetLock(_config
->FindDir("Dir::Cache::Archives")) == false)
129 // Read the source list
130 if (Cache
.BuildSourceList() == false)
132 pkgSourceList
*List
= Cache
.GetSourceList();
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)
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())
146 c0out
<< DebBytes
<< ',' << Cache
->DebSize() << std::endl
;
147 c0out
<< _("How odd... The sizes didn't match, email apt@packages.debian.org") << std::endl
;
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());
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());
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());
174 if (_error
->PendingError() == true)
177 if (CheckFreeSpaceBeforeDownload(_config
->FindDir("Dir::Cache::Archives"), (FetchBytes
- FetchPBytes
)) == false)
181 if (_config
->FindI("quiet",0) >= 2 ||
182 _config
->FindB("APT::Get::Assume-Yes",false) == true)
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"));
188 if (Essential
== true && Safety
== true)
190 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
191 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
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!");
197 _("You are about to do something potentially harmful.\n"
198 "To continue type in the phrase '%s'\n"
201 if (AnalPrompt(Prompt
) == false)
203 c2out
<< _("Abort.") << std::endl
;
209 // Prompt to continue
210 if (Ask
== true || Fail
== true)
212 if (_config
->FindB("APT::Get::Trivial-Only",false) == true)
213 return _error
->Error(_("Trivial Only specified but this is not a trivial operation."));
215 if (_config
->FindI("quiet",0) < 2 &&
216 _config
->FindB("APT::Get::Assume-Yes",false) == false)
218 c2out
<< _("Do you want to continue?") << std::flush
;
219 if (YnPrompt() == false)
221 c2out
<< _("Abort.") << std::endl
;
228 // Just print out the uris an exit if the --print-uris flag was used
229 if (_config
->FindB("APT::Get::Print-URIs") == true)
231 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
232 for (; I
!= Fetcher
.UriEnd(); ++I
)
233 std::cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
234 I
->Owner
->FileSize
<< ' ' << I
->Owner
->HashSum() << std::endl
;
238 if (!CheckAuth(Fetcher
, true))
241 /* Unlock the dpkg lock if we are not going to be doing an install
243 if (_config
->FindB("APT::Get::Download-Only",false) == true)
249 bool Transient
= false;
250 if (_config
->FindB("APT::Get::Download",true) == false)
252 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
< Fetcher
.ItemsEnd();)
254 if ((*I
)->Local
== true)
260 // Close the item and check if it was found in cache
262 if ((*I
)->Complete
== false)
265 // Clear it out of the fetch list
267 I
= Fetcher
.ItemsBegin();
272 if (AcquireRun(Fetcher
, 0, &Failed
, &Transient
) == false)
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)
285 if (_config
->FindB("APT::Get::Download-Only",false) == true)
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
;
293 if (Failed
== true && _config
->FindB("APT::Get::Fix-Missing",false) == false)
295 return _error
->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
298 if (Transient
== true && Failed
== true)
299 return _error
->Error(_("--fix-missing and media swapping is not currently supported"));
301 // Try to deal with missing package files
302 if (Failed
== true && PM
->FixMissing() == false)
304 c2out
<< _("Unable to correct missing packages.") << std::endl
;
305 return _error
->Error(_("Aborting install."));
310 #if APT_PKG_ABI >= 413
311 APT::Progress::PackageManager
*progress
= APT::Progress::PackageManagerProgressFactory();
312 pkgPackageManager::OrderResult Res
= PM
->DoInstall(progress
);
315 int status_fd
= _config
->FindI("APT::Status-Fd", -1);
316 pkgPackageManager::OrderResult Res
= PM
->DoInstall(status_fd
);
319 if (Res
== pkgPackageManager::Failed
|| _error
->PendingError() == true)
321 if (Res
== pkgPackageManager::Completed
)
324 // Reload the fetcher object and loop again for media swapping
326 if (PM
->GetArchives(&Fetcher
,List
,&Recs
) == false)
332 std::set
<std::string
> const disappearedPkgs
= PM
->GetDisappearedPackages();
333 if (disappearedPkgs
.empty() == true)
336 std::string disappear
;
337 for (std::set
<std::string
>::const_iterator d
= disappearedPkgs
.begin();
338 d
!= disappearedPkgs
.end(); ++d
)
339 disappear
.append(*d
).append(" ");
341 ShowList(c1out
, P_("The following package disappeared from your system as\n"
342 "all files have been overwritten by other packages:",
343 "The following packages disappeared from your system as\n"
344 "all files have been overwritten by other packages:", disappearedPkgs
.size()), disappear
, "");
345 c0out
<< _("Note: This is done automatically and on purpose by dpkg.") << std::endl
;
350 // DoAutomaticRemove - Remove all automatic unused packages /*{{{*/
351 // ---------------------------------------------------------------------
352 /* Remove unused automatic packages */
353 static bool DoAutomaticRemove(CacheFile
&Cache
)
355 bool Debug
= _config
->FindI("Debug::pkgAutoRemove",false);
356 bool doAutoRemove
= _config
->FindB("APT::Get::AutomaticRemove", false);
357 bool hideAutoRemove
= _config
->FindB("APT::Get::HideAutoRemove");
359 pkgDepCache::ActionGroup
group(*Cache
);
361 std::cout
<< "DoAutomaticRemove()" << std::endl
;
363 if (doAutoRemove
== true &&
364 _config
->FindB("APT::Get::Remove",true) == false)
366 c1out
<< _("We are not supposed to delete stuff, can't start "
367 "AutoRemover") << std::endl
;
371 bool purgePkgs
= _config
->FindB("APT::Get::Purge", false);
372 bool smallList
= (hideAutoRemove
== false &&
373 strcasecmp(_config
->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
375 unsigned long autoRemoveCount
= 0;
376 APT::PackageSet tooMuch
;
377 APT::PackageList autoRemoveList
;
378 // look over the cache to see what can be removed
379 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; ++J
)
381 pkgCache::PkgIterator
Pkg(Cache
,Cache
.List
[J
]);
382 if (Cache
[Pkg
].Garbage
)
384 if(Pkg
.CurrentVer() != 0 || Cache
[Pkg
].Install())
386 std::cout
<< "We could delete %s" << Pkg
.FullName(true).c_str() << std::endl
;
390 if(Pkg
.CurrentVer() != 0 &&
391 Pkg
->CurrentState
!= pkgCache::State::ConfigFiles
)
392 Cache
->MarkDelete(Pkg
, purgePkgs
, 0, false);
394 Cache
->MarkKeep(Pkg
, false, false);
398 if (hideAutoRemove
== false && Cache
[Pkg
].Delete() == false)
399 autoRemoveList
.insert(Pkg
);
400 // if the package is a new install and already garbage we don't need to
401 // install it in the first place, so nuke it instead of show it
402 if (Cache
[Pkg
].Install() == true && Pkg
.CurrentVer() == 0)
404 if (Pkg
.CandVersion() != 0)
406 Cache
->MarkDelete(Pkg
, false, 0, false);
408 // only show stuff in the list that is not yet marked for removal
409 else if(hideAutoRemove
== false && Cache
[Pkg
].Delete() == false)
415 // we could have removed a new dependency of a garbage package,
416 // so check if a reverse depends is broken and if so install it again.
417 if (tooMuch
.empty() == false && (Cache
->BrokenCount() != 0 || Cache
->PolicyBrokenCount() != 0))
422 for (APT::PackageSet::const_iterator Pkg
= tooMuch
.begin();
423 Pkg
!= tooMuch
.end(); ++Pkg
)
427 for (pkgCache::PrvIterator Prv
= Cache
[Pkg
].CandidateVerIter(Cache
).ProvidesList();
428 Prv
.end() == false; ++Prv
)
429 too
.insert(Prv
.ParentPkg());
430 for (APT::PackageSet::const_iterator P
= too
.begin(); P
!= too
.end(); ++P
)
432 for (pkgCache::DepIterator R
= P
.RevDependsList();
433 R
.end() == false; ++R
)
435 if (R
.IsNegative() == true ||
436 Cache
->IsImportantDep(R
) == false)
438 pkgCache::PkgIterator N
= R
.ParentPkg();
439 if (N
.end() == true || (N
->CurrentVer
== 0 && (*Cache
)[N
].Install() == false))
442 std::clog
<< "Save " << Pkg
<< " as another installed garbage package depends on it" << std::endl
;
443 Cache
->MarkInstall(Pkg
, false, 0, false);
444 if (hideAutoRemove
== false)
456 } while (Changed
== true);
459 std::string autoremovelist
, autoremoveversions
;
460 if (smallList
== false && autoRemoveCount
!= 0)
462 for (APT::PackageList::const_iterator Pkg
= autoRemoveList
.begin(); Pkg
!= autoRemoveList
.end(); ++Pkg
)
464 if (Cache
[Pkg
].Garbage
== false)
466 autoremovelist
+= Pkg
.FullName(true) + " ";
467 autoremoveversions
+= std::string(Cache
[Pkg
].CandVersion
) + "\n";
471 // Now see if we had destroyed anything (if we had done anything)
472 if (Cache
->BrokenCount() != 0)
474 c1out
<< _("Hmm, seems like the AutoRemover destroyed something which really\n"
475 "shouldn't happen. Please file a bug report against apt.") << std::endl
;
477 c1out
<< _("The following information may help to resolve the situation:") << std::endl
;
479 ShowBroken(c1out
,Cache
,false);
481 return _error
->Error(_("Internal Error, AutoRemover broke stuff"));
484 // if we don't remove them, we should show them!
485 if (doAutoRemove
== false && (autoremovelist
.empty() == false || autoRemoveCount
!= 0))
487 if (smallList
== false)
488 ShowList(c1out
, P_("The following package was automatically installed and is no longer required:",
489 "The following packages were automatically installed and are no longer required:",
490 autoRemoveCount
), autoremovelist
, autoremoveversions
);
492 ioprintf(c1out
, P_("%lu package was automatically installed and is no longer required.\n",
493 "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount
), autoRemoveCount
);
494 c1out
<< P_("Use 'apt-get autoremove' to remove it.", "Use 'apt-get autoremove' to remove them.", autoRemoveCount
) << std::endl
;
499 // DoCacheManipulationFromCommandLine /*{{{*/
500 static const unsigned short MOD_REMOVE
= 1;
501 static const unsigned short MOD_INSTALL
= 2;
503 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, CacheFile
&Cache
, int UpgradeMode
)
505 std::map
<unsigned short, APT::VersionSet
> verset
;
506 return DoCacheManipulationFromCommandLine(CmdL
, Cache
, verset
, UpgradeMode
);
508 bool DoCacheManipulationFromCommandLine(CommandLine
&CmdL
, CacheFile
&Cache
,
509 std::map
<unsigned short, APT::VersionSet
> &verset
, int UpgradeMode
)
511 // Enter the special broken fixing mode if the user specified arguments
512 bool BrokenFix
= false;
513 if (Cache
->BrokenCount() != 0)
516 SPtr
<pkgProblemResolver
> Fix
;
517 if (_config
->FindB("APT::Get::CallResolver", true) == true)
518 Fix
= new pkgProblemResolver(Cache
);
520 unsigned short fallback
= MOD_INSTALL
;
521 if (strcasecmp(CmdL
.FileList
[0],"remove") == 0)
522 fallback
= MOD_REMOVE
;
523 else if (strcasecmp(CmdL
.FileList
[0], "purge") == 0)
525 _config
->Set("APT::Get::Purge", true);
526 fallback
= MOD_REMOVE
;
528 else if (strcasecmp(CmdL
.FileList
[0], "autoremove") == 0)
530 _config
->Set("APT::Get::AutomaticRemove", "true");
531 fallback
= MOD_REMOVE
;
534 std::list
<APT::VersionSet::Modifier
> mods
;
535 mods
.push_back(APT::VersionSet::Modifier(MOD_INSTALL
, "+",
536 APT::VersionSet::Modifier::POSTFIX
, APT::CacheSetHelper::CANDIDATE
));
537 mods
.push_back(APT::VersionSet::Modifier(MOD_REMOVE
, "-",
538 APT::VersionSet::Modifier::POSTFIX
, APT::CacheSetHelper::NEWEST
));
539 CacheSetHelperAPTGet
helper(c0out
);
540 verset
= APT::VersionSet::GroupedFromCommandLine(Cache
,
541 CmdL
.FileList
+ 1, mods
, fallback
, helper
);
543 if (_error
->PendingError() == true)
545 helper
.showVirtualPackageErrors(Cache
);
550 TryToInstall
InstallAction(Cache
, Fix
, BrokenFix
);
551 TryToRemove
RemoveAction(Cache
, Fix
);
553 // new scope for the ActionGroup
555 pkgDepCache::ActionGroup
group(Cache
);
556 unsigned short const order
[] = { MOD_REMOVE
, MOD_INSTALL
, 0 };
558 for (unsigned short i
= 0; order
[i
] != 0; ++i
)
560 if (order
[i
] == MOD_INSTALL
)
561 InstallAction
= std::for_each(verset
[MOD_INSTALL
].begin(), verset
[MOD_INSTALL
].end(), InstallAction
);
562 else if (order
[i
] == MOD_REMOVE
)
563 RemoveAction
= std::for_each(verset
[MOD_REMOVE
].begin(), verset
[MOD_REMOVE
].end(), RemoveAction
);
566 if (Fix
!= NULL
&& _config
->FindB("APT::Get::AutoSolving", true) == true)
568 for (unsigned short i
= 0; order
[i
] != 0; ++i
)
570 if (order
[i
] != MOD_INSTALL
)
572 InstallAction
.propergateReleaseCandiateSwitching(helper
.selectedByRelease
, c0out
);
573 InstallAction
.doAutoInstall();
577 if (_error
->PendingError() == true)
582 /* If we are in the Broken fixing mode we do not attempt to fix the
583 problems. This is if the user invoked install without -f and gave
585 if (BrokenFix
== true && Cache
->BrokenCount() != 0)
587 c1out
<< _("You might want to run 'apt-get -f install' to correct these:") << std::endl
;
588 ShowBroken(c1out
,Cache
,false);
589 return _error
->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
594 // Call the scored problem resolver
595 OpTextProgress
Progress(*_config
);
596 bool const distUpgradeMode
= strcmp(CmdL
.FileList
[0], "dist-upgrade") == 0 || strcmp(CmdL
.FileList
[0], "full-upgrade") == 0;
598 bool resolver_fail
= false;
599 if (distUpgradeMode
== true || UpgradeMode
!= APT::Upgrade::ALLOW_EVERYTHING
)
600 resolver_fail
= APT::Upgrade::Upgrade(Cache
, UpgradeMode
, &Progress
);
602 resolver_fail
= Fix
->Resolve(true, &Progress
);
604 if (resolver_fail
== false && Cache
->BrokenCount() == 0)
608 // Now we check the state of the packages,
609 if (Cache
->BrokenCount() != 0)
612 _("Some packages could not be installed. This may mean that you have\n"
613 "requested an impossible situation or if you are using the unstable\n"
614 "distribution that some required packages have not yet been created\n"
615 "or been moved out of Incoming.") << std::endl
;
621 _("Since you only requested a single operation it is extremely likely that\n"
622 "the package is simply not installable and a bug report against\n"
623 "that package should be filed.") << std::endl;
627 c1out
<< _("The following information may help to resolve the situation:") << std::endl
;
629 ShowBroken(c1out
,Cache
,false);
630 if (_error
->PendingError() == true)
633 return _error
->Error(_("Broken packages"));
636 if (!DoAutomaticRemove(Cache
))
639 // if nothing changed in the cache, but only the automark information
640 // we write the StateFile here, otherwise it will be written in
642 if (InstallAction
.AutoMarkChanged
> 0 &&
643 Cache
->DelCount() == 0 && Cache
->InstCount() == 0 &&
644 Cache
->BadCount() == 0 &&
645 _config
->FindB("APT::Get::Simulate",false) == false)
646 Cache
->writeStateFile(NULL
);
651 // DoInstall - Install packages from the command line /*{{{*/
652 // ---------------------------------------------------------------------
653 /* Install named packages */
654 bool DoInstall(CommandLine
&CmdL
)
657 // first check for local pkgs and add them to the cache
658 for (const char **I
= CmdL
.FileList
; *I
!= 0; I
++)
662 // FIXME: make this more elegant
663 std::string TypeStr
= flExtension(*I
) + "-file";
664 pkgSourceList::Type
*Type
= pkgSourceList::Type::GetType(TypeStr
.c_str());
667 std::vector
<metaIndex
*> List
;
668 std::map
<std::string
, std::string
> Options
;
669 if(Type
->CreateItem(List
, *I
, "", "", Options
))
671 // we have our own CacheFile that gives us a SourceList
673 SourceList
*sources
= (SourceList
*)Cache
.GetSourceList();
674 sources
->AddMetaIndex(List
[0]);
680 // then open the cache
681 if (Cache
.OpenForInstall() == false ||
682 Cache
.CheckDeps(CmdL
.FileSize() != 1) == false)
685 std::map
<unsigned short, APT::VersionSet
> verset
;
687 if(!DoCacheManipulationFromCommandLine(CmdL
, Cache
, verset
, 0))
690 /* Print out a list of packages that are going to be installed extra
691 to what the user asked */
692 if (Cache
->InstCount() != verset
[MOD_INSTALL
].size())
695 std::string VersionsList
;
696 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
698 pkgCache::PkgIterator
I(Cache
,Cache
.List
[J
]);
699 if ((*Cache
)[I
].Install() == false)
701 pkgCache::VerIterator Cand
= Cache
[I
].CandidateVerIter(Cache
);
703 if (verset
[MOD_INSTALL
].find(Cand
) != verset
[MOD_INSTALL
].end())
706 List
+= I
.FullName(true) + " ";
707 VersionsList
+= std::string(Cache
[I
].CandVersion
) + "\n";
710 ShowList(c1out
,_("The following extra packages will be installed:"),List
,VersionsList
);
713 /* Print out a list of suggested and recommended packages */
715 std::string SuggestsList
, RecommendsList
;
716 std::string SuggestsVersions
, RecommendsVersions
;
717 for (unsigned J
= 0; J
< Cache
->Head().PackageCount
; J
++)
719 pkgCache::PkgIterator
Pkg(Cache
,Cache
.List
[J
]);
721 /* Just look at the ones we want to install */
722 if ((*Cache
)[Pkg
].Install() == false)
725 // get the recommends/suggests for the candidate ver
726 pkgCache::VerIterator CV
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
727 for (pkgCache::DepIterator D
= CV
.DependsList(); D
.end() == false; )
729 pkgCache::DepIterator Start
;
730 pkgCache::DepIterator End
;
731 D
.GlobOr(Start
,End
); // advances D
733 // FIXME: we really should display a or-group as a or-group to the user
734 // the problem is that ShowList is incapable of doing this
735 std::string RecommendsOrList
,RecommendsOrVersions
;
736 std::string SuggestsOrList
,SuggestsOrVersions
;
737 bool foundInstalledInOrGroup
= false;
740 /* Skip if package is installed already, or is about to be */
741 std::string target
= Start
.TargetPkg().FullName(true) + " ";
742 pkgCache::PkgIterator
const TarPkg
= Start
.TargetPkg();
743 if (TarPkg
->SelectedState
== pkgCache::State::Install
||
744 TarPkg
->SelectedState
== pkgCache::State::Hold
||
745 Cache
[Start
.TargetPkg()].Install())
747 foundInstalledInOrGroup
=true;
751 /* Skip if we already saw it */
752 if (int(SuggestsList
.find(target
)) != -1 || int(RecommendsList
.find(target
)) != -1)
754 foundInstalledInOrGroup
=true;
758 // this is a dep on a virtual pkg, check if any package that provides it
759 // should be installed
760 if(Start
.TargetPkg().ProvidesList() != 0)
762 pkgCache::PrvIterator I
= Start
.TargetPkg().ProvidesList();
763 for (; I
.end() == false; ++I
)
765 pkgCache::PkgIterator Pkg
= I
.OwnerPkg();
766 if (Cache
[Pkg
].CandidateVerIter(Cache
) == I
.OwnerVer() &&
767 Pkg
.CurrentVer() != 0)
768 foundInstalledInOrGroup
=true;
772 if (Start
->Type
== pkgCache::Dep::Suggests
)
774 SuggestsOrList
+= target
;
775 SuggestsOrVersions
+= std::string(Cache
[Start
.TargetPkg()].CandVersion
) + "\n";
778 if (Start
->Type
== pkgCache::Dep::Recommends
)
780 RecommendsOrList
+= target
;
781 RecommendsOrVersions
+= std::string(Cache
[Start
.TargetPkg()].CandVersion
) + "\n";
789 if(foundInstalledInOrGroup
== false)
791 RecommendsList
+= RecommendsOrList
;
792 RecommendsVersions
+= RecommendsOrVersions
;
793 SuggestsList
+= SuggestsOrList
;
794 SuggestsVersions
+= SuggestsOrVersions
;
800 ShowList(c1out
,_("Suggested packages:"),SuggestsList
,SuggestsVersions
);
801 ShowList(c1out
,_("Recommended packages:"),RecommendsList
,RecommendsVersions
);
805 // See if we need to prompt
806 // FIXME: check if really the packages in the set are going to be installed
807 if (Cache
->InstCount() == verset
[MOD_INSTALL
].size() && Cache
->DelCount() == 0)
808 return InstallPackages(Cache
,false,false);
810 return InstallPackages(Cache
,false);
814 // TryToInstall - Mark a package for installation /*{{{*/
815 void TryToInstall::operator() (pkgCache::VerIterator
const &Ver
) {
816 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
818 Cache
->GetDepCache()->SetCandidateVersion(Ver
);
819 pkgDepCache::StateCache
&State
= (*Cache
)[Pkg
];
821 // Handle the no-upgrade case
822 if (_config
->FindB("APT::Get::upgrade",true) == false && Pkg
->CurrentVer
!= 0)
823 ioprintf(c1out
,_("Skipping %s, it is already installed and upgrade is not set.\n"),
824 Pkg
.FullName(true).c_str());
825 // Ignore request for install if package would be new
826 else if (_config
->FindB("APT::Get::Only-Upgrade", false) == true && Pkg
->CurrentVer
== 0)
827 ioprintf(c1out
,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
828 Pkg
.FullName(true).c_str());
834 Cache
->GetDepCache()->MarkInstall(Pkg
,false);
836 if (State
.Install() == false) {
837 if (_config
->FindB("APT::Get::ReInstall",false) == true) {
838 if (Pkg
->CurrentVer
== 0 || Pkg
.CurrentVer().Downloadable() == false)
839 ioprintf(c1out
,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
840 Pkg
.FullName(true).c_str());
842 Cache
->GetDepCache()->SetReInstall(Pkg
, true);
844 ioprintf(c1out
,_("%s is already the newest version.\n"),
845 Pkg
.FullName(true).c_str());
848 // Install it with autoinstalling enabled (if we not respect the minial
849 // required deps or the policy)
850 if (FixBroken
== false)
851 doAutoInstallLater
.insert(Pkg
);
854 // see if we need to fix the auto-mark flag
855 // e.g. apt-get install foo
856 // where foo is marked automatic
857 if (State
.Install() == false &&
858 (State
.Flags
& pkgCache::Flag::Auto
) &&
859 _config
->FindB("APT::Get::ReInstall",false) == false &&
860 _config
->FindB("APT::Get::Only-Upgrade",false) == false &&
861 _config
->FindB("APT::Get::Download-Only",false) == false)
863 ioprintf(c1out
,_("%s set to manually installed.\n"),
864 Pkg
.FullName(true).c_str());
865 Cache
->GetDepCache()->MarkAuto(Pkg
,false);
870 bool TryToInstall::propergateReleaseCandiateSwitching(std::list
<std::pair
<pkgCache::VerIterator
, std::string
> > const &start
, std::ostream
&out
)/*{{{*/
872 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
873 s
!= start
.end(); ++s
)
874 Cache
->GetDepCache()->SetCandidateVersion(s
->first
);
877 // the Changed list contains:
878 // first: "new version"
879 // second: "what-caused the change"
880 std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> > Changed
;
881 for (std::list
<std::pair
<pkgCache::VerIterator
, std::string
> >::const_iterator s
= start
.begin();
882 s
!= start
.end(); ++s
)
884 Changed
.push_back(std::make_pair(s
->first
, pkgCache::VerIterator(*Cache
)));
885 // We continue here even if it failed to enhance the ShowBroken output
886 Success
&= Cache
->GetDepCache()->SetCandidateRelease(s
->first
, s
->second
, Changed
);
888 for (std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> >::const_iterator c
= Changed
.begin();
889 c
!= Changed
.end(); ++c
)
891 if (c
->second
.end() == true)
892 ioprintf(out
, _("Selected version '%s' (%s) for '%s'\n"),
893 c
->first
.VerStr(), c
->first
.RelStr().c_str(), c
->first
.ParentPkg().FullName(true).c_str());
894 else if (c
->first
.ParentPkg()->Group
!= c
->second
.ParentPkg()->Group
)
896 pkgCache::VerIterator V
= (*Cache
)[c
->first
.ParentPkg()].CandidateVerIter(*Cache
);
897 ioprintf(out
, _("Selected version '%s' (%s) for '%s' because of '%s'\n"), V
.VerStr(),
898 V
.RelStr().c_str(), V
.ParentPkg().FullName(true).c_str(), c
->second
.ParentPkg().FullName(true).c_str());
904 void TryToInstall::doAutoInstall() { /*{{{*/
905 for (APT::PackageSet::const_iterator P
= doAutoInstallLater
.begin();
906 P
!= doAutoInstallLater
.end(); ++P
) {
907 pkgDepCache::StateCache
&State
= (*Cache
)[P
];
908 if (State
.InstBroken() == false && State
.InstPolicyBroken() == false)
910 Cache
->GetDepCache()->MarkInstall(P
, true);
912 doAutoInstallLater
.clear();
915 // TryToRemove - Mark a package for removal /*{{{*/
916 void TryToRemove::operator() (pkgCache::VerIterator
const &Ver
)
918 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
927 if ((Pkg
->CurrentVer
== 0 && PurgePkgs
== false) ||
928 (PurgePkgs
== true && Pkg
->CurrentState
== pkgCache::State::NotInstalled
))
930 pkgCache::GrpIterator Grp
= Pkg
.Group();
931 pkgCache::PkgIterator P
= Grp
.PackageList();
932 for (; P
.end() != true; P
= Grp
.NextPkg(P
))
936 if (P
->CurrentVer
!= 0 || (PurgePkgs
== true && P
->CurrentState
!= pkgCache::State::NotInstalled
))
938 // TRANSLATORS: Note, this is not an interactive question
939 ioprintf(c1out
,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
940 Pkg
.FullName(true).c_str(), P
.FullName(true).c_str());
945 ioprintf(c1out
,_("Package '%s' is not installed, so not removed\n"),Pkg
.FullName(true).c_str());
947 // MarkInstall refuses to install packages on hold
948 Pkg
->SelectedState
= pkgCache::State::Hold
;
951 Cache
->GetDepCache()->MarkDelete(Pkg
, PurgePkgs
);