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