]> git.saurik.com Git - apt.git/blobdiff - cmdline/apt-get.cc
* merged from apt--mvo
[apt.git] / cmdline / apt-get.cc
index d0330b08e2b308f55a86226b498e671daded907f..765591b143bb0a7abfa069dda8cbabc9df143c2f 100644 (file)
@@ -629,6 +629,8 @@ void CacheFile::Sort()
    and verifies that the system is OK. */
 bool CacheFile::CheckDeps(bool AllowBroken)
 {
+   bool FixBroken = _config->FindB("APT::Get::Fix-Broken",false);
+
    if (_error->PendingError() == true)
       return false;
 
@@ -640,12 +642,24 @@ bool CacheFile::CheckDeps(bool AllowBroken)
    if (pkgApplyStatus(*DCache) == false)
       return false;
    
+   if (_config->FindB("APT::Get::Fix-Policy-Broken",false) == true)
+   {
+      FixBroken = true;
+      if ((DCache->PolicyBrokenCount() > 0))
+      {
+        // upgrade all policy-broken packages with ForceImportantDeps=True
+        for (pkgCache::PkgIterator I = Cache->PkgBegin(); !I.end(); I++)
+           if ((*DCache)[I].NowPolicyBroken() == true) 
+              DCache->MarkInstall(I,true,0,false, true);
+      }
+   }
+
    // Nothing is broken
    if (DCache->BrokenCount() == 0 || AllowBroken == true)
       return true;
 
    // Attempt to fix broken things
-   if (_config->FindB("APT::Get::Fix-Broken",false) == true)
+   if (FixBroken == true)
    {
       c1out << _("Correcting dependencies...") << flush;
       if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0)
@@ -1405,31 +1419,47 @@ bool DoUpdate(CommandLine &CmdL)
 /* Remove unused automatic packages */
 bool DoAutomaticRemove(CacheFile &Cache)
 {
-   if(_config->FindI("Debug::pkgAutoRemove",false))
-      std::cout << "DoAutomaticRemove()" << std::endl;
+   bool Debug = _config->FindI("Debug::pkgAutoRemove",false);
+   bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false);
+   pkgDepCache::ActionGroup group(*Cache);
+   
 
-   if (_config->FindB("APT::Get::Remove",true) == false)
-      return _error->Error(_("We are not supposed to delete stuff, can't "
-                            "start AutoRemover"));
+   if(Debug)
+      std::cout << "DoAutomaticRemove()" << std::endl;
 
+   if (_config->FindB("APT::Get::Remove",true) == false &&
+       doAutoRemove == true)
    {
-     pkgDepCache::ActionGroup group(*Cache);
-
-     // look over the cache to see what can be removed
-     for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg)
-       {
-        if (Cache[Pkg].Garbage)
-          {
-            if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
-              fprintf(stdout,"We could delete %s\n", Pkg.Name());
+      c1out << _("We are not supposed to delete stuff, can't start "
+                "AutoRemover") << std::endl;
+      doAutoRemove = false;
+   }
 
-            if(Pkg.CurrentVer() != 0 && Pkg->CurrentState != pkgCache::State::ConfigFiles)
+   string autoremovelist, autoremoveversions;
+   // look over the cache to see what can be removed
+   for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg)
+   {
+      if (Cache[Pkg].Garbage)
+      {
+        if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
+           if(Debug)
+              std::cout << "We could delete %s" <<  Pkg.Name() << std::endl;
+          
+        autoremovelist += string(Pkg.Name()) + " ";
+        autoremoveversions += string(Cache[Pkg].CandVersion) + " ";
+        if (doAutoRemove)
+        {
+           if(Pkg.CurrentVer() != 0 && 
+              Pkg->CurrentState != pkgCache::State::ConfigFiles)
               Cache->MarkDelete(Pkg, _config->FindB("APT::Get::Purge", false));
-            else
+           else
               Cache->MarkKeep(Pkg, false, false);
-          }
-       }
+        }
+      }
    }
+   ShowList(c1out, _("The following packages were automatically installed and are no longer required:"), autoremovelist, autoremoveversions);
+   if (!doAutoRemove && autoremovelist.size() > 0)
+      c1out << _("Use 'apt-get autoremove' to remove them.") << std::endl;
 
    // Now see if we destroyed anything
    if (Cache->BrokenCount() != 0)
@@ -1466,6 +1496,51 @@ bool DoUpgrade(CommandLine &CmdL)
    return InstallPackages(Cache,true);
 }
                                                                        /*}}}*/
+// DoInstallTask - Install task from the command line                  /*{{{*/
+// ---------------------------------------------------------------------
+/* Install named task */
+bool TryInstallTask(pkgDepCache &Cache, pkgProblemResolver &Fix, 
+                   bool BrokenFix,
+                   unsigned int& ExpectedInst, 
+                   const char *taskname)
+{
+   const char *start, *end;
+   pkgCache::PkgIterator Pkg;
+   char buf[64*1024];
+   regex_t Pattern;
+
+   // get the records
+   pkgRecords Recs(Cache);
+
+   // build regexp for the task
+   char S[300];
+   snprintf(S, sizeof(S), "^Task:.*[^a-z]%s[^a-z].*\n", taskname);
+   regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
+   
+   bool found = false;
+   bool res = true;
+   for (Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
+   {
+      pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache);
+      if(ver.end())
+        continue;
+      pkgRecords::Parser &parser = Recs.Lookup(ver.FileList());
+      parser.GetRec(start,end);
+      strncpy(buf, start, end-start);
+      buf[end-start] = 0x0;
+      if (regexec(&Pattern,buf,0,0,0) != 0)
+        continue;
+      res &= TryToInstall(Pkg,Cache,Fix,false,true,ExpectedInst);
+      found = true;
+   }
+   
+   if(!found)
+      _error->Error(_("Couldn't find task %s"),taskname);
+
+   regfree(&Pattern);
+   return res;
+}
+
 // DoInstall - Install packages from the command line                  /*{{{*/
 // ---------------------------------------------------------------------
 /* Install named packages */
@@ -1488,6 +1563,7 @@ bool DoInstall(CommandLine &CmdL)
    bool DefRemove = false;
    if (strcasecmp(CmdL.FileList[0],"remove") == 0)
       DefRemove = true;
+
    else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0)
    {
       _config->Set("APT::Get::AutomaticRemove", "true");
@@ -1510,6 +1586,18 @@ bool DoInstall(CommandLine &CmdL)
         bool Remove = DefRemove;
         char *VerTag = 0;
         bool VerIsRel = false;
+
+        // this is a task!
+        if (Length >= 1 && S[Length - 1] == '^')
+        {
+           S[--Length] = 0;
+           // tasks must always be confirmed
+           ExpectedInst += 1000;
+           // see if we can install it
+           TryInstallTask(Cache, Fix, BrokenFix, ExpectedInst, S);
+           continue;
+        }
+
         while (Cache->FindPkg(S).end() == true)
         {
            // Handle an optional end tag indicating what to do
@@ -1598,6 +1686,7 @@ bool DoInstall(CommandLine &CmdL)
         }
         else
         {
+
            if (VerTag != 0)
               if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
                  return false;
@@ -1645,10 +1734,8 @@ bool DoInstall(CommandLine &CmdL)
         return _error->Error(_("Broken packages"));
       }   
    }
-   if (_config->FindB("APT::Get::AutomaticRemove")) {
-      if (!DoAutomaticRemove(Cache)) 
+   if (!DoAutomaticRemove(Cache)) 
         return false;
-   }
 
    /* Print out a list of packages that are going to be installed extra
       to what the user asked */
@@ -2559,7 +2646,6 @@ void GetInitialize()
    _config->Set("APT::Get::Fix-Broken",false);
    _config->Set("APT::Get::Force-Yes",false);
    _config->Set("APT::Get::List-Cleanup",true);
-   _config->Set("APT::Get::AutomaticRemove",false);
 }
                                                                        /*}}}*/
 // SigWinch - Window size change signal handler                                /*{{{*/
@@ -2618,6 +2704,7 @@ int main(int argc,const char *argv[])
       {0,"auto-remove","APT::Get::AutomaticRemove",0},
       {0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0},
       {0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean},
+      {0,"fix-policy","APT::Get::Fix-Policy-Broken",0},
       {'c',"config-file",0,CommandLine::ConfigFile},
       {'o',"option",0,CommandLine::ArbItem},
       {0,0,0,0}};