X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/b821e492d6dc4e1e8fd1f83590e12e3fbccad717..e5fefea6ec93746376bf42733ee84a9fafeab764:/apt-private/private-install.cc

diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc
index c07d060f3..55893bda0 100644
--- a/apt-private/private-install.cc
+++ b/apt-private/private-install.cc
@@ -1,99 +1,49 @@
 // Include Files							/*{{{*/
 #include <config.h>
 
-#include <apt-pkg/aptconfiguration.h>
-#include <apt-pkg/error.h>
-#include <apt-pkg/cmndline.h>
-#include <apt-pkg/init.h>
-#include <apt-pkg/depcache.h>
-#include <apt-pkg/sourcelist.h>
-#include <apt-pkg/algorithms.h>
+#include <apt-pkg/acquire.h>
 #include <apt-pkg/acquire-item.h>
-#include <apt-pkg/strutl.h>
-#include <apt-pkg/fileutl.h>
-#include <apt-pkg/clean.h>
-#include <apt-pkg/srcrecords.h>
-#include <apt-pkg/version.h>
+#include <apt-pkg/algorithms.h>
 #include <apt-pkg/cachefile.h>
 #include <apt-pkg/cacheset.h>
-#include <apt-pkg/sptr.h>
-#include <apt-pkg/md5.h>
-#include <apt-pkg/versionmatch.h>
-#include <apt-pkg/progress.h>
-#include <apt-pkg/pkgsystem.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/indexfile.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 <set>
-#include <locale.h>
-#include <langinfo.h>
-#include <fstream>
-#include <termios.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
 #include <sys/statfs.h>
 #include <sys/statvfs.h>
-#include <signal.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include <regex.h>
-#include <sys/wait.h>
-#include <sstream>
+#include <algorithm>
+#include <iostream>
+#include <set>
+#include <vector>
+#include <map>
 
-#include "private-install.h"
-#include "private-cachefile.h"
-#include "private-output.h"
-#include "private-cacheset.h"
-#include "acqprogress.h"
+#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;
 
-// 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"));
-}
-									/*}}}*/
 // InstallPackages - Actually download and install the packages		/*{{{*/
 // ---------------------------------------------------------------------
 /* This displays the informative messages describing what is going to 
@@ -146,8 +96,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)
@@ -189,7 +147,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
@@ -304,7 +262,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
       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
@@ -336,29 +294,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 
@@ -394,8 +333,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)
@@ -430,7 +377,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
 // 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);
@@ -500,15 +447,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)
 	       {
@@ -527,7 +474,11 @@ bool DoAutomaticRemove(CacheFile &Cache)
 		 Changed = true;
 		 break;
 	       }
+	       if (Changed == true)
+		  break;
 	    }
+	    if (Changed == true)
+	       break;
 	 }
       } while (Changed == true);
    }
@@ -576,15 +527,14 @@ bool DoAutomaticRemove(CacheFile &Cache)
 static const unsigned short MOD_REMOVE = 1;
 static const unsigned short MOD_INSTALL = 2;
 
-bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache)
+bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, int UpgradeMode)
 {
    std::map<unsigned short, APT::VersionSet> verset;
-   return DoCacheManipulationFromCommandLine(CmdL, Cache, verset);
+   return DoCacheManipulationFromCommandLine(CmdL, Cache, verset, UpgradeMode);
 }
 bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
-                                        std::map<unsigned short, APT::VersionSet> &verset)
+                                        std::map<unsigned short, APT::VersionSet> &verset, int UpgradeMode)
 {
-
    // Enter the special broken fixing mode if the user specified arguments
    bool BrokenFix = false;
    if (Cache->BrokenCount() != 0)
@@ -669,7 +619,18 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
       if (Fix != NULL)
       {
 	 // Call the scored problem resolver
-	 Fix->Resolve(true);
+	 bool resolver_fail = false;
+	 if (UpgradeMode == 0)
+	 {
+	    if (strcmp(CmdL.FileList[0], "dist-upgrade") == 0 || strcmp(CmdL.FileList[0], "full-upgrade") == 0)
+	       resolver_fail = APT::Upgrade::Upgrade(Cache, 0);
+	    else
+	       resolver_fail = Fix->Resolve(true);
+	 } else
+	    resolver_fail = APT::Upgrade::Upgrade(Cache, UpgradeMode);
+
+	 if (resolver_fail == false && Cache->BrokenCount() == 0)
+	    return false;
       }
 
       // Now we check the state of the packages,
@@ -721,13 +682,37 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
 bool DoInstall(CommandLine &CmdL)
 {
    CacheFile Cache;
+   // first check for local pkgs and add them to the cache
+   for (const char **I = CmdL.FileList; *I != 0; I++)
+   {
+      if(FileExists(*I))
+      {
+         // FIXME: make this more elegant
+         std::string TypeStr = flExtension(*I) + "-file";
+         pkgSourceList::Type *Type = pkgSourceList::Type::GetType(TypeStr.c_str());
+         if(Type != 0)
+         {
+            std::vector<metaIndex *> List;
+            std::map<std::string, std::string> Options;
+            if(Type->CreateItem(List, *I, "", "", Options))
+            {
+               // we have our own CacheFile that gives us a SourceList
+               // with superpowerz
+               SourceList *sources = (SourceList*)Cache.GetSourceList();
+               sources->AddMetaIndex(List[0]);
+            }
+         }
+      }
+   }
+
+   // then open the cache
    if (Cache.OpenForInstall() == false || 
        Cache.CheckDeps(CmdL.FileSize() != 1) == false)
       return false;
-
+   
    std::map<unsigned short, APT::VersionSet> verset;
 
-   if(!DoCacheManipulationFromCommandLine(CmdL, Cache, verset))
+   if(!DoCacheManipulationFromCommandLine(CmdL, Cache, verset, 0))
       return false;
 
    /* Print out a list of packages that are going to be installed extra
@@ -853,3 +838,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<std::pair<pkgCache::VerIterator, std::string> > const &start, std::ostream &out)/*{{{*/
+{
+   for (std::list<std::pair<pkgCache::VerIterator, std::string> >::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<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > Changed;
+   for (std::list<std::pair<pkgCache::VerIterator, std::string> >::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<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::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);
+}
+									/*}}}*/