]> git.saurik.com Git - apt.git/blobdiff - apt-private/private-install.cc
headers are for declarations only
[apt.git] / apt-private / private-install.cc
index e08cd8057f1c0b8d3cc55b9bf2e88fa63dbd2285..cdca457553a0fb067556f7f735eb12892b9e6b88 100644 (file)
 #include <apt-pkg/packagemanager.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/upgrade.h>
+#include <apt-pkg/install-progress.h>
 
-#include <errno.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/statfs.h>
-#include <sys/statvfs.h>
 #include <algorithm>
 #include <iostream>
 #include <set>
 #include <vector>
+#include <map>
 
 #include <apt-private/acqprogress.h>
 #include <apt-private/private-install.h>
@@ -95,7 +94,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
    {
       pkgSimulate PM(Cache);
 
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+#if APT_PKG_ABI >= 413
       APT::Progress::PackageManager *progress = APT::Progress::PackageManagerProgressFactory();
       pkgPackageManager::OrderResult Res = PM.DoInstall(progress);
       delete progress;
@@ -117,14 +116,14 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
       return false;
 
    // Create the download object
-   pkgAcquire Fetcher;
-   AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));   
+   AcqTextStatus Stat(std::cout, ScreenWidth,_config->FindI("quiet",0));
+   pkgAcquire Fetcher(&Stat);
    if (_config->FindB("APT::Get::Print-URIs", false) == true)
    {
       // force a hashsum for compatibility reasons
       _config->CndSet("Acquire::ForceHash", "md5sum");
    }
-   else if (Fetcher.Setup(&Stat, _config->FindDir("Dir::Cache::Archives")) == false)
+   else if (Fetcher.GetLock(_config->FindDir("Dir::Cache::Archives")) == false)
       return false;
 
    // Read the source list
@@ -175,33 +174,9 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
    if (_error->PendingError() == true)
       return false;
 
-   /* Check for enough free space, but only if we are actually going to
-      download */
-   if (_config->FindB("APT::Get::Print-URIs") == false &&
-       _config->FindB("APT::Get::Download",true) == true)
-   {
-      struct statvfs Buf;
-      std::string OutputDir = _config->FindDir("Dir::Cache::Archives");
-      if (statvfs(OutputDir.c_str(),&Buf) != 0) {
-        if (errno == EOVERFLOW)
-           return _error->WarningE("statvfs",_("Couldn't determine free space in %s"),
-                                OutputDir.c_str());
-        else
-           return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
-                                OutputDir.c_str());
-      } else if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
-      {
-         struct statfs Stat;
-         if (statfs(OutputDir.c_str(),&Stat) != 0
-#if HAVE_STRUCT_STATFS_F_TYPE
-             || unsigned(Stat.f_type) != RAMFS_MAGIC
-#endif
-             )
-            return _error->Error(_("You don't have enough free space in %s."),
-                OutputDir.c_str());
-      }
-   }
-   
+   if (CheckFreeSpaceBeforeDownload(_config->FindDir("Dir::Cache::Archives"), (FetchBytes - FetchPBytes)) == false)
+      return false;
+
    // Fail safe check
    if (_config->FindI("quiet",0) >= 2 ||
        _config->FindB("APT::Get::Assume-Yes",false) == true)
@@ -331,8 +306,8 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
       }
 
       _system->UnLock();
-      
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+
+#if APT_PKG_ABI >= 413
       APT::Progress::PackageManager *progress = APT::Progress::PackageManagerProgressFactory();
       pkgPackageManager::OrderResult Res = PM->DoInstall(progress);
       delete progress;
@@ -399,11 +374,10 @@ static bool DoAutomaticRemove(CacheFile &Cache)
 
    unsigned long autoRemoveCount = 0;
    APT::PackageSet tooMuch;
-   APT::PackageList autoRemoveList;
+   SortedPackageUniverse Universe(Cache);
    // look over the cache to see what can be removed
-   for (unsigned J = 0; J < Cache->Head().PackageCount; ++J)
+   for (auto const &Pkg: Universe)
    {
-      pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
       if (Cache[Pkg].Garbage)
       {
         if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
@@ -420,8 +394,6 @@ static bool DoAutomaticRemove(CacheFile &Cache)
         }
         else
         {
-           if (hideAutoRemove == false && Cache[Pkg].Delete() == false)
-              autoRemoveList.insert(Pkg);
            // if the package is a new install and already garbage we don't need to
            // install it in the first place, so nuke it instead of show it
            if (Cache[Pkg].Install() == true && Pkg.CurrentVer() == 0)
@@ -444,7 +416,7 @@ static bool DoAutomaticRemove(CacheFile &Cache)
       bool Changed;
       do {
         Changed = false;
-        for (APT::PackageSet::const_iterator Pkg = tooMuch.begin();
+        for (APT::PackageSet::iterator Pkg = tooMuch.begin();
              Pkg != tooMuch.end(); ++Pkg)
         {
            APT::PackageSet too;
@@ -481,18 +453,6 @@ static bool DoAutomaticRemove(CacheFile &Cache)
       } while (Changed == true);
    }
 
-   std::string autoremovelist, autoremoveversions;
-   if (smallList == false && autoRemoveCount != 0)
-   {
-      for (APT::PackageList::const_iterator Pkg = autoRemoveList.begin(); Pkg != autoRemoveList.end(); ++Pkg)
-      {
-        if (Cache[Pkg].Garbage == false)
-           continue;
-        autoremovelist += Pkg.FullName(true) + " ";
-        autoremoveversions += std::string(Cache[Pkg].CandVersion) + "\n";
-      }
-   }
-
    // Now see if we had destroyed anything (if we had done anything)
    if (Cache->BrokenCount() != 0)
    {
@@ -507,12 +467,17 @@ static bool DoAutomaticRemove(CacheFile &Cache)
    }
 
    // if we don't remove them, we should show them!
-   if (doAutoRemove == false && (autoremovelist.empty() == false || autoRemoveCount != 0))
+   if (doAutoRemove == false && autoRemoveCount != 0)
    {
       if (smallList == false)
+      {
+        SortedPackageUniverse Universe(Cache);
         ShowList(c1out, P_("The following package was automatically installed and is no longer required:",
                  "The following packages were automatically installed and are no longer required:",
-                 autoRemoveCount), autoremovelist, autoremoveversions);
+                 autoRemoveCount), Universe,
+              [&Cache](pkgCache::PkgIterator const &Pkg) { return (*Cache)[Pkg].Garbage == true && (*Cache)[Pkg].Delete() == false; },
+              &PrettyFullName, CandidateVersion(&Cache));
+      }
       else
         ioprintf(c1out, P_("%lu package was automatically installed and is no longer required.\n",
                  "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount), autoRemoveCount);
@@ -558,9 +523,9 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
 
    std::list<APT::VersionSet::Modifier> mods;
    mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+",
-               APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDIDATE));
+               APT::VersionSet::Modifier::POSTFIX, APT::CacheSetHelper::CANDIDATE));
    mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-",
-               APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::NEWEST));
+               APT::VersionSet::Modifier::POSTFIX, APT::CacheSetHelper::NEWEST));
    CacheSetHelperAPTGet helper(c0out);
    verset = APT::VersionSet::GroupedFromCommandLine(Cache,
                CmdL.FileList + 1, mods, fallback, helper);
@@ -617,15 +582,14 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
       if (Fix != NULL)
       {
         // Call the scored problem resolver
+        OpTextProgress Progress(*_config);
+        bool const distUpgradeMode = strcmp(CmdL.FileList[0], "dist-upgrade") == 0 || strcmp(CmdL.FileList[0], "full-upgrade") == 0;
+
         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 (distUpgradeMode == true || UpgradeMode != APT::Upgrade::ALLOW_EVERYTHING)
+           resolver_fail = APT::Upgrade::Upgrade(Cache, UpgradeMode, &Progress);
+        else
+           resolver_fail = Fix->Resolve(true, &Progress);
 
         if (resolver_fail == false && Cache->BrokenCount() == 0)
            return false;
@@ -677,13 +641,49 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
 // DoInstall - Install packages from the command line                  /*{{{*/
 // ---------------------------------------------------------------------
 /* Install named packages */
+struct PkgIsExtraInstalled {
+   pkgCacheFile * const Cache;
+   APT::VersionSet const * const verset;
+   PkgIsExtraInstalled(pkgCacheFile * const Cache, APT::VersionSet const * const Container) : Cache(Cache), verset(Container) {}
+   bool operator() (pkgCache::PkgIterator const Pkg)
+   {
+        if ((*Cache)[Pkg].Install() == false)
+           return false;
+        pkgCache::VerIterator const Cand = (*Cache)[Pkg].CandidateVerIter(*Cache);
+        return verset->find(Cand) == verset->end();
+   }
+};
 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, 0))
@@ -691,35 +691,18 @@ bool DoInstall(CommandLine &CmdL)
 
    /* Print out a list of packages that are going to be installed extra
       to what the user asked */
+   SortedPackageUniverse Universe(Cache);
    if (Cache->InstCount() != verset[MOD_INSTALL].size())
-   {
-      std::string List;
-      std::string VersionsList;
-      for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
-      {
-        pkgCache::PkgIterator I(Cache,Cache.List[J]);
-        if ((*Cache)[I].Install() == false)
-           continue;
-        pkgCache::VerIterator Cand = Cache[I].CandidateVerIter(Cache);
-
-        if (verset[MOD_INSTALL].find(Cand) != verset[MOD_INSTALL].end())
-           continue;
-
-        List += I.FullName(true) + " ";
-        VersionsList += std::string(Cache[I].CandVersion) + "\n";
-      }
-      
-      ShowList(c1out,_("The following extra packages will be installed:"),List,VersionsList);
-   }
+      ShowList(c1out, _("The following extra packages will be installed:"), Universe,
+           PkgIsExtraInstalled(&Cache, &verset[MOD_INSTALL]),
+           &PrettyFullName, CandidateVersion(&Cache));
 
    /* Print out a list of suggested and recommended packages */
    {
       std::string SuggestsList, RecommendsList;
       std::string SuggestsVersions, RecommendsVersions;
-      for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+      for (auto const &Pkg: Universe)
       {
-        pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
-
         /* Just look at the ones we want to install */
         if ((*Cache)[Pkg].Install() == false)
           continue;
@@ -740,7 +723,6 @@ bool DoInstall(CommandLine &CmdL)
            for(;;)
            {
               /* Skip if package is  installed already, or is about to be */
-               std::string target = Start.TargetPkg().FullName(true) + " ";
               pkgCache::PkgIterator const TarPkg = Start.TargetPkg();
               if (TarPkg->SelectedState == pkgCache::State::Install ||
                   TarPkg->SelectedState == pkgCache::State::Hold ||
@@ -751,6 +733,7 @@ bool DoInstall(CommandLine &CmdL)
               }
 
               /* Skip if we already saw it */
+               std::string target = Start.TargetPkg().FullName(true) + " ";
               if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1)
               {
                  foundInstalledInOrGroup=true;