if Resolver fails, do not continue even if not broken
[ntk/apt.git] / apt-private / private-install.cc
index d5052fc..f15ccc3 100644 (file)
 // 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 <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 "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>
                                                                        /*}}}*/
-
-// 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<unsigned short, APT::VersionSet> verset;
+   return DoCacheManipulationFromCommandLine(CmdL, Cache, verset);
+}
+bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
+                                        std::map<unsigned short, APT::VersionSet> &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<pkgProblemResolver> 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<unsigned short, APT::VersionSet> 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<unsigned short, APT::VersionSet> 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)