// Include Files /*{{{*/
#include <config.h>
#include <apt-pkg/acquire.h>
#include <apt-pkg/acquire-item.h>
#include <apt-pkg/algorithms.h>
#include <apt-pkg/cachefile.h>
#include <apt-pkg/cacheset.h>
#include <apt-pkg/cmndline.h>
#include <apt-pkg/depcache.h>
#include <apt-pkg/error.h>
#include <apt-pkg/fileutl.h>
#include <apt-pkg/pkgrecords.h>
#include <apt-pkg/pkgsystem.h>
#include <apt-pkg/sptr.h>
#include <apt-pkg/strutl.h>
#include <apt-pkg/cacheiterators.h>
#include <apt-pkg/configuration.h>
#include <apt-pkg/macros.h>
#include <apt-pkg/packagemanager.h>
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/upgrade.h>
#include <apt-pkg/install-progress.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <apt-private/acqprogress.h>
#include <apt-private/private-install.h>
#include <apt-private/private-cachefile.h>
#include <apt-private/private-cacheset.h>
#include <apt-private/private-download.h>
#include <apt-private/private-output.h>
#include <apti18n.h>
/*}}}*/
class pkgSourceList;
bool CheckNothingBroken(CacheFile &Cache) /*{{{*/
{
// Now we check the state of the packages,
if (Cache->BrokenCount() == 0)
return true;
c1out <<
_("Some packages could not be installed. This may mean that you have\n"
"requested an impossible situation or if you are using the unstable\n"
"distribution that some required packages have not yet been created\n"
"or been moved out of Incoming.") << std::endl;
/*
if (Packages == 1)
{
c1out << std::endl;
c1out <<
_("Since you only requested a single operation it is extremely likely that\n"
"the package is simply not installable and a bug report against\n"
"that package should be filed.") << std::endl;
}
*/
c1out << _("The following information may help to resolve the situation:") << std::endl;
c1out << std::endl;
ShowBroken(c1out,Cache,false);
if (_error->PendingError() == true)
return false;
else
return _error->Error(_("Broken packages"));
}
/*}}}*/
// InstallPackages - Actually download and install the packages /*{{{*/
// ---------------------------------------------------------------------
/* This displays the informative messages describing what is going to
happen and then calls the download routines */
bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
{
if (_config->FindB("APT::Get::Purge",false) == true)
{
pkgCache::PkgIterator I = Cache->PkgBegin();
for (; I.end() == false; ++I)
{
if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
Cache->MarkDelete(I,true);
}
}
bool Hold = false;
bool Downgrade = false;
bool Essential = false;
// Show all the various warning indicators
ShowDel(c1out,Cache);
ShowNew(c1out,Cache);
if (ShwKept == true)
ShowKept(c1out,Cache);
Hold = !ShowHold(c1out,Cache);
if (_config->FindB("APT::Get::Show-Upgraded",true) == true)
ShowUpgraded(c1out,Cache);
Downgrade = !ShowDowngraded(c1out,Cache);
if (_config->FindB("APT::Get::Download-Only",false) == false)
Essential = !ShowEssential(c1out,Cache);
// All kinds of failures
bool Fail = (Essential || Downgrade || Hold);
Stats(c1out,Cache);
// Sanity check
if (Cache->BrokenCount() != 0)
{
ShowBroken(c1out,Cache,false);
return _error->Error(_("Internal error, InstallPackages was called with broken packages!"));
}
if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
Cache->BadCount() == 0)
return true;
// No remove flag
if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
return _error->Error(_("Packages need to be removed but remove is disabled."));
// Fail safe check
if (_config->FindI("quiet",0) >= 2 ||
_config->FindB("APT::Get::Assume-Yes",false) == true)
{
if (_config->FindB("APT::Get::Force-Yes",false) == true) {
_error->Warning(_("--force-yes is deprecated, use one of the options starting with --allow instead."));
}
if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false) {
if (Essential == true && _config->FindB("APT::Get::allow-remove-essential", false) == false)
return _error->Error(_("Essential packages were removed and -y was used without --allow-remove-essential."));
if (Downgrade == true && _config->FindB("APT::Get::allow-downgrades", false) == false)
return _error->Error(_("Packages were downgraded and -y was used without --allow-downgrades."));
if (Hold == true && _config->FindB("APT::Get::allow-change-held-packages", false) == false)
return _error->Error(_("Held packages were changed and -y was used without --allow-change-held-packages."));
}
}
// Run the simulator ..
if (_config->FindB("APT::Get::Simulate") == true)
{
pkgSimulate PM(Cache);
APT::Progress::PackageManager *progress = APT::Progress::PackageManagerProgressFactory();
pkgPackageManager::OrderResult Res = PM.DoInstall(progress);
delete progress;
if (Res == pkgPackageManager::Failed)
return false;
if (Res != pkgPackageManager::Completed)
return _error->Error(_("Internal error, Ordering didn't finish"));
return true;
}
// Create the text record parser
pkgRecords Recs(Cache);
if (_error->PendingError() == true)
return false;
// Create the download object
aptAcquireWithTextStatus Fetcher;
if (_config->FindB("APT::Get::Print-URIs", false) == true)
{
// force a hashsum for compatibility reasons
_config->CndSet("Acquire::ForceHash", "md5sum");
}
else if (Fetcher.GetLock(_config->FindDir("Dir::Cache::Archives")) == false)
return false;
// Read the source list
if (Cache.BuildSourceList() == false)
return false;
pkgSourceList *List = Cache.GetSourceList();
// Create the package manager and prepare to download
std::unique_ptr<pkgPackageManager> PM(_system->CreatePM(Cache));
if (PM->GetArchives(&Fetcher,List,&Recs) == false ||
_error->PendingError() == true)
return false;
// Display statistics
unsigned long long FetchBytes = Fetcher.FetchNeeded();
unsigned long long FetchPBytes = Fetcher.PartialPresent();
unsigned long long DebBytes = Fetcher.TotalNeeded();
if (DebBytes != Cache->DebSize())
{
c0out << DebBytes << ',' << Cache->DebSize() << std::endl;
c0out << _("How odd... The sizes didn't match, email apt@packages.debian.org") << std::endl;
}
// Number of bytes
if (DebBytes != FetchBytes)
//TRANSLATOR: The required space between number and unit is already included
// in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"),
SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
else if (DebBytes != 0)
//TRANSLATOR: The required space between number and unit is already included
// in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
ioprintf(c1out,_("Need to get %sB of archives.\n"),
SizeToStr(DebBytes).c_str());
// Size delta
if (Cache->UsrSize() >= 0)
//TRANSLATOR: The required space between number and unit is already included
// in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
ioprintf(c1out,_("After this operation, %sB of additional disk space will be used.\n"),
SizeToStr(Cache->UsrSize()).c_str());
else
//TRANSLATOR: The required space between number and unit is already included
// in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
ioprintf(c1out,_("After this operation, %sB disk space will be freed.\n"),
SizeToStr(-1*Cache->UsrSize()).c_str());
if (_error->PendingError() == true)
return false;
if (CheckFreeSpaceBeforeDownload(_config->FindDir("Dir::Cache::Archives"), (FetchBytes - FetchPBytes)) == false)
return false;
if (Essential == true && Safety == true && _config->FindB("APT::Get::allow-remove-essential", false) == false)
{
if (_config->FindB("APT::Get::Trivial-Only",false) == true)
return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
// TRANSLATOR: This string needs to be typed by the user as a confirmation, so be
// careful with hard to type or special characters (like non-breaking spaces)
const char *Prompt = _("Yes, do as I say!");
ioprintf(c2out,
_("You are about to do something potentially harmful.\n"
"To continue type in the phrase '%s'\n"
" ?] "),Prompt);
c2out << std::flush;
if (AnalPrompt(Prompt) == false)
{
c2out << _("Abort.") << std::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?") << std::flush;
if (YnPrompt() == false)
{
c2out << _("Abort.") << std::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)
std::cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
I->Owner->FileSize << ' ' << I->Owner->HashSum() << std::endl;
return true;
}
if (!CheckAuth(Fetcher, true))
return false;
/* Unlock the dpkg lock if we are not going to be doing an install
after. */
if (_config->FindB("APT::Get::Download-Only",false) == true)
_system->UnLock();
// Run it
while (1)
{
bool Transient = false;
if (_config->FindB("APT::Get::Download",true) == false)
{
for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
{
if ((*I)->Local == true)
{
++I;
continue;
}
// Close the item and check if it was found in cache
(*I)->Finished();
if ((*I)->Complete == false)
Transient = true;
// Clear it out of the fetch list
delete *I;
I = Fetcher.ItemsBegin();
}
}
bool Failed = false;
if (AcquireRun(Fetcher, 0, &Failed, &Transient) == false)
return false;
/* If we are in no download mode and missing files and 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::Download",true) == false)
{
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"));
c1out << _("Download complete and in download only mode") << std::endl;
return true;
}
if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
{
return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or 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)
{
c2out << _("Unable to correct missing packages.") << std::endl;
return _error->Error(_("Aborting install."));
Loading ...