]> git.saurik.com Git - apt.git/blobdiff - cmdline/apt-get.cc
* merged with mainline
[apt.git] / cmdline / apt-get.cc
index 411b16e9089426d1adb305c1e6005cec18e8ab4a..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)
@@ -1146,9 +1160,11 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
    else
       ExpectedInst++;
    
-   // Install it with autoinstalling enabled.
-   if (State.InstBroken() == true && BrokenFix == false)
+   // Install it with autoinstalling enabled (if we not respect the minial
+   // required deps or the policy)
+   if ((State.InstBroken() == true || State.InstPolicyBroken() == true) && BrokenFix == false)
       Cache.MarkInstall(Pkg,true);
+
    return true;
 }
                                                                        /*}}}*/
@@ -1356,20 +1372,29 @@ bool DoUpdate(CommandLine &CmdL)
       return false;
 
    bool Failed = false;
+   bool TransientNetworkFailure = false;
    for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
    {
       if ((*I)->Status == pkgAcquire::Item::StatDone)
         continue;
 
       (*I)->Finished();
-      
+
       fprintf(stderr,_("Failed to fetch %s  %s\n"),(*I)->DescURI().c_str(),
              (*I)->ErrorText.c_str());
+
+      if ((*I)->Status == pkgAcquire::Item::StatTransientNetworkError) 
+      {
+        TransientNetworkFailure = true;
+        continue;
+      }
+
       Failed = true;
    }
    
    // Clean out any old list files
-   if (!Failed && _config->FindB("APT::Get::List-Cleanup",true) == true)
+   if (!TransientNetworkFailure &&
+       _config->FindB("APT::Get::List-Cleanup",true) == true)
    {
       if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
          Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
@@ -1381,9 +1406,11 @@ bool DoUpdate(CommandLine &CmdL)
    if (Cache.BuildCaches() == false)
       return false;
    
-   if (Failed == true)
+   if (TransientNetworkFailure == true)
+      _error->Warning(_("Some index files failed to download, they have been ignored, or old ones used instead."));
+   else if (Failed == true)
       return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
-   
+
    return true;
 }
                                                                        /*}}}*/
@@ -1393,15 +1420,20 @@ bool DoUpdate(CommandLine &CmdL)
 bool DoAutomaticRemove(CacheFile &Cache)
 {
    bool Debug = _config->FindI("Debug::pkgAutoRemove",false);
+   bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false);
    pkgDepCache::ActionGroup group(*Cache);
+   
 
    if(Debug)
       std::cout << "DoAutomaticRemove()" << std::endl;
 
-   if (_config->FindB("APT::Get::AutomaticRemove") &&
-       _config->FindB("APT::Get::Remove",true) == false)
-      return _error->Error(_("We are not supposed to delete stuff, can't "
-                            "start AutoRemover"));
+   if (_config->FindB("APT::Get::Remove",true) == false &&
+       doAutoRemove == true)
+   {
+      c1out << _("We are not supposed to delete stuff, can't start "
+                "AutoRemover") << std::endl;
+      doAutoRemove = false;
+   }
 
    string autoremovelist, autoremoveversions;
    // look over the cache to see what can be removed
@@ -1415,7 +1447,7 @@ bool DoAutomaticRemove(CacheFile &Cache)
           
         autoremovelist += string(Pkg.Name()) + " ";
         autoremoveversions += string(Cache[Pkg].CandVersion) + " ";
-        if (_config->FindB("APT::Get::AutomaticRemove")) 
+        if (doAutoRemove)
         {
            if(Pkg.CurrentVer() != 0 && 
               Pkg->CurrentState != pkgCache::State::ConfigFiles)
@@ -1425,9 +1457,8 @@ bool DoAutomaticRemove(CacheFile &Cache)
         }
       }
    }
-   ShowList(c1out, _("The following packages where automatically installed and are no longer required:"), autoremovelist, autoremoveversions);
-   if (!_config->FindB("APT::Get::AutomaticRemove") && 
-       autoremovelist.size() > 0)
+   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
@@ -1465,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 */
@@ -1487,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");
@@ -1509,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
@@ -1597,6 +1686,7 @@ bool DoInstall(CommandLine &CmdL)
         }
         else
         {
+
            if (VerTag != 0)
               if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
                  return false;
@@ -2556,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                                /*{{{*/
@@ -2614,6 +2703,8 @@ int main(int argc,const char *argv[])
       {0,"arch-only","APT::Get::Arch-Only",0},
       {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}};