]> git.saurik.com Git - apt.git/commitdiff
* merged daniel burrows fixes for the auto-mark code
authorMichael Vogt <michael.vogt@ubuntu.com>
Wed, 9 Nov 2005 11:39:27 +0000 (11:39 +0000)
committerMichael Vogt <michael.vogt@ubuntu.com>
Wed, 9 Nov 2005 11:39:27 +0000 (11:39 +0000)
Patches applied:

 * dburrows@debian.org--2005/apt--auto-mark--0--base-0
   tag of michael.vogt@ubuntu.com--2005/apt--auto-mark--0--patch-22

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-1
   doxygenize the new automark stuff

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-2
   Automatically update package markings after every state-changing public operation, and allow users of the dep-cache to group actions into a single action.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-3
   Automatically update package markings after every state-changing public operation, and allow users of the dep-cache to group actions into a single action.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-4
   Make action groups noncopyable

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-5
   Typo fix

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-6
   Add a FromUser flag to MarkKeep.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-7
   Somehow the ActionGroup definition got duplicated; kill the duplicate.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-8
   Cancel the automatic flag on packages that are being kept only if they are garbage.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-9
   Don't clear the 'automatically installed' flag in MarkDelete.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-10
   Add a FromUser flag to MarkInstall, and fix its handling of the Auto flag.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-11
   Only clear the Auto flag on manual changes in MarkKeep.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-12
   Make changes from the internal algorithms automatic.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-13
   Use ActionGroups in algorithms that make lots of changes, and fix a compile error.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-14
   Split the sweep code into a separate routine from pkgMarkUsed

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-15
   Update another call of MarkKeep to indicate that it's automatic.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-16
   Move the mark-and-sweep code into pkgDepCache; call Sweep and document what it and Garbage are for; add a hook that can be used to generate a custom root-set function; move the big blob of regexp stuff into the custom root-set; fix the memory leak in the regexp stuff.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-17
   Make ActionGroup take a reference instead of a pointer to the cache.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-18
   Don't mark already-to-be-deleted packages as garbage, to imitate aptitude's behavior.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-19
   Update apt-get for the new auto-mark protocol.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-20
   Add a setter method for the Auto flag.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-21
   Fix the test in apt-get about what to delete.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-22
   Add a zero-argument mark-and-sweep routine and use it to do a mark-and-sweep on startup (so the garbage flags are initialized properly).

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-23
   Right, Status is 2 for new installs, not 0.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-24
   POT updates.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-25
   Actually initialize group_level to 0.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-26
   Don't make an ActionGroup in Sweep, since there's no point and it also is an infinite loop.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-27
   Add virtual hooks to control whether the garbage collector considers recommends and/or suggests to be strong links.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-28
   Call the progress methods in the right order so we don't generate nonsensical progress notifications.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-29
   Typo fix.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-30
   Make RecommendsImportant default to true in apt, too.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-31
   Add a release() method to action groups.

 * dburrows@debian.org--2005/apt--auto-mark--0--patch-32
   Add an 'autoremove' command that is synonymous to '--auto-remove remove'.

apt-pkg/algorithms.cc
apt-pkg/algorithms.h
apt-pkg/depcache.cc
apt-pkg/depcache.h
apt-pkg/packagemanager.cc
cmdline/apt-get.cc
po/apt-all.pot

index 82ea19c935345f34843cb52136ea3154c76a05a9..ac9d3be0bea35a05c93d4545c1996c8c7a91f349 100644 (file)
 #include <apt-pkg/algorithms.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/configuration.h>
-#include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/version.h>
 #include <apt-pkg/sptr.h>
 
     
 #include <apti18n.h>
 #include <sys/types.h>
-#include <regex.h>
 #include <iostream>
                                                                        /*}}}*/
 using namespace std;
@@ -224,6 +222,8 @@ void pkgSimulate::ShortBreaks()
    the necessary calculations to deal with the problems. */
 bool pkgApplyStatus(pkgDepCache &Cache)
 {
+   pkgDepCache::ActionGroup group(Cache);
+
    for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
    {
       if (I->VersionList == 0)
@@ -234,13 +234,13 @@ bool pkgApplyStatus(pkgDepCache &Cache)
          I->InstState == pkgCache::State::HoldReInstReq)
       {
         if (I->CurrentVer != 0 && I.CurrentVer().Downloadable() == true)
-           Cache.MarkKeep(I);
+           Cache.MarkKeep(I, false, false);
         else
         {
            // Is this right? Will dpkg choke on an upgrade?
            if (Cache[I].CandidateVer != 0 &&
                 Cache[I].CandidateVerIter(Cache).Downloadable() == true)
-              Cache.MarkInstall(I);
+              Cache.MarkInstall(I, false, 0, false);
            else
               return _error->Error(_("The package %s needs to be reinstalled, "
                                    "but I can't find an archive for it."),I.Name());
@@ -257,12 +257,12 @@ bool pkgApplyStatus(pkgDepCache &Cache)
         case pkgCache::State::HalfConfigured:
         if ((I->CurrentVer != 0 && I.CurrentVer().Downloadable() == true) ||
             I.State() != pkgCache::PkgIterator::NeedsUnpack)
-           Cache.MarkKeep(I);
+           Cache.MarkKeep(I, false, false);
         else
         {
            if (Cache[I].CandidateVer != 0 &&
                 Cache[I].CandidateVerIter(Cache).Downloadable() == true)
-              Cache.MarkInstall(I);
+              Cache.MarkInstall(I, true, 0, false);
            else
               Cache.MarkDelete(I);
         }
@@ -288,10 +288,12 @@ bool pkgApplyStatus(pkgDepCache &Cache)
    on the result. */
 bool pkgFixBroken(pkgDepCache &Cache)
 {
+   pkgDepCache::ActionGroup group(Cache);
+
    // Auto upgrade all broken packages
    for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
       if (Cache[I].NowBroken() == true)
-        Cache.MarkInstall(I,true);
+        Cache.MarkInstall(I, true, 0, false);
    
    /* Fix packages that are in a NeedArchive state but don't have a
       downloadable install version */
@@ -304,7 +306,7 @@ bool pkgFixBroken(pkgDepCache &Cache)
       if (Cache[I].InstVerIter(Cache).Downloadable() == false)
         continue;
 
-      Cache.MarkInstall(I,true);      
+      Cache.MarkInstall(I, true, 0, false);
    }
    
    pkgProblemResolver Fix(&Cache);
@@ -321,23 +323,25 @@ bool pkgFixBroken(pkgDepCache &Cache)
  */
 bool pkgDistUpgrade(pkgDepCache &Cache)
 {
+   pkgDepCache::ActionGroup group(Cache);
+
    /* Auto upgrade all installed packages, this provides the basis 
       for the installation */
    for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
       if (I->CurrentVer != 0)
-        Cache.MarkInstall(I,true);
+        Cache.MarkInstall(I, true, 0, false);
 
    /* Now, auto upgrade all essential packages - this ensures that
       the essential packages are present and working */
    for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
       if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
-        Cache.MarkInstall(I,true);
+        Cache.MarkInstall(I, true, 0, false);
    
    /* We do it again over all previously installed packages to force 
       conflict resolution on them all. */
    for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
       if (I->CurrentVer != 0)
-        Cache.MarkInstall(I,false);
+        Cache.MarkInstall(I, false, 0, false);
 
    pkgProblemResolver Fix(&Cache);
 
@@ -349,7 +353,7 @@ bool pkgDistUpgrade(pkgDepCache &Cache)
         if (I->SelectedState == pkgCache::State::Hold)
         {
            Fix.Protect(I);
-           Cache.MarkKeep(I);
+           Cache.MarkKeep(I, false, false);
         }
       }
    }
@@ -364,6 +368,8 @@ bool pkgDistUpgrade(pkgDepCache &Cache)
    to install packages not marked for install */
 bool pkgAllUpgrade(pkgDepCache &Cache)
 {
+   pkgDepCache::ActionGroup group(Cache);
+
    pkgProblemResolver Fix(&Cache);
 
    if (Cache.BrokenCount() != 0)
@@ -380,7 +386,7 @@ bool pkgAllUpgrade(pkgDepCache &Cache)
            continue;
       
       if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
-        Cache.MarkInstall(I,false);
+        Cache.MarkInstall(I, false, 0, false);
    }
       
    return Fix.ResolveByKeep();
@@ -393,6 +399,8 @@ bool pkgAllUpgrade(pkgDepCache &Cache)
    the package is restored. */
 bool pkgMinimizeUpgrade(pkgDepCache &Cache)
 {   
+   pkgDepCache::ActionGroup group(Cache);
+
    if (Cache.BrokenCount() != 0)
       return false;
    
@@ -409,9 +417,9 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache)
            continue;
 
         // Keep it and see if that is OK
-        Cache.MarkKeep(I);
+        Cache.MarkKeep(I, false, false);
         if (Cache.BrokenCount() != 0)
-           Cache.MarkInstall(I,false);
+           Cache.MarkInstall(I, false, 0, false);
         else
         {
            // If keep didnt actually do anything then there was no change..
@@ -569,6 +577,8 @@ void pkgProblemResolver::MakeScores()
    installable */
 bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
 {
+   pkgDepCache::ActionGroup group(Cache);
+
    if ((Flags[Pkg->ID] & Upgradable) == 0 || Cache[Pkg].Upgradable() == false)
       return false;
    if ((Flags[Pkg->ID] & Protected) == Protected)
@@ -577,7 +587,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
    Flags[Pkg->ID] &= ~Upgradable;
    
    bool WasKept = Cache[Pkg].Keep();
-   Cache.MarkInstall(Pkg,false);
+   Cache.MarkInstall(Pkg, false, 0, false);
 
    // This must be a virtual package or something like that.
    if (Cache[Pkg].InstVerIter(Cache).end() == true)
@@ -662,7 +672,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
    if (Fail == true)
    {
       if (WasKept == true)
-        Cache.MarkKeep(Pkg);
+        Cache.MarkKeep(Pkg, false, false);
       else
         Cache.MarkDelete(Pkg);
       return false;
@@ -689,6 +699,8 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
    upgrade packages to advoid problems. */
 bool pkgProblemResolver::Resolve(bool BrokenFix)
 {
+   pkgDepCache::ActionGroup group(Cache);
+
    unsigned long Size = Cache.Head().PackageCount;
 
    // Record which packages are marked for install
@@ -704,7 +716,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
         {
            if (Cache[I].InstBroken() == true && BrokenFix == true)
            {
-              Cache.MarkInstall(I,false);
+              Cache.MarkInstall(I, false, 0, false);
               if (Cache[I].Install() == true)
                  Again = true;
            }
@@ -770,14 +782,14 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
            pkgCache::Version *OldVer = Cache[I].InstallVer;
            Flags[I->ID] &= ReInstateTried;
            
-           Cache.MarkInstall(I,false);
+           Cache.MarkInstall(I, false, 0, false);
            if (Cache[I].InstBroken() == true || 
                OldBreaks < Cache.BrokenCount())
            {
               if (OldVer == 0)
                  Cache.MarkDelete(I);
               else
-                 Cache.MarkKeep(I);
+                 Cache.MarkKeep(I, false, false);
            }       
            else
               if (Debug == true)
@@ -822,7 +834,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
                  {
                     if (Debug == true)
                        clog << "  Or group keep for " << I.Name() << endl;
-                    Cache.MarkKeep(I);
+                    Cache.MarkKeep(I, false, false);
                     Change = true;
                  }
               }
@@ -872,7 +884,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
               }
               
               Change = true;
-              Cache.MarkKeep(I);                 
+              Cache.MarkKeep(I, false, false);
               break;
            }
            
@@ -909,7 +921,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
                  /* See if a keep will do, unless the package is protected,
                     then installing it will be necessary */
                  bool Installed = Cache[I].Install();
-                 Cache.MarkKeep(I);
+                 Cache.MarkKeep(I, false, false);
                  if (Cache[I].InstBroken() == false)
                  {
                     // Unwind operation will be keep now
@@ -918,7 +930,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
                     
                     // Restore
                     if (InOr == true && Installed == true)
-                       Cache.MarkInstall(I,false);
+                       Cache.MarkInstall(I, false, 0, false);
                     
                     if (Debug == true)
                        clog << "  Holding Back " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl;
@@ -990,7 +1002,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
                  
                  // Restore
                  if (InOr == true && Installed == true)
-                    Cache.MarkInstall(I,false);
+                    Cache.MarkInstall(I, false, 0, false);
                  
                  if (Debug == true)
                     clog << "  Holding Back " << I.Name() << " because I can't find " << Start.TargetPkg().Name() << endl;
@@ -1035,7 +1047,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
               {
                  if (Debug == true)
                     clog << "  Fixing " << I.Name() << " via keep of " << J->Pkg.Name() << endl;
-                 Cache.MarkKeep(J->Pkg);
+                 Cache.MarkKeep(J->Pkg, false, false);
               }
 
               if (Counter > 1)
@@ -1089,6 +1101,8 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
    system was non-broken previously. */
 bool pkgProblemResolver::ResolveByKeep()
 {
+   pkgDepCache::ActionGroup group(Cache);
+
    unsigned long Size = Cache.Head().PackageCount;
 
    if (Debug == true)      
@@ -1122,7 +1136,7 @@ bool pkgProblemResolver::ResolveByKeep()
       {
         if (Debug == true)
            clog << "Keeping package " << I.Name() << endl;
-        Cache.MarkKeep(I);
+        Cache.MarkKeep(I, false, false);
         if (Cache[I].InstBroken() == false)
         {
            K = PList - 1;
@@ -1170,7 +1184,7 @@ bool pkgProblemResolver::ResolveByKeep()
               {
                  if (Debug == true)
                     clog << "  Keeping Package " << Pkg.Name() << " due to dep" << endl;
-                 Cache.MarkKeep(Pkg);
+                 Cache.MarkKeep(Pkg, false, false);
               }
               
               if (Cache[I].InstBroken() == false)
@@ -1207,6 +1221,8 @@ bool pkgProblemResolver::ResolveByKeep()
 /* This is used to make sure protected packages are installed */
 void pkgProblemResolver::InstallProtect()
 {
+   pkgDepCache::ActionGroup group(Cache);
+
    for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
    {
       if ((Flags[I->ID] & Protected) == Protected)
@@ -1214,7 +1230,7 @@ void pkgProblemResolver::InstallProtect()
         if ((Flags[I->ID] & ToRemove) == ToRemove)
            Cache.MarkDelete(I);
         else
-           Cache.MarkInstall(I,false);
+           Cache.MarkInstall(I, false, 0, false);
       }
    }   
 }
@@ -1251,247 +1267,3 @@ void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List)
 }
                                                                        /*}}}*/
 
-
-// mark a single package in Mark-and-Sweep
-void pkgMarkPackage(pkgDepCache &Cache,
-                   const pkgCache::PkgIterator &pkg,
-                   const pkgCache::VerIterator &ver,
-                   bool follow_recommends,
-                   bool follow_suggests)
-{
-   pkgDepCache::StateCache &state=Cache[pkg];
-   pkgCache::VerIterator candver=state.CandidateVerIter(Cache);
-   pkgCache::VerIterator instver=state.InstVerIter(Cache);
-
-#if 0
-   // If a package was garbage-collected but is now being marked, we
-   // should re-select it 
-   // For cases when a pkg is set to upgrade and this trigger the
-   // removal of a no-longer used dependency.  if the pkg is set to
-   // keep again later it will result in broken deps
-   if(state.Delete() && state.RemoveReason=pkgDepCache::Unused) 
-   {
-      if(ver==candver)
-        mark_install(pkg, false, false, NULL);
-      else if(ver==pkg.CurrentVer())
-        MarkKeep(pkg);
-      
-      instver=state.InstVerIter(*this);
-   }
-#endif
-
-   // Ignore versions other than the InstVer, and ignore packages
-   // that are already going to be removed or just left uninstalled.
-   if(!(ver==instver && !instver.end()))
-      return;
-
-   // if we are marked already we are done
-   if(state.Marked)
-      return;
-
-   //std::cout << "Setting Marked for: " << pkg.Name() << std::endl;
-   state.Marked=true;
-
-   if(!ver.end())
-   {
-     for(pkgCache::DepIterator d=ver.DependsList(); !d.end(); ++d)
-     {
-       if(d->Type==pkgCache::Dep::Depends ||
-          d->Type==pkgCache::Dep::PreDepends ||
-          (follow_recommends &&
-           d->Type==pkgCache::Dep::Recommends) ||
-          (follow_suggests &&
-           d->Type==pkgCache::Dep::Suggests))
-        {
-          // Try all versions of this package.
-          for(pkgCache::VerIterator V=d.TargetPkg().VersionList(); 
-              !V.end(); ++V)
-          {
-             if(_system->VS->CheckDep(V.VerStr(),d->CompareOp, d.TargetVer()))
-             {
-                pkgMarkPackage(Cache, V.ParentPkg(), V, 
-                               follow_recommends, follow_suggests);
-             }
-          }
-          // Now try virtual packages
-          for(pkgCache::PrvIterator prv=d.TargetPkg().ProvidesList(); 
-              !prv.end(); ++prv)
-          {
-             if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp, 
-                                      d.TargetVer()))
-             {
-                pkgMarkPackage(Cache, prv.OwnerPkg(), prv.OwnerVer(),
-                               follow_recommends, follow_suggests);
-             }
-          }
-       }
-     }
-   }
-}
-
-
-// Helper for APT::NeverAutoRemove, always include the packages matching
-// this regexp into the root-set
-inline bool 
-pkgMarkAlwaysInclude(pkgCache::PkgIterator p, vector<regex_t*> alwaysMark)
-{
-   for(unsigned int i=0;i<alwaysMark.size();i++)
-      if (regexec(alwaysMark[i],p.Name(),0,0,0) == 0)
-        return true;
-
-   return false;
-}
-
-bool pkgMarkUsed(pkgDepCache &Cache)
-{
-   InRootSetFunc f;
-   return pkgMarkUsed(Cache, f);
-}
-
-// the main mark algorithm
-bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc &userFunc)
-{
-   bool follow_recommends;
-   bool follow_suggests;
-
-   // init the states
-   for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p)
-   {
-      Cache[p].Marked=false;
-      Cache[p].Garbage=false;
-
-      // debug output
-      if(_config->FindB("Debug::pkgAutoRemove",false) 
-        && Cache[p].Flags & pkgCache::Flag::Auto)
-        std::clog << "AutoDep: " << p.Name() << std::endl;
-   }
-
-   // init vars
-   follow_recommends=_config->FindB("APT::AutoRemove::RecommendsImportant",false);
-   follow_suggests=_config->FindB("APT::AutoRemove::SuggestsImportant", false);
-
-
-   // init the "NeverAutoRemove" variable
-   vector<regex_t *> neverAutoRemoveRegexp;
-   Configuration::Item const *Opts;
-   Opts = _config->Tree("APT::NeverAutoRemove");
-   if (Opts != 0 && Opts->Child != 0)
-   {
-      Opts = Opts->Child;
-      for (; Opts != 0; Opts = Opts->Next)
-      {
-        if (Opts->Value.empty() == true)
-           continue;
-
-        regex_t *p = new regex_t;
-        if(regcomp(p,Opts->Value.c_str(),
-                   REG_EXTENDED | REG_ICASE |  REG_NOSUB) != 0)
-        {
-           regfree(p);
-           for(unsigned int i=0;i<neverAutoRemoveRegexp.size();i++)
-              regfree(neverAutoRemoveRegexp[i]);
-           return _error->Error("Regex compilation error for APT::NeverAutoRemove");
-        }
-        neverAutoRemoveRegexp.push_back(p);
-      }
-   }
-
-
-   // do the mark part, this is the core bit of the algorithm
-   for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p)
-   {
-      if( userFunc.InRootSet(p) ||
-          pkgMarkAlwaysInclude(p, neverAutoRemoveRegexp) ||
-        !(Cache[p].Flags & pkgCache::Flag::Auto) ||
-         (p->Flags & pkgCache::Flag::Essential))
-          
-      {
-        // the package is installed (and set to keep)
-        if(Cache[p].Keep() && !p.CurrentVer().end())
-           pkgMarkPackage(Cache, p, p.CurrentVer(),
-                          follow_recommends, follow_suggests);
-        // the package is to be installed 
-        else if(Cache[p].Install())
-           pkgMarkPackage(Cache, p, Cache[p].InstVerIter(Cache),
-                          follow_recommends, follow_suggests);
-      }
-   }
-
-
-   // do the sweep
-   for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p)
-  {
-     pkgDepCache::StateCache &state=Cache[p];
-
-     // if it is not marked and it is installed, it's garbage 
-     if(!state.Marked && !p.CurrentVer().end())
-     {
-       state.Garbage=true;
-       if(_config->FindB("Debug::pkgAutoRemove",false))
-          std::cout << "Garbage: " << p.Name() << std::endl;
-     
-#if 0   // mvo: the below bits still needs to be ported
-
-       // Be sure not to re-delete already deleted packages.
-       if(delete_unused && (!p.CurrentVer().end() || state.Install()) &&
-          !state.Delete())
-       {
-             bool do_delete=true;
-
-             // If the package is being upgraded, check if we're
-             // losing a versioned dep.  If the dependency matches
-             // the previous version and not the new version, keep
-             // the package back instead of removing it.
-             if(!p.CurrentVer().end() && state.Install())
-               {
-                 const char *vs=p.CurrentVer().VerStr();
-
-                 // Check direct revdeps only.  THIS ASSUMES NO
-                 // VERSIONED PROVIDES, but Debian probably won't
-                 // have them for ages if ever.
-                 for(pkgCache::DepIterator revdep=p.RevDependsList();
-                     !revdep.end(); ++revdep)
-                   {
-                     pkgCache::PkgIterator depender=revdep.ParentPkg();
-                     // Find which version of the depending package
-                     // will be installed.
-                     pkgCache::VerIterator instver=(*this)[depender].InstVerIter(*this);
-
-                     // Only pay attention to strong positive
-                     // dependencies whose parents will be installed.
-                     if(revdep.ParentVer()==instver &&
-                        (revdep->Type==pkgCache::Dep::Depends ||
-                         revdep->Type==pkgCache::Dep::PreDepends ||
-                         (revdep->Type==pkgCache::Dep::Recommends &&
-                          follow_recommends)))
-                       {
-                         // If the previous version matched, cancel the
-                         // deletion.  (note that I assume that the new
-                         // version does NOT match; otherwise it would
-                         // not be unused!)
-                         if(_system->VS->CheckDep(vs,
-                                                  revdep->CompareOp,
-                                                  revdep.TargetVer()))
-                           {
-                             mark_keep(p, false, false, undo);
-                             do_delete=false;
-                             break;
-                           }
-                       }
-                   }
-               }
-
-             if(do_delete)
-               mark_delete(p, false, true, undo);
-           }
-#endif
-     }
-  }
-
-   // cleanup
-   for(unsigned int i=0;i<neverAutoRemoveRegexp.size();i++)
-      regfree(neverAutoRemoveRegexp[i]);
-   
-
-   return true;
-}
index e539a410e32100f8837af46182da07795223203f..174a7f58d18aea15aa0c36bf2fde93c243a3de8a 100644 (file)
@@ -132,28 +132,5 @@ bool pkgAllUpgrade(pkgDepCache &Cache);
 bool pkgMinimizeUpgrade(pkgDepCache &Cache);
 
 void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List);
-
-
-// class that can be subclassed by the client to bring in
-// certain own packages into the root set (if the client returns
-// True the package will be considered as part of the root set)
-class InRootSetFunc
-{
- public:
-   virtual bool InRootSet(const pkgCache::PkgIterator &pkg) {return false;};
-   virtual ~InRootSetFunc() {};
-};
-
-
-// Mark all reachable packages with "pkgDepCache::StateCache.Marked=1"
-// the root-set are all essential packages+everything that was not 
-// installed automatically
-//
-// If InRootSetFunc is set, it will be called for each PkgIterator. This
-// is usefull for clients that have there own idea about the root-set
-// 
-// Everything that is not reach can be removed
-bool pkgMarkUsed(pkgDepCache &Cache);
-bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc &f);
                     
 #endif
index 4c52c6c719aa843d863dd2fc6a26b80557c5c234..22dd53f9779dff3885177a139e2ce24078dcdabd 100644 (file)
 
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/configuration.h>
+#include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/tagfile.h>
 
 #include <iostream>
 #include <sstream>    
 #include <apti18n.h>    
-                                                                       /*}}}*/
+
+pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) :
+  cache(cache), released(false)
+{
+  ++cache.group_level;
+}
+
+void pkgDepCache::ActionGroup::release()
+{
+  if(!released)
+    {
+      if(cache.group_level == 0)
+       std::cerr << "W: Unbalanced action groups, expect badness" << std::endl;
+      else
+       {
+         --cache.group_level;
+
+         if(cache.group_level == 0)
+           cache.MarkAndSweep();
+       }
+
+      released = false;
+    }
+}
+
+pkgDepCache::ActionGroup::~ActionGroup()
+{
+  release();
+}
 
 // DepCache::pkgDepCache - Constructors                                        /*{{{*/
 // ---------------------------------------------------------------------
 /* */
 pkgDepCache::pkgDepCache(pkgCache *pCache,Policy *Plcy) :
-                Cache(pCache), PkgState(0), DepState(0)
+  group_level(0), Cache(pCache), PkgState(0), DepState(0)
 {
    delLocalPolicy = 0;
    LocalPolicy = Plcy;
@@ -53,6 +82,10 @@ pkgDepCache::~pkgDepCache()
 /* This allocats the extension buffers and initializes them. */
 bool pkgDepCache::Init(OpProgress *Prog)
 {
+   // Suppress mark updates during this operation (just in case) and
+   // run a mark operation when Init terminates.
+   ActionGroup actions(*this);
+
    delete [] PkgState;
    delete [] DepState;
    PkgState = new StateCache[Head().PackageCount];
@@ -100,7 +133,7 @@ bool pkgDepCache::Init(OpProgress *Prog)
 
    if(Prog != 0)
       Prog->Done();
-   
+
    return true;
 } 
                                                                        /*}}}*/
@@ -161,7 +194,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog)
 
       if(PkgState[pkg->ID].Flags & Flag::Auto) {
         if(_config->FindB("Debug::pkgAutoRemove",false))
-           std::clog << "AutoInstal: " << pkg.Name() << std::endl;
+           std::clog << "AutoInstall: " << pkg.Name() << std::endl;
         ostr.str(string(""));
         ostr << "Package: " << pkg.Name() 
              << "\nAuto-Installed: 1\n\n";
@@ -522,16 +555,16 @@ void pkgDepCache::Update(OpProgress *Prog)
       AddStates(I);
    }
 
-   readStateFile(Prog);
-
    if (Prog != 0)      
       Prog->Progress(Done);
+
+   readStateFile(Prog);
 }
                                                                        /*}}}*/
 // DepCache::Update - Update the deps list of a package                        /*{{{*/
 // ---------------------------------------------------------------------
 /* This is a helper for update that only does the dep portion of the scan. 
-   It is mainly ment to scan reverse dependencies. */
+   It is mainly meant to scan reverse dependencies. */
 void pkgDepCache::Update(DepIterator D)
 {
    // Update the reverse deps
@@ -583,7 +616,7 @@ void pkgDepCache::Update(PkgIterator const &Pkg)
 // DepCache::MarkKeep - Put the package in the keep state              /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgDepCache::MarkKeep(PkgIterator const &Pkg,bool Soft)
+void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser)
 {
    // Simplifies other routines.
    if (Pkg.end() == true)
@@ -595,6 +628,9 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg,bool Soft)
        Pkg.CurrentVer().Downloadable() == false)
       return;
    
+   /** \todo Can this be moved later in the method? */
+   ActionGroup group(*this);
+
    /* We changed the soft state all the time so the UI is a bit nicer
       to use */
    StateCache &P = PkgState[Pkg->ID];
@@ -611,7 +647,8 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg,bool Soft)
    if (Pkg->VersionList == 0)
       return;
    
-   P.Flags &= ~Flag::Auto;
+   if(FromUser && !P.Marked)
+     P.Flags &= ~Flag::Auto;
    RemoveSizes(Pkg);
    RemoveStates(Pkg);
 
@@ -637,6 +674,8 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
    if (Pkg.end() == true)
       return;
 
+   ActionGroup group(*this);
+
    // Check that it is not already marked for delete
    StateCache &P = PkgState[Pkg->ID];
    P.iFlags &= ~(AutoKept | Purge);
@@ -659,8 +698,6 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
    else
       P.Mode = ModeDelete;
    P.InstallVer = 0;
-   // This was not inverted before, but I think it should be
-   P.Flags &= ~Flag::Auto;
 
    AddStates(Pkg);   
    Update(Pkg);
@@ -671,7 +708,7 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
 // ---------------------------------------------------------------------
 /* */
 void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
-                             unsigned long Depth)
+                             unsigned long Depth, bool FromUser)
 {
    if (Depth > 100)
       return;
@@ -680,6 +717,8 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
    if (Pkg.end() == true)
       return;
    
+   ActionGroup group(*this);
+
    /* Check that it is not already marked for install and that it can be 
       installed */
    StateCache &P = PkgState[Pkg->ID];
@@ -688,7 +727,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
        P.CandidateVer == (Version *)Pkg.CurrentVer()))
    {
       if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
-        MarkKeep(Pkg);
+        MarkKeep(Pkg, false, FromUser);
       return;
    }
 
@@ -708,9 +747,20 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
    
    P.Mode = ModeInstall;
    P.InstallVer = P.CandidateVer;
-   // invert the auto-flag only for new installs, not for upgrades
-   if(P.Status == 0)
-      P.Flags &= ~Flag::Auto;
+
+   if(FromUser)
+     {
+       // Set it to manual if it's a new install or cancelling the
+       // removal of a garbage package.
+       if(P.Status == 2 || (!Pkg.CurrentVer().end() && !P.Marked))
+        P.Flags &= ~Flag::Auto;
+     }
+   else
+     {
+       // Set it to auto if this is a new install.
+       if(P.Status == 2)
+        P.Flags |= Flag::Auto;
+     }
    if (P.CandidateVer == (Version *)Pkg.CurrentVer())
       P.Mode = ModeKeep;
        
@@ -788,13 +838,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
         }
         
         if (InstPkg.end() == false)
-        {
-           MarkInstall(InstPkg,true,Depth + 1);
-
-           // Set the autoflag, after MarkInstall because MarkInstall unsets it
-           if (P->CurrentVer == 0)
-              PkgState[InstPkg->ID].Flags |= Flag::Auto;
-        }
+          MarkInstall(InstPkg, true, Depth + 1, false);
         
         continue;
       }
@@ -809,7 +853,6 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
            PkgIterator Pkg = Ver.ParentPkg();
       
            MarkDelete(Pkg);
-           PkgState[Pkg->ID].Flags |= Flag::Auto;
         }
         continue;
       }      
@@ -821,6 +864,8 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 /* */
 void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
 {
+   ActionGroup group(*this);
+
    RemoveSizes(Pkg);
    RemoveStates(Pkg);
    
@@ -839,9 +884,11 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
 /* */
 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer)
 {
+   ActionGroup group(*this);
+
    pkgCache::PkgIterator Pkg = TargetVer.ParentPkg();
    StateCache &P = PkgState[Pkg->ID];
-   
+
    RemoveSizes(Pkg);
    RemoveStates(Pkg);
 
@@ -854,6 +901,18 @@ void pkgDepCache::SetCandidateVersion(VerIterator TargetVer)
    Update(Pkg);
    AddSizes(Pkg);
 }
+
+void pkgDepCache::MarkAuto(const PkgIterator &Pkg, bool Auto)
+{
+  StateCache &state = PkgState[Pkg->ID];
+
+  ActionGroup group(*this);
+
+  if(Auto)
+    state.Flags |= Flag::Auto;
+  else
+    state.Flags &= ~Flag::Auto;
+}
                                                                        /*}}}*/
 // StateCache::Update - Compute the various static display things      /*{{{*/
 // ---------------------------------------------------------------------
@@ -944,3 +1003,216 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep)
    return Dep.IsCritical();
 }
                                                                        /*}}}*/
+
+pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()
+  : constructedSuccessfully(false)
+{
+  Configuration::Item const *Opts;
+  Opts = _config->Tree("APT::NeverAutoRemove");
+  if (Opts != 0 && Opts->Child != 0)
+    {
+      Opts = Opts->Child;
+      for (; Opts != 0; Opts = Opts->Next)
+       {
+         if (Opts->Value.empty() == true)
+           continue;
+
+         regex_t *p = new regex_t;
+         if(regcomp(p,Opts->Value.c_str(),
+                    REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
+           {
+             regfree(p);
+             delete p;
+             _error->Error("Regex compilation error for APT::NeverAutoRemove");
+             return;
+           }
+
+         rootSetRegexp.push_back(p);
+       }
+    }
+
+  constructedSuccessfully = true;
+}
+
+pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc()
+{
+  for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
+    {
+      regfree(rootSetRegexp[i]);
+      delete rootSetRegexp[i];
+    }
+}
+
+
+bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg)
+{
+   for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
+      if (regexec(rootSetRegexp[i], pkg.Name(), 0, 0, 0) == 0)
+        return true;
+
+   return false;
+}
+
+pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc()
+{
+  DefaultRootSetFunc *f = new DefaultRootSetFunc;
+  if(f->wasConstructedSuccessfully())
+    return f;
+  else
+    {
+      delete f;
+      return NULL;
+    }
+}
+
+bool pkgDepCache::MarkFollowsRecommends()
+{
+  return _config->FindB("APT::AutoRemove::RecommendsImportant", true);
+}
+
+bool pkgDepCache::MarkFollowsSuggests()
+{
+  return _config->FindB("APT::AutoRemove::SuggestsImportant", false);
+}
+
+// the main mark algorithm
+bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
+{
+   bool follow_recommends;
+   bool follow_suggests;
+
+   // init the states
+   for(PkgIterator p = PkgBegin(); !p.end(); ++p)
+   {
+      PkgState[p->ID].Marked  = false;
+      PkgState[p->ID].Garbage = false;
+
+      // debug output
+      if(_config->FindB("Debug::pkgAutoRemove",false) 
+        && PkgState[p->ID].Flags & Flag::Auto)
+        std::clog << "AutoDep: " << p.Name() << std::endl;
+   }
+
+   // init vars
+   follow_recommends = MarkFollowsRecommends();
+   follow_suggests   = MarkFollowsSuggests();
+
+
+
+   // do the mark part, this is the core bit of the algorithm
+   for(PkgIterator p = PkgBegin(); !p.end(); ++p)
+   {
+      if(!(PkgState[p->ID].Flags & Flag::Auto) ||
+         (p->Flags & Flag::Essential) ||
+         userFunc.InRootSet(p))
+          
+      {
+        // the package is installed (and set to keep)
+        if(PkgState[p->ID].Keep() && !p.CurrentVer().end())
+           MarkPackage(p, p.CurrentVer(),
+                       follow_recommends, follow_suggests);
+        // the package is to be installed 
+        else if(PkgState[p->ID].Install())
+           MarkPackage(p, PkgState[p->ID].InstVerIter(*this),
+                       follow_recommends, follow_suggests);
+      }
+   }
+
+   return true;
+}
+
+// mark a single package in Mark-and-Sweep
+void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
+                             const pkgCache::VerIterator &ver,
+                             bool follow_recommends,
+                             bool follow_suggests)
+{
+   pkgDepCache::StateCache &state = PkgState[pkg->ID];
+   VerIterator candver            = state.CandidateVerIter(*this);
+   VerIterator instver            = state.InstVerIter(*this);
+
+#if 0
+   // If a package was garbage-collected but is now being marked, we
+   // should re-select it 
+   // For cases when a pkg is set to upgrade and this trigger the
+   // removal of a no-longer used dependency.  if the pkg is set to
+   // keep again later it will result in broken deps
+   if(state.Delete() && state.RemoveReason = Unused) 
+   {
+      if(ver==candver)
+        mark_install(pkg, false, false, NULL);
+      else if(ver==pkg.CurrentVer())
+        MarkKeep(pkg, false, false);
+      
+      instver=state.InstVerIter(*this);
+   }
+#endif
+
+   // Ignore versions other than the InstVer, and ignore packages
+   // that are already going to be removed or just left uninstalled.
+   if(!(ver == instver && !instver.end()))
+      return;
+
+   // if we are marked already we are done
+   if(state.Marked)
+      return;
+
+   //std::cout << "Setting Marked for: " << pkg.Name() << std::endl;
+   state.Marked=true;
+
+   if(!ver.end())
+   {
+     for(DepIterator d = ver.DependsList(); !d.end(); ++d)
+     {
+       if(d->Type == Dep::Depends ||
+          d->Type == Dep::PreDepends ||
+          (follow_recommends &&
+           d->Type == Dep::Recommends) ||
+          (follow_suggests &&
+           d->Type == Dep::Suggests))
+        {
+          // Try all versions of this package.
+          for(VerIterator V = d.TargetPkg().VersionList(); 
+              !V.end(); ++V)
+          {
+             if(_system->VS->CheckDep(V.VerStr(), d->CompareOp, d.TargetVer()))
+             {
+                MarkPackage(V.ParentPkg(), V, 
+                            follow_recommends, follow_suggests);
+             }
+          }
+          // Now try virtual packages
+          for(PrvIterator prv=d.TargetPkg().ProvidesList(); 
+              !prv.end(); ++prv)
+          {
+             if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp, 
+                                      d.TargetVer()))
+             {
+                MarkPackage(prv.OwnerPkg(), prv.OwnerVer(),
+                            follow_recommends, follow_suggests);
+             }
+          }
+       }
+     }
+   }
+}
+
+bool pkgDepCache::Sweep()
+{
+   // do the sweep
+   for(PkgIterator p=PkgBegin(); !p.end(); ++p)
+  {
+     StateCache &state=PkgState[p->ID];
+
+     // if it is not marked and it is installed, it's garbage 
+     if(!state.Marked && (!p.CurrentVer().end() || state.Install()) &&
+       !state.Delete())
+     {
+       state.Garbage=true;
+       if(_config->FindB("Debug::pkgAutoRemove",false))
+          std::cout << "Garbage: " << p.Name() << std::endl;
+     }
+  }   
+
+   return true;
+}
index 619daf8f67293b04230336e94aabd5eb83912cb7..fd935c2680f1f1cf68a9456dc3067e07a31af6bc 100644 (file)
@@ -1,4 +1,4 @@
-// -*- mode: cpp; mode: fold -*-
+// -*- mode: c++; mode: fold -*-
 // Description                                                         /*{{{*/
 // $Id: depcache.h,v 1.14 2001/02/20 07:03:17 jgg Exp $
 /* ######################################################################
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/progress.h>
 
+#include <regex.h>
+
+#include <vector>
+
 class pkgDepCache : protected pkgCache::Namespace
 {
    public:
+
+   /** \brief An arbitrary predicate on packages. */
+   class InRootSetFunc
+   {
+   public:
+     virtual bool InRootSet(const pkgCache::PkgIterator &pkg) {return false;};
+     virtual ~InRootSetFunc() {};
+   };
+
+   private:
+   /** \brief Mark a single package and all its unmarked important
+    *  dependencies during mark-and-sweep.
+    *
+    *  Recursively invokes itself to mark all dependencies of the
+    *  package.
+    *
+    *  \param pkg The package to mark.
+    *
+    *  \param ver The version of the package that is to be marked.
+    *
+    *  \param follow_recommends If \b true, recommendations of the
+    *  package will be recursively marked.
+    *
+    *  \param follow_suggests If \b true, suggestions of the package
+    *  will be recursively marked.
+    */
+   void MarkPackage(const pkgCache::PkgIterator &pkg,
+                   const pkgCache::VerIterator &ver,
+                   bool follow_recommends,
+                   bool follow_suggests);
+
+   /** \brief Update the Marked field of all packages.
+    *
+    *  Each package's StateCache::Marked field will be set to \b true
+    *  if and only if it can be reached from the root set.  By
+    *  default, the root set consists of the set of manually installed
+    *  or essential packages, but it can be extended using the
+    *  parameter #rootFunc.
+    *
+    *  \param rootFunc A callback that can be used to add extra
+    *  packages to the root set.
+    *
+    *  \return \b false if an error occured.
+    */
+   bool MarkRequired(InRootSetFunc &rootFunc);
+
+   /** \brief Set the StateCache::Garbage flag on all packages that
+    *  should be removed.
+    *
+    *  Packages that were not marked by the last call to #MarkRequired
+    *  are tested to see whether they are actually garbage.  If so,
+    *  they are marked as such.
+    *
+    *  \return \b false if an error occured.
+    */
+   bool Sweep();
+
+   public:
    
    // These flags are used in DepState
    enum DepFlags {DepNow = (1 << 0),DepInstall = (1 << 1),DepCVer = (1 << 2),
@@ -64,6 +126,83 @@ class pkgDepCache : protected pkgCache::Namespace
    enum VersionTypes {NowVersion, InstallVersion, CandidateVersion};
    enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2};
 
+   /** \brief Represents an active action group.
+    *
+    *  An action group is a group of actions that are currently being
+    *  performed.  While an active group is active, certain routine
+    *  clean-up actions that would normally be performed after every
+    *  cache operation are delayed until the action group is
+    *  completed.  This is necessary primarily to avoid inefficiencies
+    *  when modifying a large number of packages at once.
+    *
+    *  This class represents an active action group.  Creating an
+    *  instance will create an action group; destroying one will
+    *  destroy the corresponding action group.
+    *
+    *  The following operations are suppressed by this class:
+    *
+    *    - Keeping the Marked and Garbage flags up to date.
+    *
+    *  \note This can be used in the future to easily accumulate
+    *  atomic actions for undo or to display "what apt did anyway";
+    *  e.g., change the counter of how many action groups are active
+    *  to a std::set of pointers to them and use those to store
+    *  information about what happened in a group in the group.
+    */
+   class ActionGroup
+   {
+       pkgDepCache &cache;
+
+       bool released;
+
+       /** Action groups are noncopyable. */
+       ActionGroup(const ActionGroup &other);
+   public:
+       /** \brief Create a new ActionGroup.
+       *
+       *  \param cache The cache that this ActionGroup should
+       *  manipulate.
+       *
+       *  As long as this object exists, no automatic cleanup
+       *  operations will be undertaken.
+       */
+       ActionGroup(pkgDepCache &cache);
+
+       /** \brief Clean up the action group before it is destroyed.
+        *
+        *  If it is destroyed later, no second cleanup wil be run.
+       */
+       void release();
+
+       /** \brief Destroy the action group.
+       *
+       *  If this is the last action group, the automatic cache
+       *  cleanup operations will be undertaken.
+       */
+       ~ActionGroup();
+   };
+
+   /** \brief Returns \b true for packages matching a regular
+    *  expression in APT::NeverAutoRemove.
+    */
+   class DefaultRootSetFunc : public InRootSetFunc
+   {
+     std::vector<regex_t *> rootSetRegexp;
+     bool constructedSuccessfully;
+
+   public:
+     DefaultRootSetFunc();
+     ~DefaultRootSetFunc();
+
+     /** \return \b true if the class initialized successfully, \b
+      *  false otherwise.  Used to avoid throwing an exception, since
+      *  APT classes generally don't.
+      */
+     bool wasConstructedSuccessfully() const { return constructedSuccessfully; }
+
+     bool InRootSet(const pkgCache::PkgIterator &pkg);
+   };
+
    struct StateCache
    {
       // Epoch stripped text versions of the two version fields
@@ -80,8 +219,15 @@ class pkgDepCache : protected pkgCache::Namespace
       unsigned short Flags;
       unsigned short iFlags;           // Internal flags
 
-      // mark and sweep flags
+      /** \brief \b true if this package can be reached from the root set. */
       bool Marked;
+
+      /** \brief \b true if this package is unused and should be removed.
+       *
+       *  This differs from !#Marked, because it is possible that some
+       *  unreachable packages will be protected from becoming
+       *  garbage.
+       */
       bool Garbage;
 
       // Various tree indicators
@@ -124,6 +270,14 @@ class pkgDepCache : protected pkgCache::Namespace
       
       virtual ~Policy() {};
    };
+
+   private:
+   /** The number of open "action groups"; certain post-action
+    *  operations are suppressed if this number is > 0.
+    */
+   int group_level;
+
+   friend class ActionGroup;
      
    protected:
 
@@ -187,13 +341,61 @@ class pkgDepCache : protected pkgCache::Namespace
    inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];};
    inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];};
 
-   // Manipulators
-   void MarkKeep(PkgIterator const &Pkg,bool Soft = false);
+   /** \return A function identifying packages in the root set other
+    *  than manually installed packages and essential packages, or \b
+    *  NULL if an error occurs.
+    *
+    *  \todo Is this the best place for this function?  Perhaps the
+    *  settings for mark-and-sweep should be stored in a single
+    *  external class?
+    */
+   virtual InRootSetFunc *GetRootSetFunc();
+
+   /** \return \b true if the garbage collector should follow recommendations.
+    */
+   virtual bool MarkFollowsRecommends();
+
+   /** \return \b true if the garbage collector should follow suggestions.
+    */
+   virtual bool MarkFollowsSuggests();
+
+   /** \brief Update the Marked and Garbage fields of all packages.
+    *
+    *  This routine is implicitly invoked after all state manipulators
+    *  and when an ActionGroup is destroyed.  It invokes #MarkRequired
+    *  and #Sweep to do its dirty work.
+    *
+    *  \param rootFunc A predicate that returns \b true for packages
+    *  that should be added to the root set.
+    */
+   bool MarkAndSweep(InRootSetFunc &rootFunc)
+   {
+     return MarkRequired(rootFunc) && Sweep();
+   }
+
+   bool MarkAndSweep()
+   {
+     std::auto_ptr<InRootSetFunc> f(GetRootSetFunc());
+     if(f.get() != NULL)
+       return MarkAndSweep(*f.get());
+     else
+       return false;
+   }
+
+   /** \name State Manipulators
+    */
+   // @{
+   void MarkKeep(PkgIterator const &Pkg, bool Soft = false,
+                bool FromUser = true);
    void MarkDelete(PkgIterator const &Pkg,bool Purge = false);
    void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
-                   unsigned long Depth = 0);
+                   unsigned long Depth = 0, bool FromUser = true);
    void SetReInstall(PkgIterator const &Pkg,bool To);
    void SetCandidateVersion(VerIterator TargetVer);
+
+   /** Set the "is automatically installed" flag of Pkg. */
+   void MarkAuto(const PkgIterator &Pkg, bool Auto);
+   // @}
    
    // This is for debuging
    void Update(OpProgress *Prog = 0);
index 87a21004f85ec333d1100af8b45bd31e543a6eb5..05615db79a2b02751824e952578b529863e4e154 100644 (file)
@@ -106,7 +106,7 @@ bool pkgPackageManager::FixMissing()
    
       // Okay, this file is missing and we need it. Mark it for keep 
       Bad = true;
-      Cache.MarkKeep(I);
+      Cache.MarkKeep(I, false, false);
    }
  
    // We have to empty the list otherwise it will not have the new changes
index ac0d5607399603aac4dff2de0197b1c4153bad85..c8b64f5d800285bef16ea3eb56b810c6edb2048d 100644 (file)
@@ -1370,19 +1370,23 @@ bool DoAutomaticRemove(CacheFile &Cache)
       return _error->Error(_("We are not supposed to delete stuff, can't "
                             "start AutoRemover"));
 
-   // do the actual work
-   pkgMarkUsed(Cache);
-
-   // look over the cache to see what can be removed
-   for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg)
    {
-      if (Cache[Pkg].Garbage &&
-          (Pkg->CurrentVer != 0 && Cache[Pkg].Install() == false && 
-          Cache[Pkg].Delete() == false))
-      {
-         fprintf(stdout,"We could delete %s\n", Pkg.Name());
-         Cache->MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
-      }
+     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());
+
+            if(Pkg.CurrentVer() != 0 && Pkg->CurrentState != pkgCache::State::ConfigFiles)
+              Cache->MarkDelete(Pkg, _config->FindB("APT::Get::Purge", false));
+            else
+              Cache->MarkKeep(Pkg, false, false);
+          }
+       }
    }
 
    // Now see if we destroyed anything
@@ -1399,6 +1403,7 @@ bool DoAutomaticRemove(CacheFile &Cache)
    }
    return true;
 }
+
 // DoUpgrade - Upgrade all packages                                    /*{{{*/
 // ---------------------------------------------------------------------
 /* Upgrade all packages without installing new packages or erasing old
@@ -1450,6 +1455,11 @@ 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");
+       DefRemove = true;
+     }
 
    for (const char **I = CmdL.FileList + 1; *I != 0; I++)
    {
@@ -2533,6 +2543,7 @@ int main(int argc,const char *argv[])
                                    {"upgrade",&DoUpgrade},
                                    {"install",&DoInstall},
                                    {"remove",&DoInstall},
+                                  {"autoremove",&DoInstall},
                                    {"dist-upgrade",&DoDistUpgrade},
                                    {"dselect-upgrade",&DoDSelectUpgrade},
                                   {"build-dep",&DoBuildDep},
index d06c14ce13af7192e1c774cc4453cbb3a0e4265c..bca32b3277ef43ebf9a9a47e99759b2b148f79b4 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2005-06-06 14:00+0200\n"
+"POT-Creation-Date: 2005-11-02 18:56-0500\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -147,8 +147,8 @@ msgid "       %4i %s\n"
 msgstr ""
 
 #: cmdline/apt-cache.cc:1651 cmdline/apt-cdrom.cc:138 cmdline/apt-config.cc:70
-#: cmdline/apt-extracttemplates.cc:225 ftparchive/apt-ftparchive.cc:545
-#: cmdline/apt-get.cc:2322 cmdline/apt-sortpkgs.cc:144
+#: cmdline/apt-extracttemplates.cc:225 ftparchive/apt-ftparchive.cc:550
+#: cmdline/apt-get.cc:2375 cmdline/apt-sortpkgs.cc:144
 #, c-format
 msgid "%s %s for %s %s compiled on %s %s\n"
 msgstr ""
@@ -231,7 +231,7 @@ msgid ""
 "  -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
 msgstr ""
 
-#: cmdline/apt-extracttemplates.cc:267 apt-pkg/pkgcachegen.cc:710
+#: cmdline/apt-extracttemplates.cc:267 apt-pkg/pkgcachegen.cc:712
 #, c-format
 msgid "Unable to write to %s"
 msgstr ""
@@ -240,31 +240,31 @@ msgstr ""
 msgid "Cannot get debconf version. Is debconf installed?"
 msgstr ""
 
-#: ftparchive/apt-ftparchive.cc:163 ftparchive/apt-ftparchive.cc:337
+#: ftparchive/apt-ftparchive.cc:167 ftparchive/apt-ftparchive.cc:341
 msgid "Package extension list is too long"
 msgstr ""
 
-#: ftparchive/apt-ftparchive.cc:165 ftparchive/apt-ftparchive.cc:179
-#: ftparchive/apt-ftparchive.cc:202 ftparchive/apt-ftparchive.cc:252
-#: ftparchive/apt-ftparchive.cc:266 ftparchive/apt-ftparchive.cc:288
+#: ftparchive/apt-ftparchive.cc:169 ftparchive/apt-ftparchive.cc:183
+#: ftparchive/apt-ftparchive.cc:206 ftparchive/apt-ftparchive.cc:256
+#: ftparchive/apt-ftparchive.cc:270 ftparchive/apt-ftparchive.cc:292
 #, c-format
 msgid "Error processing directory %s"
 msgstr ""
 
-#: ftparchive/apt-ftparchive.cc:250
+#: ftparchive/apt-ftparchive.cc:254
 msgid "Source extension list is too long"
 msgstr ""
 
-#: ftparchive/apt-ftparchive.cc:367
+#: ftparchive/apt-ftparchive.cc:371
 msgid "Error writing header to contents file"
 msgstr ""
 
-#: ftparchive/apt-ftparchive.cc:397
+#: ftparchive/apt-ftparchive.cc:401
 #, c-format
 msgid "Error processing contents %s"
 msgstr ""
 
-#: ftparchive/apt-ftparchive.cc:551
+#: ftparchive/apt-ftparchive.cc:556
 msgid ""
 "Usage: apt-ftparchive [options] command\n"
 "Commands: packages binarypath [overridefile [pathprefix]]\n"
@@ -306,11 +306,11 @@ msgid ""
 "  -o=?  Set an arbitrary configuration option"
 msgstr ""
 
-#: ftparchive/apt-ftparchive.cc:757
+#: ftparchive/apt-ftparchive.cc:762
 msgid "No selections matched"
 msgstr ""
 
-#: ftparchive/apt-ftparchive.cc:830
+#: ftparchive/apt-ftparchive.cc:835
 #, c-format
 msgid "Some files are missing in the package file group `%s'"
 msgstr ""
@@ -343,83 +343,83 @@ msgstr ""
 msgid "Unable to get a cursor"
 msgstr ""
 
-#: ftparchive/writer.cc:79
+#: ftparchive/writer.cc:78
 #, c-format
 msgid "W: Unable to read directory %s\n"
 msgstr ""
 
-#: ftparchive/writer.cc:84
+#: ftparchive/writer.cc:83
 #, c-format
 msgid "W: Unable to stat %s\n"
 msgstr ""
 
-#: ftparchive/writer.cc:126
+#: ftparchive/writer.cc:125
 msgid "E: "
 msgstr ""
 
-#: ftparchive/writer.cc:128
+#: ftparchive/writer.cc:127
 msgid "W: "
 msgstr ""
 
-#: ftparchive/writer.cc:135
+#: ftparchive/writer.cc:134
 msgid "E: Errors apply to file "
 msgstr ""
 
-#: ftparchive/writer.cc:152 ftparchive/writer.cc:182
+#: ftparchive/writer.cc:151 ftparchive/writer.cc:181
 #, c-format
 msgid "Failed to resolve %s"
 msgstr ""
 
-#: ftparchive/writer.cc:164
+#: ftparchive/writer.cc:163
 msgid "Tree walking failed"
 msgstr ""
 
-#: ftparchive/writer.cc:189
+#: ftparchive/writer.cc:188
 #, c-format
 msgid "Failed to open %s"
 msgstr ""
 
-#: ftparchive/writer.cc:246
+#: ftparchive/writer.cc:245
 #, c-format
 msgid " DeLink %s [%s]\n"
 msgstr ""
 
-#: ftparchive/writer.cc:254
+#: ftparchive/writer.cc:253
 #, c-format
 msgid "Failed to readlink %s"
 msgstr ""
 
-#: ftparchive/writer.cc:258
+#: ftparchive/writer.cc:257
 #, c-format
 msgid "Failed to unlink %s"
 msgstr ""
 
-#: ftparchive/writer.cc:265
+#: ftparchive/writer.cc:264
 #, c-format
 msgid "*** Failed to link %s to %s"
 msgstr ""
 
-#: ftparchive/writer.cc:275
+#: ftparchive/writer.cc:274
 #, c-format
 msgid " DeLink limit of %sB hit.\n"
 msgstr ""
 
 #: ftparchive/writer.cc:358 apt-inst/extract.cc:181 apt-inst/extract.cc:193
-#: apt-inst/extract.cc:210 apt-inst/deb/dpkgdb.cc:121
+#: apt-inst/extract.cc:210 apt-inst/deb/dpkgdb.cc:121 methods/gpgv.cc:256
 #, c-format
 msgid "Failed to stat %s"
 msgstr ""
 
-#: ftparchive/writer.cc:378
+#: ftparchive/writer.cc:386
 msgid "Archive had no package field"
 msgstr ""
 
-#: ftparchive/writer.cc:386 ftparchive/writer.cc:595
+#: ftparchive/writer.cc:394 ftparchive/writer.cc:602
 #, c-format
 msgid "  %s has no override entry\n"
 msgstr ""
 
-#: ftparchive/writer.cc:429 ftparchive/writer.cc:677
+#: ftparchive/writer.cc:437 ftparchive/writer.cc:688
 #, c-format
 msgid "  %s maintainer is %s not %s\n"
 msgstr ""
@@ -519,200 +519,221 @@ msgstr ""
 msgid "Failed to rename %s to %s"
 msgstr ""
 
-#: cmdline/apt-get.cc:118
+#: cmdline/apt-get.cc:119
 msgid "Y"
 msgstr ""
 
-#: cmdline/apt-get.cc:140 cmdline/apt-get.cc:1484
+#: cmdline/apt-get.cc:141 cmdline/apt-get.cc:1532
 #, c-format
 msgid "Regex compilation error - %s"
 msgstr ""
 
-#: cmdline/apt-get.cc:235
+#: cmdline/apt-get.cc:236
 msgid "The following packages have unmet dependencies:"
 msgstr ""
 
-#: cmdline/apt-get.cc:325
+#: cmdline/apt-get.cc:326
 #, c-format
 msgid "but %s is installed"
 msgstr ""
 
-#: cmdline/apt-get.cc:327
+#: cmdline/apt-get.cc:328
 #, c-format
 msgid "but %s is to be installed"
 msgstr ""
 
-#: cmdline/apt-get.cc:334
+#: cmdline/apt-get.cc:335
 msgid "but it is not installable"
 msgstr ""
 
-#: cmdline/apt-get.cc:336
+#: cmdline/apt-get.cc:337
 msgid "but it is a virtual package"
 msgstr ""
 
-#: cmdline/apt-get.cc:339
+#: cmdline/apt-get.cc:340
 msgid "but it is not installed"
 msgstr ""
 
-#: cmdline/apt-get.cc:339
+#: cmdline/apt-get.cc:340
 msgid "but it is not going to be installed"
 msgstr ""
 
-#: cmdline/apt-get.cc:344
+#: cmdline/apt-get.cc:345
 msgid " or"
 msgstr ""
 
-#: cmdline/apt-get.cc:373
+#: cmdline/apt-get.cc:374
 msgid "The following NEW packages will be installed:"
 msgstr ""
 
-#: cmdline/apt-get.cc:399
+#: cmdline/apt-get.cc:400
 msgid "The following packages will be REMOVED:"
 msgstr ""
 
-#: cmdline/apt-get.cc:421
+#: cmdline/apt-get.cc:422
 msgid "The following packages have been kept back:"
 msgstr ""
 
-#: cmdline/apt-get.cc:442
+#: cmdline/apt-get.cc:443
 msgid "The following packages will be upgraded:"
 msgstr ""
 
-#: cmdline/apt-get.cc:463
+#: cmdline/apt-get.cc:464
 msgid "The following packages will be DOWNGRADED:"
 msgstr ""
 
-#: cmdline/apt-get.cc:483
+#: cmdline/apt-get.cc:484
 msgid "The following held packages will be changed:"
 msgstr ""
 
-#: cmdline/apt-get.cc:536
+#: cmdline/apt-get.cc:537
 #, c-format
 msgid "%s (due to %s) "
 msgstr ""
 
-#: cmdline/apt-get.cc:544
+#: cmdline/apt-get.cc:545
 msgid ""
 "WARNING: The following essential packages will be removed.\n"
 "This should NOT be done unless you know exactly what you are doing!"
 msgstr ""
 
-#: cmdline/apt-get.cc:575
+#: cmdline/apt-get.cc:576
 #, c-format
 msgid "%lu upgraded, %lu newly installed, "
 msgstr ""
 
-#: cmdline/apt-get.cc:579
+#: cmdline/apt-get.cc:580
 #, c-format
 msgid "%lu reinstalled, "
 msgstr ""
 
-#: cmdline/apt-get.cc:581
+#: cmdline/apt-get.cc:582
 #, c-format
 msgid "%lu downgraded, "
 msgstr ""
 
-#: cmdline/apt-get.cc:583
+#: cmdline/apt-get.cc:584
 #, c-format
 msgid "%lu to remove and %lu not upgraded.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:587
+#: cmdline/apt-get.cc:588
 #, c-format
 msgid "%lu not fully installed or removed.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:647
+#: cmdline/apt-get.cc:648
 msgid "Correcting dependencies..."
 msgstr ""
 
-#: cmdline/apt-get.cc:650
+#: cmdline/apt-get.cc:651
 msgid " failed."
 msgstr ""
 
-#: cmdline/apt-get.cc:653
+#: cmdline/apt-get.cc:654
 msgid "Unable to correct dependencies"
 msgstr ""
 
-#: cmdline/apt-get.cc:656
+#: cmdline/apt-get.cc:657
 msgid "Unable to minimize the upgrade set"
 msgstr ""
 
-#: cmdline/apt-get.cc:658
+#: cmdline/apt-get.cc:659
 msgid " Done"
 msgstr ""
 
-#: cmdline/apt-get.cc:662
+#: cmdline/apt-get.cc:663
 msgid "You might want to run `apt-get -f install' to correct these."
 msgstr ""
 
-#: cmdline/apt-get.cc:665
+#: cmdline/apt-get.cc:666
 msgid "Unmet dependencies. Try using -f."
 msgstr ""
 
-#: cmdline/apt-get.cc:687
+#: cmdline/apt-get.cc:688
 msgid "WARNING: The following packages cannot be authenticated!"
 msgstr ""
 
-#: cmdline/apt-get.cc:698
+#: cmdline/apt-get.cc:692
+msgid "Authentication warning overridden.\n"
+msgstr ""
+
+#: cmdline/apt-get.cc:699
 msgid "Install these packages without verification [y/N]? "
 msgstr ""
 
-#: cmdline/apt-get.cc:700
+#: cmdline/apt-get.cc:701
 msgid "Some packages could not be authenticated"
 msgstr ""
 
-#: cmdline/apt-get.cc:709 cmdline/apt-get.cc:855
+#: cmdline/apt-get.cc:710 cmdline/apt-get.cc:857
 msgid "There are problems and -y was used without --force-yes"
 msgstr ""
 
-#: cmdline/apt-get.cc:762
+#: cmdline/apt-get.cc:754
+msgid "Internal error, InstallPackages was called with broken packages!"
+msgstr ""
+
+#: cmdline/apt-get.cc:763
 msgid "Packages need to be removed but remove is disabled."
 msgstr ""
 
-#: cmdline/apt-get.cc:788 cmdline/apt-get.cc:1778 cmdline/apt-get.cc:1811
+#: cmdline/apt-get.cc:774
+msgid "Internal error, Ordering didn't finish"
+msgstr ""
+
+#: cmdline/apt-get.cc:790 cmdline/apt-get.cc:1831 cmdline/apt-get.cc:1864
 msgid "Unable to lock the download directory"
 msgstr ""
 
-#: cmdline/apt-get.cc:798 cmdline/apt-get.cc:1859 cmdline/apt-get.cc:2070
+#: cmdline/apt-get.cc:800 cmdline/apt-get.cc:1912 cmdline/apt-get.cc:2123
 #: apt-pkg/cachefile.cc:67
 msgid "The list of sources could not be read."
 msgstr ""
 
-#: cmdline/apt-get.cc:818
+#: cmdline/apt-get.cc:815
+msgid "How odd.. The sizes didn't match, email apt@packages.debian.org"
+msgstr ""
+
+#: cmdline/apt-get.cc:820
 #, c-format
 msgid "Need to get %sB/%sB of archives.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:821
+#: cmdline/apt-get.cc:823
 #, c-format
 msgid "Need to get %sB of archives.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:826
+#: cmdline/apt-get.cc:828
 #, c-format
 msgid "After unpacking %sB of additional disk space will be used.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:829
+#: cmdline/apt-get.cc:831
 #, c-format
 msgid "After unpacking %sB disk space will be freed.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:846
+#: cmdline/apt-get.cc:845 cmdline/apt-get.cc:1978
+#, c-format
+msgid "Couldn't determine free space in %s"
+msgstr ""
+
+#: cmdline/apt-get.cc:848
 #, c-format
 msgid "You don't have enough free space in %s."
 msgstr ""
 
-#: cmdline/apt-get.cc:861 cmdline/apt-get.cc:881
+#: cmdline/apt-get.cc:863 cmdline/apt-get.cc:883
 msgid "Trivial Only specified but this is not a trivial operation."
 msgstr ""
 
-#: cmdline/apt-get.cc:863
+#: cmdline/apt-get.cc:865
 msgid "Yes, do as I say!"
 msgstr ""
 
-#: cmdline/apt-get.cc:865
+#: cmdline/apt-get.cc:867
 #, c-format
 msgid ""
 "You are about to do something potentially harmful.\n"
@@ -720,74 +741,74 @@ msgid ""
 " ?] "
 msgstr ""
 
-#: cmdline/apt-get.cc:871 cmdline/apt-get.cc:890
+#: cmdline/apt-get.cc:873 cmdline/apt-get.cc:892
 msgid "Abort."
 msgstr ""
 
-#: cmdline/apt-get.cc:886
+#: cmdline/apt-get.cc:888
 msgid "Do you want to continue [Y/n]? "
 msgstr ""
 
-#: cmdline/apt-get.cc:958 cmdline/apt-get.cc:1334 cmdline/apt-get.cc:1968
+#: cmdline/apt-get.cc:960 cmdline/apt-get.cc:1337 cmdline/apt-get.cc:2021
 #, c-format
 msgid "Failed to fetch %s  %s\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:976
+#: cmdline/apt-get.cc:978
 msgid "Some files failed to download"
 msgstr ""
 
-#: cmdline/apt-get.cc:977 cmdline/apt-get.cc:1977
+#: cmdline/apt-get.cc:979 cmdline/apt-get.cc:2030
 msgid "Download complete and in download only mode"
 msgstr ""
 
-#: cmdline/apt-get.cc:983
+#: cmdline/apt-get.cc:985
 msgid ""
 "Unable to fetch some archives, maybe run apt-get update or try with --fix-"
 "missing?"
 msgstr ""
 
-#: cmdline/apt-get.cc:987
+#: cmdline/apt-get.cc:989
 msgid "--fix-missing and media swapping is not currently supported"
 msgstr ""
 
-#: cmdline/apt-get.cc:992
+#: cmdline/apt-get.cc:994
 msgid "Unable to correct missing packages."
 msgstr ""
 
-#: cmdline/apt-get.cc:993
+#: cmdline/apt-get.cc:995
 msgid "Aborting install."
 msgstr ""
 
-#: cmdline/apt-get.cc:1026
+#: cmdline/apt-get.cc:1029
 #, c-format
 msgid "Note, selecting %s instead of %s\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:1036
+#: cmdline/apt-get.cc:1039
 #, c-format
 msgid "Skipping %s, it is already installed and upgrade is not set.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:1054
+#: cmdline/apt-get.cc:1057
 #, c-format
 msgid "Package %s is not installed, so not removed\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:1065
+#: cmdline/apt-get.cc:1068
 #, c-format
 msgid "Package %s is a virtual package provided by:\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:1077
+#: cmdline/apt-get.cc:1080
 msgid " [Installed]"
 msgstr ""
 
-#: cmdline/apt-get.cc:1082
+#: cmdline/apt-get.cc:1085
 msgid "You should explicitly select one to install."
 msgstr ""
 
-#: cmdline/apt-get.cc:1087
+#: cmdline/apt-get.cc:1090
 #, c-format
 msgid ""
 "Package %s is not available, but is referred to by another package.\n"
@@ -795,79 +816,97 @@ msgid ""
 "is only available from another source\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:1106
+#: cmdline/apt-get.cc:1109
 msgid "However the following packages replace it:"
 msgstr ""
 
-#: cmdline/apt-get.cc:1109
+#: cmdline/apt-get.cc:1112
 #, c-format
 msgid "Package %s has no installation candidate"
 msgstr ""
 
-#: cmdline/apt-get.cc:1129
+#: cmdline/apt-get.cc:1132
 #, c-format
 msgid "Reinstallation of %s is not possible, it cannot be downloaded.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:1137
+#: cmdline/apt-get.cc:1140
 #, c-format
 msgid "%s is already the newest version.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:1164
+#: cmdline/apt-get.cc:1167
 #, c-format
 msgid "Release '%s' for '%s' was not found"
 msgstr ""
 
-#: cmdline/apt-get.cc:1166
+#: cmdline/apt-get.cc:1169
 #, c-format
 msgid "Version '%s' for '%s' was not found"
 msgstr ""
 
-#: cmdline/apt-get.cc:1172
+#: cmdline/apt-get.cc:1175
 #, c-format
 msgid "Selected version %s (%s) for %s\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:1282
+#: cmdline/apt-get.cc:1285
 msgid "The update command takes no arguments"
 msgstr ""
 
-#: cmdline/apt-get.cc:1295 cmdline/apt-get.cc:1389
+#: cmdline/apt-get.cc:1298 cmdline/apt-get.cc:1437
 msgid "Unable to lock the list directory"
 msgstr ""
 
-#: cmdline/apt-get.cc:1353
+#: cmdline/apt-get.cc:1356
 msgid ""
 "Some index files failed to download, they have been ignored, or old ones "
 "used instead."
 msgstr ""
 
-#: cmdline/apt-get.cc:1372
+#: cmdline/apt-get.cc:1370
+msgid "We are not supposed to delete stuff, can't start AutoRemover"
+msgstr ""
+
+#: cmdline/apt-get.cc:1395
+msgid ""
+"Hmm, seems like the AutoRemover destroyed something which really\n"
+"shouldn't happen. Please file a bug report against apt."
+msgstr ""
+
+#: cmdline/apt-get.cc:1398 cmdline/apt-get.cc:1600
+msgid "The following information may help to resolve the situation:"
+msgstr ""
+
+#: cmdline/apt-get.cc:1402
+msgid "Internal Error, AutoRemover broke stuff"
+msgstr ""
+
+#: cmdline/apt-get.cc:1420
 msgid "Internal error, AllUpgrade broke stuff"
 msgstr ""
 
-#: cmdline/apt-get.cc:1471 cmdline/apt-get.cc:1507
+#: cmdline/apt-get.cc:1519 cmdline/apt-get.cc:1555
 #, c-format
 msgid "Couldn't find package %s"
 msgstr ""
 
-#: cmdline/apt-get.cc:1494
+#: cmdline/apt-get.cc:1542
 #, c-format
 msgid "Note, selecting %s for regex '%s'\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:1524
+#: cmdline/apt-get.cc:1572
 msgid "You might want to run `apt-get -f install' to correct these:"
 msgstr ""
 
-#: cmdline/apt-get.cc:1527
+#: cmdline/apt-get.cc:1575
 msgid ""
 "Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a "
 "solution)."
 msgstr ""
 
-#: cmdline/apt-get.cc:1539
+#: cmdline/apt-get.cc:1587
 msgid ""
 "Some packages could not be installed. This may mean that you have\n"
 "requested an impossible situation or if you are using the unstable\n"
@@ -875,149 +914,149 @@ msgid ""
 "or been moved out of Incoming."
 msgstr ""
 
-#: cmdline/apt-get.cc:1547
+#: cmdline/apt-get.cc:1595
 msgid ""
 "Since you only requested a single operation it is extremely likely that\n"
 "the package is simply not installable and a bug report against\n"
 "that package should be filed."
 msgstr ""
 
-#: cmdline/apt-get.cc:1552
-msgid "The following information may help to resolve the situation:"
-msgstr ""
-
-#: cmdline/apt-get.cc:1555
+#: cmdline/apt-get.cc:1603
 msgid "Broken packages"
 msgstr ""
 
-#: cmdline/apt-get.cc:1581
+#: cmdline/apt-get.cc:1634
 msgid "The following extra packages will be installed:"
 msgstr ""
 
-#: cmdline/apt-get.cc:1652
+#: cmdline/apt-get.cc:1705
 msgid "Suggested packages:"
 msgstr ""
 
-#: cmdline/apt-get.cc:1653
+#: cmdline/apt-get.cc:1706
 msgid "Recommended packages:"
 msgstr ""
 
-#: cmdline/apt-get.cc:1673
+#: cmdline/apt-get.cc:1726
 msgid "Calculating upgrade... "
 msgstr ""
 
-#: cmdline/apt-get.cc:1676 methods/ftp.cc:702 methods/connect.cc:99
+#: cmdline/apt-get.cc:1729 methods/ftp.cc:702 methods/connect.cc:101
 msgid "Failed"
 msgstr ""
 
-#: cmdline/apt-get.cc:1681
+#: cmdline/apt-get.cc:1734
 msgid "Done"
 msgstr ""
 
-#: cmdline/apt-get.cc:1854
+#: cmdline/apt-get.cc:1799 cmdline/apt-get.cc:1807
+msgid "Internal error, problem resolver broke stuff"
+msgstr ""
+
+#: cmdline/apt-get.cc:1907
 msgid "Must specify at least one package to fetch source for"
 msgstr ""
 
-#: cmdline/apt-get.cc:1881 cmdline/apt-get.cc:2088
+#: cmdline/apt-get.cc:1934 cmdline/apt-get.cc:2141
 #, c-format
 msgid "Unable to find a source package for %s"
 msgstr ""
 
-#: cmdline/apt-get.cc:1928
+#: cmdline/apt-get.cc:1981
 #, c-format
 msgid "You don't have enough free space in %s"
 msgstr ""
 
-#: cmdline/apt-get.cc:1933
+#: cmdline/apt-get.cc:1986
 #, c-format
 msgid "Need to get %sB/%sB of source archives.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:1936
+#: cmdline/apt-get.cc:1989
 #, c-format
 msgid "Need to get %sB of source archives.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:1942
+#: cmdline/apt-get.cc:1995
 #, c-format
 msgid "Fetch source %s\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:1973
+#: cmdline/apt-get.cc:2026
 msgid "Failed to fetch some archives."
 msgstr ""
 
-#: cmdline/apt-get.cc:2001
+#: cmdline/apt-get.cc:2054
 #, c-format
 msgid "Skipping unpack of already unpacked source in %s\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:2013
+#: cmdline/apt-get.cc:2066
 #, c-format
 msgid "Unpack command '%s' failed.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:2030
+#: cmdline/apt-get.cc:2083
 #, c-format
 msgid "Build command '%s' failed.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:2049
+#: cmdline/apt-get.cc:2102
 msgid "Child process failed"
 msgstr ""
 
-#: cmdline/apt-get.cc:2065
+#: cmdline/apt-get.cc:2118
 msgid "Must specify at least one package to check builddeps for"
 msgstr ""
 
-#: cmdline/apt-get.cc:2093
+#: cmdline/apt-get.cc:2146
 #, c-format
 msgid "Unable to get build-dependency information for %s"
 msgstr ""
 
-#: cmdline/apt-get.cc:2113
+#: cmdline/apt-get.cc:2166
 #, c-format
 msgid "%s has no build depends.\n"
 msgstr ""
 
-#: cmdline/apt-get.cc:2165
+#: cmdline/apt-get.cc:2218
 #, c-format
 msgid ""
 "%s dependency for %s cannot be satisfied because the package %s cannot be "
 "found"
 msgstr ""
 
-#: cmdline/apt-get.cc:2217
+#: cmdline/apt-get.cc:2270
 #, c-format
 msgid ""
 "%s dependency for %s cannot be satisfied because no available versions of "
 "package %s can satisfy version requirements"
 msgstr ""
 
-#: cmdline/apt-get.cc:2252
+#: cmdline/apt-get.cc:2305
 #, c-format
 msgid "Failed to satisfy %s dependency for %s: Installed package %s is too new"
 msgstr ""
 
-#: cmdline/apt-get.cc:2277
+#: cmdline/apt-get.cc:2330
 #, c-format
 msgid "Failed to satisfy %s dependency for %s: %s"
 msgstr ""
 
-#: cmdline/apt-get.cc:2291
+#: cmdline/apt-get.cc:2344
 #, c-format
 msgid "Build-dependencies for %s could not be satisfied."
 msgstr ""
 
-#: cmdline/apt-get.cc:2295
+#: cmdline/apt-get.cc:2348
 msgid "Failed to process build dependencies"
 msgstr ""
 
-#: cmdline/apt-get.cc:2327
+#: cmdline/apt-get.cc:2380
 msgid "Supported modules:"
 msgstr ""
 
-#: cmdline/apt-get.cc:2368
+#: cmdline/apt-get.cc:2421
 msgid ""
 "Usage: apt-get [options] command\n"
 "       apt-get [options] install|remove pkg1 [pkg2 ...]\n"
@@ -1270,8 +1309,8 @@ msgstr ""
 msgid "File %s/%s overwrites the one in the package %s"
 msgstr ""
 
-#: apt-inst/extract.cc:467 apt-pkg/contrib/configuration.cc:709
-#: apt-pkg/contrib/cdromutl.cc:153 apt-pkg/acquire.cc:416 apt-pkg/clean.cc:38
+#: apt-inst/extract.cc:467 apt-pkg/contrib/configuration.cc:750
+#: apt-pkg/contrib/cdromutl.cc:153 apt-pkg/acquire.cc:417 apt-pkg/clean.cc:38
 #, c-format
 msgid "Unable to read %s"
 msgstr ""
@@ -1301,9 +1340,9 @@ msgid "The info and temp directories need to be on the same filesystem"
 msgstr ""
 
 #. Build the status cache
-#: apt-inst/deb/dpkgdb.cc:139 apt-pkg/pkgcachegen.cc:643
-#: apt-pkg/pkgcachegen.cc:712 apt-pkg/pkgcachegen.cc:717
-#: apt-pkg/pkgcachegen.cc:840
+#: apt-inst/deb/dpkgdb.cc:139 apt-pkg/pkgcachegen.cc:645
+#: apt-pkg/pkgcachegen.cc:714 apt-pkg/pkgcachegen.cc:719
+#: apt-pkg/pkgcachegen.cc:842
 msgid "Reading package lists"
 msgstr ""
 
@@ -1431,11 +1470,12 @@ msgstr ""
 msgid "File not found"
 msgstr ""
 
-#: methods/copy.cc:42 methods/gzip.cc:133 methods/gzip.cc:142
+#: methods/copy.cc:42 methods/gpgv.cc:265 methods/gzip.cc:133
+#: methods/gzip.cc:142
 msgid "Failed to stat"
 msgstr ""
 
-#: methods/copy.cc:79 methods/gzip.cc:139
+#: methods/copy.cc:79 methods/gpgv.cc:262 methods/gzip.cc:139
 msgid "Failed to set modification time"
 msgstr ""
 
@@ -1495,7 +1535,7 @@ msgstr ""
 msgid "Server closed the connection"
 msgstr ""
 
-#: methods/ftp.cc:338 methods/rsh.cc:190 apt-pkg/contrib/fileutl.cc:453
+#: methods/ftp.cc:338 apt-pkg/contrib/fileutl.cc:471 methods/rsh.cc:190
 msgid "Read error"
 msgstr ""
 
@@ -1507,7 +1547,7 @@ msgstr ""
 msgid "Protocol corruption"
 msgstr ""
 
-#: methods/ftp.cc:446 methods/rsh.cc:232 apt-pkg/contrib/fileutl.cc:492
+#: methods/ftp.cc:446 apt-pkg/contrib/fileutl.cc:510 methods/rsh.cc:232
 msgid "Write error"
 msgstr ""
 
@@ -1608,43 +1648,79 @@ msgstr ""
 msgid "Cannot initiate the connection to %s:%s (%s)."
 msgstr ""
 
-#: methods/connect.cc:92
+#: methods/connect.cc:93
 #, c-format
 msgid "Could not connect to %s:%s (%s), connection timed out"
 msgstr ""
 
-#: methods/connect.cc:104
+#: methods/connect.cc:106
 #, c-format
 msgid "Could not connect to %s:%s (%s)."
 msgstr ""
 
 #. We say this mainly because the pause here is for the
 #. ssh connection that is still going
-#: methods/connect.cc:132 methods/rsh.cc:425
+#: methods/connect.cc:134 methods/rsh.cc:425
 #, c-format
 msgid "Connecting to %s"
 msgstr ""
 
-#: methods/connect.cc:163
+#: methods/connect.cc:165
 #, c-format
 msgid "Could not resolve '%s'"
 msgstr ""
 
-#: methods/connect.cc:167
+#: methods/connect.cc:169
 #, c-format
 msgid "Temporary failure resolving '%s'"
 msgstr ""
 
-#: methods/connect.cc:169
+#: methods/connect.cc:171
 #, c-format
 msgid "Something wicked happened resolving '%s:%s' (%i)"
 msgstr ""
 
-#: methods/connect.cc:216
+#: methods/connect.cc:218
 #, c-format
 msgid "Unable to connect to %s %s:"
 msgstr ""
 
+#: methods/gpgv.cc:92
+msgid "E: Argument list from Acquire::gpgv::Options too long. Exiting."
+msgstr ""
+
+#: methods/gpgv.cc:191
+msgid ""
+"Internal error: Good signature, but could not determine key fingerprint?!"
+msgstr ""
+
+#: methods/gpgv.cc:196
+msgid "At least one invalid signature was encountered."
+msgstr ""
+
+#. FIXME String concatenation considered harmful.
+#: methods/gpgv.cc:201
+msgid "Could not execute "
+msgstr ""
+
+#: methods/gpgv.cc:202
+msgid " to verify signature (is gnupg installed?)"
+msgstr ""
+
+#: methods/gpgv.cc:206
+msgid "Unknown error executing gpgv"
+msgstr ""
+
+#: methods/gpgv.cc:237
+msgid "The following signatures were invalid:\n"
+msgstr ""
+
+#: methods/gpgv.cc:244
+msgid ""
+"The following signatures couldn't be verified because the public key is not "
+"available:\n"
+msgstr ""
+
 #: methods/gzip.cc:57
 #, c-format
 msgid "Couldn't open pipe for %s"
@@ -1728,10 +1804,6 @@ msgstr ""
 msgid "Internal error"
 msgstr ""
 
-#: methods/rsh.cc:330
-msgid "Connection closed prematurely"
-msgstr ""
-
 #: apt-pkg/contrib/mmap.cc:82
 msgid "Can't mmap an empty file"
 msgstr ""
@@ -1746,57 +1818,57 @@ msgstr ""
 msgid "Selection %s not found"
 msgstr ""
 
-#: apt-pkg/contrib/configuration.cc:395
+#: apt-pkg/contrib/configuration.cc:436
 #, c-format
 msgid "Unrecognized type abbreviation: '%c'"
 msgstr ""
 
-#: apt-pkg/contrib/configuration.cc:453
+#: apt-pkg/contrib/configuration.cc:494
 #, c-format
 msgid "Opening configuration file %s"
 msgstr ""
 
-#: apt-pkg/contrib/configuration.cc:471
+#: apt-pkg/contrib/configuration.cc:512
 #, c-format
 msgid "Line %d too long (max %d)"
 msgstr ""
 
-#: apt-pkg/contrib/configuration.cc:567
+#: apt-pkg/contrib/configuration.cc:608
 #, c-format
 msgid "Syntax error %s:%u: Block starts with no name."
 msgstr ""
 
-#: apt-pkg/contrib/configuration.cc:586
+#: apt-pkg/contrib/configuration.cc:627
 #, c-format
 msgid "Syntax error %s:%u: Malformed tag"
 msgstr ""
 
-#: apt-pkg/contrib/configuration.cc:603
+#: apt-pkg/contrib/configuration.cc:644
 #, c-format
 msgid "Syntax error %s:%u: Extra junk after value"
 msgstr ""
 
-#: apt-pkg/contrib/configuration.cc:643
+#: apt-pkg/contrib/configuration.cc:684
 #, c-format
 msgid "Syntax error %s:%u: Directives can only be done at the top level"
 msgstr ""
 
-#: apt-pkg/contrib/configuration.cc:650
+#: apt-pkg/contrib/configuration.cc:691
 #, c-format
 msgid "Syntax error %s:%u: Too many nested includes"
 msgstr ""
 
-#: apt-pkg/contrib/configuration.cc:654 apt-pkg/contrib/configuration.cc:659
+#: apt-pkg/contrib/configuration.cc:695 apt-pkg/contrib/configuration.cc:700
 #, c-format
 msgid "Syntax error %s:%u: Included from here"
 msgstr ""
 
-#: apt-pkg/contrib/configuration.cc:663
+#: apt-pkg/contrib/configuration.cc:704
 #, c-format
 msgid "Syntax error %s:%u: Unsupported directive '%s'"
 msgstr ""
 
-#: apt-pkg/contrib/configuration.cc:697
+#: apt-pkg/contrib/configuration.cc:738
 #, c-format
 msgid "Syntax error %s:%u: Extra junk at end of file"
 msgstr ""
@@ -1862,7 +1934,7 @@ msgstr ""
 msgid "Unable to stat the mount point %s"
 msgstr ""
 
-#: apt-pkg/contrib/cdromutl.cc:149 apt-pkg/acquire.cc:422 apt-pkg/clean.cc:44
+#: apt-pkg/contrib/cdromutl.cc:149 apt-pkg/acquire.cc:423 apt-pkg/clean.cc:44
 #, c-format
 msgid "Unable to change to %s"
 msgstr ""
@@ -1871,70 +1943,70 @@ msgstr ""
 msgid "Failed to stat the cdrom"
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:80
+#: apt-pkg/contrib/fileutl.cc:82
 #, c-format
 msgid "Not using locking for read only lock file %s"
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:85
+#: apt-pkg/contrib/fileutl.cc:87
 #, c-format
 msgid "Could not open lock file %s"
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:103
+#: apt-pkg/contrib/fileutl.cc:105
 #, c-format
 msgid "Not using locking for nfs mounted lock file %s"
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:107
+#: apt-pkg/contrib/fileutl.cc:109
 #, c-format
 msgid "Could not get lock %s"
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:359
+#: apt-pkg/contrib/fileutl.cc:377
 #, c-format
 msgid "Waited for %s but it wasn't there"
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:369
+#: apt-pkg/contrib/fileutl.cc:387
 #, c-format
 msgid "Sub-process %s received a segmentation fault."
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:372
+#: apt-pkg/contrib/fileutl.cc:390
 #, c-format
 msgid "Sub-process %s returned an error code (%u)"
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:374
+#: apt-pkg/contrib/fileutl.cc:392
 #, c-format
 msgid "Sub-process %s exited unexpectedly"
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:418
+#: apt-pkg/contrib/fileutl.cc:436
 #, c-format
 msgid "Could not open file %s"
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:474
+#: apt-pkg/contrib/fileutl.cc:492
 #, c-format
 msgid "read, still have %lu to read but none left"
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:504
+#: apt-pkg/contrib/fileutl.cc:522
 #, c-format
 msgid "write, still have %lu to write but couldn't"
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:579
+#: apt-pkg/contrib/fileutl.cc:597
 msgid "Problem closing the file"
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:585
+#: apt-pkg/contrib/fileutl.cc:603
 msgid "Problem unlinking the file"
 msgstr ""
 
-#: apt-pkg/contrib/fileutl.cc:596
+#: apt-pkg/contrib/fileutl.cc:614
 msgid "Problem syncing the file"
 msgstr ""
 
@@ -2007,18 +2079,27 @@ msgstr ""
 msgid "extra"
 msgstr ""
 
-#: apt-pkg/depcache.cc:60 apt-pkg/depcache.cc:89
+#: apt-pkg/depcache.cc:89 apt-pkg/depcache.cc:118
 msgid "Building dependency tree"
 msgstr ""
 
-#: apt-pkg/depcache.cc:61
+#: apt-pkg/depcache.cc:90
 msgid "Candidate versions"
 msgstr ""
 
-#: apt-pkg/depcache.cc:90
+#: apt-pkg/depcache.cc:119
 msgid "Dependency generation"
 msgstr ""
 
+#: apt-pkg/depcache.cc:140 apt-pkg/depcache.cc:159 apt-pkg/depcache.cc:163
+msgid "Reading state information"
+msgstr ""
+
+#: apt-pkg/depcache.cc:179
+#, c-format
+msgid "Failed to write StateFile %s"
+msgstr ""
+
 #: apt-pkg/tagfile.cc:73
 #, c-format
 msgid "Unable to parse package file %s (1)"
@@ -2092,32 +2173,37 @@ msgstr ""
 msgid "Index file type '%s' is not supported"
 msgstr ""
 
-#: apt-pkg/algorithms.cc:241
+#: apt-pkg/algorithms.cc:245
 #, c-format
 msgid ""
 "The package %s needs to be reinstalled, but I can't find an archive for it."
 msgstr ""
 
-#: apt-pkg/algorithms.cc:1059
+#: apt-pkg/algorithms.cc:1075
 msgid ""
 "Error, pkgProblemResolver::Resolve generated breaks, this may be caused by "
 "held packages."
 msgstr ""
 
-#: apt-pkg/algorithms.cc:1061
+#: apt-pkg/algorithms.cc:1077
 msgid "Unable to correct problems, you have held broken packages."
 msgstr ""
 
-#: apt-pkg/acquire.cc:61
+#: apt-pkg/acquire.cc:62
 #, c-format
 msgid "Lists directory %spartial is missing."
 msgstr ""
 
-#: apt-pkg/acquire.cc:65
+#: apt-pkg/acquire.cc:66
 #, c-format
 msgid "Archive directory %spartial is missing."
 msgstr ""
 
+#: apt-pkg/acquire.cc:817
+#, c-format
+msgid "Downloading file %li of %li (%s remaining)"
+msgstr ""
+
 #: apt-pkg/acquire-worker.cc:112
 #, c-format
 msgid "The method driver %s could not be found."
@@ -2167,82 +2253,82 @@ msgstr ""
 msgid "No priority (or zero) specified for pin"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:74
+#: apt-pkg/pkgcachegen.cc:76
 msgid "Cache has an incompatible versioning system"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:117
+#: apt-pkg/pkgcachegen.cc:119
 #, c-format
 msgid "Error occurred while processing %s (NewPackage)"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:129
+#: apt-pkg/pkgcachegen.cc:131
 #, c-format
 msgid "Error occurred while processing %s (UsePackage1)"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:150
+#: apt-pkg/pkgcachegen.cc:152
 #, c-format
 msgid "Error occurred while processing %s (UsePackage2)"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:154
+#: apt-pkg/pkgcachegen.cc:156
 #, c-format
 msgid "Error occurred while processing %s (NewFileVer1)"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:184
+#: apt-pkg/pkgcachegen.cc:186
 #, c-format
 msgid "Error occurred while processing %s (NewVersion1)"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:188
+#: apt-pkg/pkgcachegen.cc:190
 #, c-format
 msgid "Error occurred while processing %s (UsePackage3)"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:192
+#: apt-pkg/pkgcachegen.cc:194
 #, c-format
 msgid "Error occurred while processing %s (NewVersion2)"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:207
+#: apt-pkg/pkgcachegen.cc:209
 msgid "Wow, you exceeded the number of package names this APT is capable of."
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:210
+#: apt-pkg/pkgcachegen.cc:212
 msgid "Wow, you exceeded the number of versions this APT is capable of."
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:213
+#: apt-pkg/pkgcachegen.cc:215
 msgid "Wow, you exceeded the number of dependencies this APT is capable of."
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:241
+#: apt-pkg/pkgcachegen.cc:243
 #, c-format
 msgid "Error occurred while processing %s (FindPkg)"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:254
+#: apt-pkg/pkgcachegen.cc:256
 #, c-format
 msgid "Error occurred while processing %s (CollectFileProvides)"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:260
+#: apt-pkg/pkgcachegen.cc:262
 #, c-format
 msgid "Package %s %s was not found while processing file dependencies"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:574
+#: apt-pkg/pkgcachegen.cc:576
 #, c-format
 msgid "Couldn't stat source package list %s"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:658
+#: apt-pkg/pkgcachegen.cc:660
 msgid "Collecting File Provides"
 msgstr ""
 
-#: apt-pkg/pkgcachegen.cc:785 apt-pkg/pkgcachegen.cc:792
+#: apt-pkg/pkgcachegen.cc:787 apt-pkg/pkgcachegen.cc:794
 msgid "IO Error saving source cache"
 msgstr ""
 
@@ -2251,31 +2337,31 @@ msgstr ""
 msgid "rename failed, %s (%s -> %s)."
 msgstr ""
 
-#: apt-pkg/acquire-item.cc:235 apt-pkg/acquire-item.cc:900
+#: apt-pkg/acquire-item.cc:235 apt-pkg/acquire-item.cc:906
 msgid "MD5Sum mismatch"
 msgstr ""
 
-#: apt-pkg/acquire-item.cc:714
+#: apt-pkg/acquire-item.cc:720
 #, c-format
 msgid ""
 "I wasn't able to locate a file for the %s package. This might mean you need "
 "to manually fix this package. (due to missing arch)"
 msgstr ""
 
-#: apt-pkg/acquire-item.cc:767
+#: apt-pkg/acquire-item.cc:773
 #, c-format
 msgid ""
 "I wasn't able to locate file for the %s package. This might mean you need to "
 "manually fix this package."
 msgstr ""
 
-#: apt-pkg/acquire-item.cc:803
+#: apt-pkg/acquire-item.cc:809
 #, c-format
 msgid ""
 "The package index files are corrupted. No Filename: field for package %s."
 msgstr ""
 
-#: apt-pkg/acquire-item.cc:890
+#: apt-pkg/acquire-item.cc:896
 msgid "Size mismatch"
 msgstr ""
 
@@ -2373,3 +2459,57 @@ msgstr ""
 #, c-format
 msgid "Wrote %i records with %i missing files and %i mismatched files\n"
 msgstr ""
+
+#: apt-pkg/deb/dpkgpm.cc:358
+#, c-format
+msgid "Preparing %s"
+msgstr ""
+
+#: apt-pkg/deb/dpkgpm.cc:359
+#, c-format
+msgid "Unpacking %s"
+msgstr ""
+
+#: apt-pkg/deb/dpkgpm.cc:364
+#, c-format
+msgid "Preparing to configure %s"
+msgstr ""
+
+#: apt-pkg/deb/dpkgpm.cc:365
+#, c-format
+msgid "Configuring %s"
+msgstr ""
+
+#: apt-pkg/deb/dpkgpm.cc:366
+#, c-format
+msgid "Installed %s"
+msgstr ""
+
+#: apt-pkg/deb/dpkgpm.cc:371
+#, c-format
+msgid "Preparing for removal of %s"
+msgstr ""
+
+#: apt-pkg/deb/dpkgpm.cc:372
+#, c-format
+msgid "Removing %s"
+msgstr ""
+
+#: apt-pkg/deb/dpkgpm.cc:373
+#, c-format
+msgid "Removed %s"
+msgstr ""
+
+#: apt-pkg/deb/dpkgpm.cc:378
+#, c-format
+msgid "Preparing for remove with config %s"
+msgstr ""
+
+#: apt-pkg/deb/dpkgpm.cc:379
+#, c-format
+msgid "Removed with config %s"
+msgstr ""
+
+#: methods/rsh.cc:330
+msgid "Connection closed prematurely"
+msgstr ""