X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/fbe0969131dc2472bcefbceaf390015ba68e1327..c4d749b78a46e69887ec9662851f180e587f2d34:/apt-private/private-install.cc diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc index d5052fcc0..a365d4294 100644 --- a/apt-private/private-install.cc +++ b/apt-private/private-install.cc @@ -1,100 +1,45 @@ // Include Files /*{{{*/ #include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include +#include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include -#include "private-install.h" -#include "private-cachefile.h" -#include "private-output.h" -#include "private-cacheset.h" -#include "acqprogress.h" +#include +#include +#include +#include +#include +#include #include /*}}}*/ - -// CheckAuth - check if each download comes form a trusted source /*{{{*/ -// --------------------------------------------------------------------- -/* */ -static bool CheckAuth(pkgAcquire& Fetcher) -{ - std::string UntrustedList; - for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd(); ++I) - { - if (!(*I)->IsTrusted()) - { - UntrustedList += std::string((*I)->ShortDesc()) + " "; - } - } - - if (UntrustedList == "") - { - return true; - } - - ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,""); - - if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true) - { - c2out << _("Authentication warning overridden.\n"); - return true; - } - - if (_config->FindI("quiet",0) < 2 - && _config->FindB("APT::Get::Assume-Yes",false) == false) - { - c2out << _("Install these packages without verification?") << std::flush; - if (!YnPrompt(false)) - return _error->Error(_("Some packages could not be authenticated")); - - return true; - } - else if (_config->FindB("APT::Get::Force-Yes",false) == true) - { - return true; - } - - return _error->Error(_("There are problems and -y was used without --force-yes")); -} - /*}}}*/ - +class pkgSourceList; // InstallPackages - Actually download and install the packages /*{{{*/ // --------------------------------------------------------------------- @@ -148,8 +93,16 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) if (_config->FindB("APT::Get::Simulate") == true) { pkgSimulate PM(Cache); + +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) + APT::Progress::PackageManager *progress = APT::Progress::PackageManagerProgressFactory(); + pkgPackageManager::OrderResult Res = PM.DoInstall(progress); + delete progress; +#else int status_fd = _config->FindI("APT::Status-Fd",-1); pkgPackageManager::OrderResult Res = PM.DoInstall(status_fd); +#endif + if (Res == pkgPackageManager::Failed) return false; if (Res != pkgPackageManager::Completed) @@ -191,7 +144,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) 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; + c0out << _("How odd... The sizes didn't match, email apt@packages.debian.org") << std::endl; } // Number of bytes @@ -301,12 +254,12 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) { pkgAcquire::UriIterator I = Fetcher.UriBegin(); for (; I != Fetcher.UriEnd(); ++I) - c1out << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << + std::cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << I->Owner->FileSize << ' ' << I->Owner->HashSum() << std::endl; return true; } - if (!CheckAuth(Fetcher)) + if (!CheckAuth(Fetcher, true)) return false; /* Unlock the dpkg lock if we are not going to be doing an install @@ -338,29 +291,10 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) I = Fetcher.ItemsBegin(); } } - - if (Fetcher.Run() == pkgAcquire::Failed) - return false; - - // Print out errors - bool Failed = false; - for (pkgAcquire::ItemIterator 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; - } - fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(), - (*I)->ErrorText.c_str()); - Failed = true; - } + 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 @@ -396,8 +330,16 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) } _system->UnLock(); - int status_fd = _config->FindI("APT::Status-Fd",-1); + +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) + APT::Progress::PackageManager *progress = APT::Progress::PackageManagerProgressFactory(); + pkgPackageManager::OrderResult Res = PM->DoInstall(progress); + delete progress; +#else + int status_fd = _config->FindI("APT::Status-Fd", -1); pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd); +#endif + if (Res == pkgPackageManager::Failed || _error->PendingError() == true) return false; if (Res == pkgPackageManager::Completed) @@ -429,12 +371,10 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) return true; } /*}}}*/ - - // DoAutomaticRemove - Remove all automatic unused packages /*{{{*/ // --------------------------------------------------------------------- /* Remove unused automatic packages */ -bool DoAutomaticRemove(CacheFile &Cache) +static bool DoAutomaticRemove(CacheFile &Cache) { bool Debug = _config->FindI("Debug::pkgAutoRemove",false); bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false); @@ -504,15 +444,15 @@ bool DoAutomaticRemove(CacheFile &Cache) do { Changed = false; for (APT::PackageSet::const_iterator Pkg = tooMuch.begin(); - Pkg != tooMuch.end() && Changed == false; ++Pkg) + Pkg != tooMuch.end(); ++Pkg) { APT::PackageSet too; too.insert(*Pkg); for (pkgCache::PrvIterator Prv = Cache[Pkg].CandidateVerIter(Cache).ProvidesList(); Prv.end() == false; ++Prv) too.insert(Prv.ParentPkg()); - for (APT::PackageSet::const_iterator P = too.begin(); - P != too.end() && Changed == false; ++P) { + for (APT::PackageSet::const_iterator P = too.begin(); P != too.end(); ++P) + { for (pkgCache::DepIterator R = P.RevDependsList(); R.end() == false; ++R) { @@ -531,7 +471,11 @@ bool DoAutomaticRemove(CacheFile &Cache) Changed = true; break; } + if (Changed == true) + break; } + if (Changed == true) + break; } } while (Changed == true); } @@ -576,32 +520,28 @@ bool DoAutomaticRemove(CacheFile &Cache) return true; } /*}}}*/ +// DoCacheManipulationFromCommandLine /*{{{*/ +static const unsigned short MOD_REMOVE = 1; +static const unsigned short MOD_INSTALL = 2; - - - -// DoInstall - Install packages from the command line /*{{{*/ -// --------------------------------------------------------------------- -/* Install named packages */ -bool DoInstall(CommandLine &CmdL) +bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache) { - CacheFile Cache; - if (Cache.OpenForInstall() == false || - Cache.CheckDeps(CmdL.FileSize() != 1) == false) - return false; - + std::map verset; + return DoCacheManipulationFromCommandLine(CmdL, Cache, verset); +} +bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, + std::map &verset) +{ + // Enter the special broken fixing mode if the user specified arguments bool BrokenFix = false; if (Cache->BrokenCount() != 0) BrokenFix = true; - pkgProblemResolver* Fix = NULL; + SPtr Fix; if (_config->FindB("APT::Get::CallResolver", true) == true) Fix = new pkgProblemResolver(Cache); - static const unsigned short MOD_REMOVE = 1; - static const unsigned short MOD_INSTALL = 2; - unsigned short fallback = MOD_INSTALL; if (strcasecmp(CmdL.FileList[0],"remove") == 0) fallback = MOD_REMOVE; @@ -622,14 +562,12 @@ bool DoInstall(CommandLine &CmdL) mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-", APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::NEWEST)); CacheSetHelperAPTGet helper(c0out); - std::map verset = APT::VersionSet::GroupedFromCommandLine(Cache, + verset = APT::VersionSet::GroupedFromCommandLine(Cache, CmdL.FileList + 1, mods, fallback, helper); if (_error->PendingError() == true) { helper.showVirtualPackageErrors(Cache); - if (Fix != NULL) - delete Fix; return false; } @@ -663,8 +601,6 @@ bool DoInstall(CommandLine &CmdL) if (_error->PendingError() == true) { - if (Fix != NULL) - delete Fix; return false; } @@ -675,16 +611,14 @@ bool DoInstall(CommandLine &CmdL) { c1out << _("You might want to run 'apt-get -f install' to correct these:") << std::endl; ShowBroken(c1out,Cache,false); - if (Fix != NULL) - delete Fix; return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).")); } if (Fix != NULL) { // Call the scored problem resolver - Fix->Resolve(true); - delete Fix; + if (Fix->Resolve(true) == false && Cache->BrokenCount() == 0) + return false; } // Now we check the state of the packages, @@ -718,6 +652,33 @@ bool DoInstall(CommandLine &CmdL) if (!DoAutomaticRemove(Cache)) return false; + // if nothing changed in the cache, but only the automark information + // we write the StateFile here, otherwise it will be written in + // cache.commit() + if (InstallAction.AutoMarkChanged > 0 && + Cache->DelCount() == 0 && Cache->InstCount() == 0 && + Cache->BadCount() == 0 && + _config->FindB("APT::Get::Simulate",false) == false) + Cache->writeStateFile(NULL); + + return true; +} + /*}}}*/ +// DoInstall - Install packages from the command line /*{{{*/ +// --------------------------------------------------------------------- +/* Install named packages */ +bool DoInstall(CommandLine &CmdL) +{ + CacheFile Cache; + if (Cache.OpenForInstall() == false || + Cache.CheckDeps(CmdL.FileSize() != 1) == false) + return false; + + std::map verset; + + if(!DoCacheManipulationFromCommandLine(CmdL, Cache, verset)) + return false; + /* Print out a list of packages that are going to be installed extra to what the user asked */ if (Cache->InstCount() != verset[MOD_INSTALL].size()) @@ -833,15 +794,6 @@ bool DoInstall(CommandLine &CmdL) } - // if nothing changed in the cache, but only the automark information - // we write the StateFile here, otherwise it will be written in - // cache.commit() - if (InstallAction.AutoMarkChanged > 0 && - Cache->DelCount() == 0 && Cache->InstCount() == 0 && - Cache->BadCount() == 0 && - _config->FindB("APT::Get::Simulate",false) == false) - Cache->writeStateFile(NULL); - // See if we need to prompt // FIXME: check if really the packages in the set are going to be installed if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0) @@ -850,3 +802,144 @@ bool DoInstall(CommandLine &CmdL) return InstallPackages(Cache,false); } /*}}}*/ + +// TryToInstall - Mark a package for installation /*{{{*/ +void TryToInstall::operator() (pkgCache::VerIterator const &Ver) { + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + + Cache->GetDepCache()->SetCandidateVersion(Ver); + pkgDepCache::StateCache &State = (*Cache)[Pkg]; + + // Handle the no-upgrade case + if (_config->FindB("APT::Get::upgrade",true) == false && Pkg->CurrentVer != 0) + ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"), + Pkg.FullName(true).c_str()); + // Ignore request for install if package would be new + else if (_config->FindB("APT::Get::Only-Upgrade", false) == true && Pkg->CurrentVer == 0) + ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"), + Pkg.FullName(true).c_str()); + else { + if (Fix != NULL) { + Fix->Clear(Pkg); + Fix->Protect(Pkg); + } + Cache->GetDepCache()->MarkInstall(Pkg,false); + + if (State.Install() == false) { + if (_config->FindB("APT::Get::ReInstall",false) == true) { + if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false) + ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"), + Pkg.FullName(true).c_str()); + else + Cache->GetDepCache()->SetReInstall(Pkg, true); + } else + ioprintf(c1out,_("%s is already the newest version.\n"), + Pkg.FullName(true).c_str()); + } + + // Install it with autoinstalling enabled (if we not respect the minial + // required deps or the policy) + if (FixBroken == false) + doAutoInstallLater.insert(Pkg); + } + + // see if we need to fix the auto-mark flag + // e.g. apt-get install foo + // where foo is marked automatic + if (State.Install() == false && + (State.Flags & pkgCache::Flag::Auto) && + _config->FindB("APT::Get::ReInstall",false) == false && + _config->FindB("APT::Get::Only-Upgrade",false) == false && + _config->FindB("APT::Get::Download-Only",false) == false) + { + ioprintf(c1out,_("%s set to manually installed.\n"), + Pkg.FullName(true).c_str()); + Cache->GetDepCache()->MarkAuto(Pkg,false); + AutoMarkChanged++; + } +} + /*}}}*/ +bool TryToInstall::propergateReleaseCandiateSwitching(std::list > const &start, std::ostream &out)/*{{{*/ +{ + for (std::list >::const_iterator s = start.begin(); + s != start.end(); ++s) + Cache->GetDepCache()->SetCandidateVersion(s->first); + + bool Success = true; + // the Changed list contains: + // first: "new version" + // second: "what-caused the change" + std::list > Changed; + for (std::list >::const_iterator s = start.begin(); + s != start.end(); ++s) + { + Changed.push_back(std::make_pair(s->first, pkgCache::VerIterator(*Cache))); + // We continue here even if it failed to enhance the ShowBroken output + Success &= Cache->GetDepCache()->SetCandidateRelease(s->first, s->second, Changed); + } + for (std::list >::const_iterator c = Changed.begin(); + c != Changed.end(); ++c) + { + if (c->second.end() == true) + ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), + c->first.VerStr(), c->first.RelStr().c_str(), c->first.ParentPkg().FullName(true).c_str()); + else if (c->first.ParentPkg()->Group != c->second.ParentPkg()->Group) + { + pkgCache::VerIterator V = (*Cache)[c->first.ParentPkg()].CandidateVerIter(*Cache); + ioprintf(out, _("Selected version '%s' (%s) for '%s' because of '%s'\n"), V.VerStr(), + V.RelStr().c_str(), V.ParentPkg().FullName(true).c_str(), c->second.ParentPkg().FullName(true).c_str()); + } + } + return Success; +} + /*}}}*/ +void TryToInstall::doAutoInstall() { /*{{{*/ + for (APT::PackageSet::const_iterator P = doAutoInstallLater.begin(); + P != doAutoInstallLater.end(); ++P) { + pkgDepCache::StateCache &State = (*Cache)[P]; + if (State.InstBroken() == false && State.InstPolicyBroken() == false) + continue; + Cache->GetDepCache()->MarkInstall(P, true); + } + doAutoInstallLater.clear(); +} + /*}}}*/ +// TryToRemove - Mark a package for removal /*{{{*/ +void TryToRemove::operator() (pkgCache::VerIterator const &Ver) +{ + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + + if (Fix != NULL) + { + Fix->Clear(Pkg); + Fix->Protect(Pkg); + Fix->Remove(Pkg); + } + + if ((Pkg->CurrentVer == 0 && PurgePkgs == false) || + (PurgePkgs == true && Pkg->CurrentState == pkgCache::State::NotInstalled)) + { + pkgCache::GrpIterator Grp = Pkg.Group(); + pkgCache::PkgIterator P = Grp.PackageList(); + for (; P.end() != true; P = Grp.NextPkg(P)) + { + if (P == Pkg) + continue; + if (P->CurrentVer != 0 || (PurgePkgs == true && P->CurrentState != pkgCache::State::NotInstalled)) + { + // TRANSLATORS: Note, this is not an interactive question + ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"), + Pkg.FullName(true).c_str(), P.FullName(true).c_str()); + break; + } + } + if (P.end() == true) + ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str()); + + // MarkInstall refuses to install packages on hold + Pkg->SelectedState = pkgCache::State::Hold; + } + else + Cache->GetDepCache()->MarkDelete(Pkg, PurgePkgs); +} + /*}}}*/