+ c1out << " of archives. After unpacking ";
+
+ // Check for enough free space
+ struct statfs Buf;
+ string OutputDir = _config->FindDir("Dir::Cache::Archives");
+ if (statfs(OutputDir.c_str(),&Buf) != 0)
+ return _error->Errno("statfs","Couldn't determine free space in %s",
+ OutputDir.c_str());
+ if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
+ return _error->Error("Sorry, you don't have enough free space in %s to hold all the .debs.",
+ OutputDir.c_str());
+
+ // Size delta
+ if (Cache->UsrSize() >= 0)
+ c1out << SizeToStr(Cache->UsrSize()) << "B will be used." << endl;
+ else
+ c1out << SizeToStr(-1*Cache->UsrSize()) << "B will be freed." << endl;
+
+ if (_error->PendingError() == true)
+ return false;
+
+ // Fail safe check
+ if (_config->FindI("quiet",0) >= 2 ||
+ _config->FindB("APT::Get::Assume-Yes",false) == true)
+ {
+ if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
+ return _error->Error("There are problems and -y was used without --force-yes");
+ }
+
+ if (Essential == true && Saftey == true)
+ {
+ if (_config->FindB("APT::Get::Trivial-Only",false) == true)
+ return _error->Error("Trivial Only specified but this is not a trivial operation.");
+
+ c2out << "You are about to do something potentially harmful" << endl;
+ c2out << "To continue type in the phrase 'Yes, I understand this may be bad'" << endl;
+ c2out << " ?] " << flush;
+ if (AnalPrompt("Yes, I understand this may be bad") == false)
+ {
+ c2out << "Abort." << endl;
+ exit(1);
+ }
+ }
+ else
+ {
+ // Prompt to continue
+ if (Ask == true || Fail == true)
+ {
+ if (_config->FindB("APT::Get::Trivial-Only",false) == true)
+ return _error->Error("Trivial Only specified but this is not a trivial operation.");
+
+ if (_config->FindI("quiet",0) < 2 &&
+ _config->FindB("APT::Get::Assume-Yes",false) == false)
+ {
+ c2out << "Do you want to continue? [Y/n] " << flush;
+
+ if (YnPrompt() == false)
+ {
+ c2out << "Abort." << endl;
+ exit(1);
+ }
+ }
+ }
+ }
+
+ // Just print out the uris an exit if the --print-uris flag was used
+ if (_config->FindB("APT::Get::Print-URIs") == true)
+ {
+ pkgAcquire::UriIterator I = Fetcher.UriBegin();
+ for (; I != Fetcher.UriEnd(); I++)
+ cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
+ I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+ return true;
+ }
+
+ // Run it
+ while (1)
+ {
+ if (_config->FindB("APT::Get::No-Download",false) == false)
+ if (Fetcher.Run() == pkgAcquire::Failed)
+ return false;
+
+ // Print out errors
+ bool Failed = false;
+ bool Transient = false;
+ for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
+ {
+ if ((*I)->Status == pkgAcquire::Item::StatDone &&
+ (*I)->Complete == true)
+ continue;
+
+ if ((*I)->Status == pkgAcquire::Item::StatIdle)
+ {
+ Transient = true;
+ // Failed = true;
+ continue;
+ }
+
+ cerr << "Failed to fetch " << (*I)->DescURI() << endl;
+ cerr << " " << (*I)->ErrorText << endl;
+ Failed = true;
+ }
+
+ /* If we are in no download mode and missing files then there were
+ 'failures' then the user must specify -m. Furthermore, there
+ is no such thing as a transient error in no-download mode! */
+ if (Transient == true &&
+ _config->FindB("APT::Get::No-Download",false) == true)
+ {
+ Transient = false;
+ Failed = true;
+ }
+
+ if (_config->FindB("APT::Get::Download-Only",false) == true)
+ {
+ if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
+ return _error->Error("Some files failed to download");
+ return true;
+ }
+
+ if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
+ {
+ return _error->Error("Unable to fetch some archives, maybe try with --fix-missing?");
+ }
+
+ if (Transient == true && Failed == true)
+ return _error->Error("--fix-missing and media swapping is not currently supported");
+
+ // Try to deal with missing package files
+ if (Failed == true && PM.FixMissing() == false)
+ {
+ cerr << "Unable to correct missing packages." << endl;
+ return _error->Error("Aborting Install.");
+ }
+
+ Cache.ReleaseLock();
+ pkgPackageManager::OrderResult Res = PM.DoInstall();
+ if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
+ return false;
+ if (Res == pkgPackageManager::Completed)
+ return true;
+
+ // Reload the fetcher object and loop again for media swapping
+ Fetcher.Shutdown();
+ if (PM.GetArchives(&Fetcher,&List,&Recs) == false)
+ return false;
+ }
+}
+ /*}}}*/
+// TryToInstall - Try to install a single package /*{{{*/
+// ---------------------------------------------------------------------
+/* This used to be inlined in DoInstall, but with the advent of regex package
+ name matching it was split out.. */
+bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
+ pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
+ unsigned int &ExpectedInst,bool AllowFail = true)
+{
+ /* This is a pure virtual package and there is a single available
+ provides */
+ if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0 &&
+ Pkg.ProvidesList()->NextProvides == 0)
+ {
+ pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg();
+ c1out << "Note, installing " << Tmp.Name() << " instead of " << Pkg.Name() << endl;
+ Pkg = Tmp;
+ }
+
+ // Handle the no-upgrade case
+ if (_config->FindB("APT::Get::no-upgrade",false) == true &&
+ Pkg->CurrentVer != 0)
+ {
+ if (AllowFail == true)
+ c1out << "Skipping " << Pkg.Name() << ", it is already installed and no-upgrade is set." << endl;
+ return true;
+ }
+
+ // Check if there is something at all to install
+ pkgDepCache::StateCache &State = Cache[Pkg];
+ if (State.CandidateVer == 0)
+ {
+ if (AllowFail == false)
+ return false;
+
+ if (Pkg->ProvidesList != 0)
+ {
+ c1out << "Package " << Pkg.Name() << " is a virtual package provided by:" << endl;
+
+ pkgCache::PrvIterator I = Pkg.ProvidesList();
+ for (; I.end() == false; I++)
+ {
+ pkgCache::PkgIterator Pkg = I.OwnerPkg();
+
+ if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer())
+ {
+ if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
+ c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() <<
+ " [Installed]"<< endl;
+ else
+ c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl;
+ }
+ }
+ c1out << "You should explicitly select one to install." << endl;
+ }
+ else
+ {
+ c1out << "Package " << Pkg.Name() << " has no available version, but exists in the database." << endl;
+ c1out << "This typically means that the package was mentioned in a dependency and " << endl;
+ c1out << "never uploaded, has been obsoleted or is not available with the contents " << endl;
+ c1out << "of sources.list" << endl;
+
+ string List;
+ pkgCache::DepIterator Dep = Pkg.RevDependsList();
+ for (; Dep.end() == false; Dep++)
+ {
+ if (Dep->Type != pkgCache::Dep::Replaces)
+ continue;
+ List += string(Dep.ParentPkg().Name()) + " ";
+ }
+ ShowList(c1out,"However the following packages replace it:",List);
+ }
+
+ _error->Error("Package %s has no installation candidate",Pkg.Name());
+ return false;
+ }
+
+ Fix.Clear(Pkg);
+ Fix.Protect(Pkg);
+ if (Remove == true)
+ {
+ Fix.Remove(Pkg);
+ Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
+ return true;
+ }
+
+ // Install it
+ Cache.MarkInstall(Pkg,false);
+ if (State.Install() == false)
+ {
+ if (_config->FindB("APT::Get::ReInstall",false) == true)
+ {
+ if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
+ c1out << "Sorry, re-installation of " << Pkg.Name() << " is not possible, it cannot be downloaded" << endl;
+ else
+ Cache.SetReInstall(Pkg,true);
+ }
+ else
+ {
+ if (AllowFail == true)
+ c1out << "Sorry, " << Pkg.Name() << " is already the newest version" << endl;
+ }
+ }
+ else
+ ExpectedInst++;
+
+ // Install it with autoinstalling enabled.
+ if (State.InstBroken() == true && BrokenFix == false)
+ Cache.MarkInstall(Pkg,true);