]> git.saurik.com Git - apt.git/commitdiff
* merged the apt--DoListUpdate branch, this provides a common interface
authorMichael Vogt <michael.vogt@ubuntu.com>
Fri, 4 Jan 2008 20:33:09 +0000 (21:33 +0100)
committerMichael Vogt <michael.vogt@ubuntu.com>
Fri, 4 Jan 2008 20:33:09 +0000 (21:33 +0100)
  for apt-get update like operations for the frontends and also provides
  hooks to run stuff in APT::Update::{Pre,Post}-Invoke

1  2 
apt-pkg/cachefile.cc
apt-pkg/cachefile.h
apt-pkg/contrib/fileutl.cc
apt-pkg/contrib/fileutl.h
apt-pkg/deb/dpkgpm.cc
apt-pkg/deb/dpkgpm.h
cmdline/apt-get.cc
debian/changelog
doc/examples/configure-index

diff --combined apt-pkg/cachefile.cc
index cccad2bf3ae95ec29f7bd8035c981cdf80721319,8b8e6dc98426a9f4d878ef1d472e5d1e63174b1b..4c2c568930a0c51540b4bce52b635498e54d9071
     ##################################################################### */
                                                                        /*}}}*/
  // Include Files                                                      /*{{{*/
 -#ifdef __GNUG__
 -#pragma implementation "apt-pkg/cachefile.h"
 -#endif
 -
  #include <apt-pkg/cachefile.h>
  #include <apt-pkg/error.h>
  #include <apt-pkg/sourcelist.h>
@@@ -19,6 -23,8 +19,8 @@@
  #include <apt-pkg/configuration.h>
  #include <apt-pkg/policy.h>
  #include <apt-pkg/pkgsystem.h>
+ #include <apt-pkg/acquire-item.h>
+ #include <apt-pkg/fileutl.h>
      
  #include <apti18n.h>
                                                                        /*}}}*/
@@@ -107,6 -113,56 +109,73 @@@ bool pkgCacheFile::Open(OpProgress &Pro
  }
                                                                        /*}}}*/
  
 -/* */
+ // CacheFile::ListUpdate - update the cache files                     /*{{{*/
+ // ---------------------------------------------------------------------
 -   
++/* This is a simple wrapper to update the cache. it will fetch stuff
++ * from the network (or any other sources defined in sources.list)
++ */
+ bool pkgCacheFile::ListUpdate(pkgAcquireStatus &Stat, pkgSourceList &List)
+ {
+    pkgAcquire Fetcher(&Stat);
+    // Populate it with the source selection
+    if (List.GetIndexes(&Fetcher) == false)
+        return false;
 -
++
+    // Run scripts
+    RunScripts("APT::Update::Pre-Invoke");
 -   for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
++   
+    // Run it
+    if (Fetcher.Run() == pkgAcquire::Failed)
+       return false;
+    bool Failed = false;
 -      
 -      _error->Warning(_("Failed to fetch %s  %s\n"),
 -                    (*I)->DescURI().c_str(),
 -                    (*I)->ErrorText.c_str());
++   bool TransientNetworkFailure = false;
++   for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); 
++      I != Fetcher.ItemsEnd(); I++)
+    {
+       if ((*I)->Status == pkgAcquire::Item::StatDone)
+        continue;
+       (*I)->Finished();
 -
 -   // Clean out any old list files (if it was not a failure)
++
++      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;
+    }
 -   if (!Failed && (_config->FindB("APT::Get::List-Cleanup",true) == true ||
 -                 _config->FindB("APT::List-Cleanup",true) == true))
++   
++   // Clean out any old list files
+    // Keep "APT::Get::List-Cleanup" name for compatibility, but
+    // this is really a global option for the APT library now
 -   // Run the scripts
 -   RunScripts("APT::Update::Post-Invoke");
++   if (!TransientNetworkFailure && !Failed &&
++       (_config->FindB("APT::Get::List-Cleanup",true) == true ||
++      _config->FindB("APT::List-Cleanup",true) == true))
+    {
+       if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
+         Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
++       // something went wrong with the clean
+        return false;
+    }
++   
++   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 (Failed == false);
++   // Run the scripts if all was fine
++   RunScripts("APT::Update::Post-Invoke");
++   return true;
+ }
+                                                                       /*}}}*/
  // CacheFile::Close - close the cache files                           /*{{{*/
  // ---------------------------------------------------------------------
  /* */
diff --combined apt-pkg/cachefile.h
index d23841e5e8051319fc5b0140154217e4fad27b00,366e3576f05bc0cbf1422af0d442e44cd9d7deaf..02c6188a7d0586dc27e125645315f2ad4aadcee9
  #ifndef PKGLIB_CACHEFILE_H
  #define PKGLIB_CACHEFILE_H
  
 -#ifdef __GNUG__
 -#pragma interface "apt-pkg/cachefile.h"
 -#endif 
  
  #include <apt-pkg/depcache.h>
+ #include <apt-pkg/acquire.h>
+ #include <apt-pkg/sourcelist.h>
  
  class pkgPolicy;
  class pkgCacheFile
@@@ -45,6 -50,7 +47,7 @@@
  
     bool BuildCaches(OpProgress &Progress,bool WithLock = true);
     bool Open(OpProgress &Progress,bool WithLock = true);
+    bool ListUpdate(pkgAcquireStatus &progress, pkgSourceList &List);
     void Close();
     
     pkgCacheFile();
index 9e13b4f60d05ebd916b15d958e095b2f941325cc,77287952a8afb37707e144f6cd353fbda643c5f9..2b7e25080ef52578fbf672331a0e549ec5476073
@@@ -8,12 -8,18 +8,15 @@@
     CopyFile - Buffered copy of a single file
     GetLock - dpkg compatible lock file manipulation (fcntl)
     
-    This source is placed in the Public Domain, do with it what you will
+    Most of this source is placed in the Public Domain, do with it what 
+    you will
     It was originally written by Jason Gunthorpe <jgg@debian.org>.
     
+    The exception is RunScripts() it is under the GPLv2
     ##################################################################### */
                                                                        /*}}}*/
  // Include Files                                                      /*{{{*/
 -#ifdef __GNUG__
 -#pragma implementation "apt-pkg/fileutl.h"
 -#endif 
  #include <apt-pkg/fileutl.h>
  #include <apt-pkg/error.h>
  #include <apt-pkg/sptr.h>
@@@ -21,9 -27,6 +24,9 @@@
  
  #include <apti18n.h>
  
 +#include <cstdlib>
 +#include <cstring>
 +
  #include <iostream>
  #include <unistd.h>
  #include <fcntl.h>
  
  using namespace std;
  
+ // RunScripts - Run a set of scripts from a configuration subtree     /*{{{*/
+ // ---------------------------------------------------------------------
+ /* */
+ bool RunScripts(const char *Cnf)
+ {
+    Configuration::Item const *Opts = _config->Tree(Cnf);
+    if (Opts == 0 || Opts->Child == 0)
+       return true;
+    Opts = Opts->Child;
+    // Fork for running the system calls
+    pid_t Child = ExecFork();
+    
+    // This is the child
+    if (Child == 0)
+    {
+       if (chdir("/tmp/") != 0)
+        _exit(100);
+        
+       unsigned int Count = 1;
+       for (; Opts != 0; Opts = Opts->Next, Count++)
+       {
+        if (Opts->Value.empty() == true)
+           continue;
+        
+        if (system(Opts->Value.c_str()) != 0)
+           _exit(100+Count);
+       }
+       _exit(0);
+    }      
+    // Wait for the child
+    int Status = 0;
+    while (waitpid(Child,&Status,0) != Child)
+    {
+       if (errno == EINTR)
+        continue;
+       return _error->Errno("waitpid","Couldn't wait for subprocess");
+    }
+    // Restore sig int/quit
+    signal(SIGQUIT,SIG_DFL);
+    signal(SIGINT,SIG_DFL);   
+    // Check for an error code.
+    if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
+    {
+       unsigned int Count = WEXITSTATUS(Status);
+       if (Count > 100)
+       {
+        Count -= 100;
+        for (; Opts != 0 && Count != 1; Opts = Opts->Next, Count--);
+        _error->Error("Problem executing scripts %s '%s'",Cnf,Opts->Value.c_str());
+       }
+       
+       return _error->Error("Sub-process returned an error code");
+    }
+    
+    return true;
+ }
+                                                                       /*}}}*/
  // CopyFile - Buffered copy of a file                                 /*{{{*/
  // ---------------------------------------------------------------------
  /* The caller is expected to set things so that failure causes erasure */
index 48bd95537b182e4f2e97fc2dfe9dac7a96d978b6,363dd041d61070f7a814f23e5b88f2a2db441d65..73b5ea3be1a3ed410ba658810cf56e9c940ffa5f
@@@ -21,6 -21,9 +21,6 @@@
  #ifndef PKGLIB_FILEUTL_H
  #define PKGLIB_FILEUTL_H
  
 -#ifdef __GNUG__
 -#pragma interface "apt-pkg/fileutl.h"
 -#endif 
  
  #include <string>
  
@@@ -77,6 -80,7 +77,7 @@@ class FileF
     virtual ~FileFd();
  };
  
+ bool RunScripts(const char *Cnf);
  bool CopyFile(FileFd &From,FileFd &To);
  int GetLock(string File,bool Errors = true);
  bool FileExists(string File);
diff --combined apt-pkg/deb/dpkgpm.cc
index 11bf827d7082e7255eae313f14cf6dc90584a4fe,fe13614c51f71ccf318ede977d5d897e92fba22e..34e166447684276082ddadec7168a7bdbb27927e
@@@ -8,17 -8,19 +8,18 @@@
     ##################################################################### */
                                                                        /*}}}*/
  // Includes                                                           /*{{{*/
 -#ifdef __GNUG__
 -#pragma implementation "apt-pkg/dpkgpm.h"
 -#endif
  #include <apt-pkg/dpkgpm.h>
  #include <apt-pkg/error.h>
  #include <apt-pkg/configuration.h>
  #include <apt-pkg/depcache.h>
  #include <apt-pkg/strutl.h>
 +#include <apti18n.h>
+ #include <apt-pkg/fileutl.h>
  
  #include <unistd.h>
  #include <stdlib.h>
  #include <fcntl.h>
 +#include <sys/select.h>
  #include <sys/types.h>
  #include <sys/wait.h>
  #include <signal.h>
  #include <sstream>
  #include <map>
  
 +#include <termios.h>
 +#include <unistd.h>
 +#include <sys/ioctl.h>
 +#include <pty.h>
 +
  #include <config.h>
  #include <apti18n.h>
                                                                        /*}}}*/
  
  using namespace std;
  
 +
 +
  // DPkgPM::pkgDPkgPM - Constructor                                    /*{{{*/
  // ---------------------------------------------------------------------
  /* */
 -pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) : pkgPackageManager(Cache)
 +pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) 
 +   : pkgPackageManager(Cache), dpkgbuf_pos(0),
 +     term_out(NULL), PackagesDone(0), PackagesTotal(0)
  {
  }
                                                                        /*}}}*/
@@@ -95,68 -88,15 +96,6 @@@ bool pkgDPkgPM::Remove(PkgIterator Pkg,
     return true;
  }
                                                                        /*}}}*/
--// DPkgPM::RunScripts - Run a set of scripts                          /*{{{*/
--// ---------------------------------------------------------------------
--/* This looks for a list of script sto run from the configuration file,
--   each one is run with system from a forked child. */
--bool pkgDPkgPM::RunScripts(const char *Cnf)
--{
-    Configuration::Item const *Opts = _config->Tree(Cnf);
-    if (Opts == 0 || Opts->Child == 0)
-       return true;
-    Opts = Opts->Child;
-    // Fork for running the system calls
-    pid_t Child = ExecFork();
-    
-    // This is the child
-    if (Child == 0)
-    {
-       if (chdir("/tmp/") != 0)
-        _exit(100);
-        
-       unsigned int Count = 1;
-       for (; Opts != 0; Opts = Opts->Next, Count++)
-       {
-        if (Opts->Value.empty() == true)
-           continue;
-        
-        if (system(Opts->Value.c_str()) != 0)
-           _exit(100+Count);
-       }
-       _exit(0);
-    }      
-    // Wait for the child
-    int Status = 0;
-    while (waitpid(Child,&Status,0) != Child)
-    {
-       if (errno == EINTR)
-        continue;
-       return _error->Errno("waitpid","Couldn't wait for subprocess");
-    }
-    // Restore sig int/quit
-    signal(SIGQUIT,SIG_DFL);
-    signal(SIGINT,SIG_DFL);   
-    // Check for an error code.
-    if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
-    {
-       unsigned int Count = WEXITSTATUS(Status);
-       if (Count > 100)
-       {
-        Count -= 100;
-        for (; Opts != 0 && Count != 1; Opts = Opts->Next, Count--);
-        _error->Error("Problem executing scripts %s '%s'",Cnf,Opts->Value.c_str());
-       }
-       
-       return _error->Error("Sub-process returned an error code");
-    }
-    
-    return true;
 -   RunScripts(Cnf);
--}
--                                                                        /*}}}*/
  // DPkgPM::SendV2Pkgs - Send version 2 package info                   /*{{{*/
  // ---------------------------------------------------------------------
  /* This is part of the helper script communication interface, it sends
@@@ -334,240 -274,7 +273,240 @@@ bool pkgDPkgPM::RunScriptsWithPkgs(cons
  
     return true;
  }
 +
                                                                        /*}}}*/
 +// DPkgPM::DoStdin - Read stdin and pass to slave pty                 /*{{{*/
 +// ---------------------------------------------------------------------
 +/*
 +*/
 +void pkgDPkgPM::DoStdin(int master)
 +{
 +   unsigned char input_buf[256] = {0,}; 
 +   ssize_t len = read(0, input_buf, sizeof(input_buf));
 +   if (len)
 +      write(master, input_buf, len);
 +   else
 +      stdin_is_dev_null = true;
 +}
 +                                                                      /*}}}*/
 +// DPkgPM::DoTerminalPty - Read the terminal pty and write log                /*{{{*/
 +// ---------------------------------------------------------------------
 +/*
 + * read the terminal pty and write log
 + */
 +void pkgDPkgPM::DoTerminalPty(int master)
 +{
 +   unsigned char term_buf[1024] = {0,0, };
 +
 +   ssize_t len=read(master, term_buf, sizeof(term_buf));
 +   if(len == -1 && errno == EIO)
 +   {
 +      // this happens when the child is about to exit, we
 +      // give it time to actually exit, otherwise we run
 +      // into a race
 +      usleep(500000);
 +      return;
 +   }  
 +   if(len <= 0) 
 +      return;
 +   write(1, term_buf, len);
 +   if(term_out)
 +      fwrite(term_buf, len, sizeof(char), term_out);
 +}
 +                                                                      /*}}}*/
 +// DPkgPM::ProcessDpkgStatusBuf                                               /*{{{*/
 +// ---------------------------------------------------------------------
 +/*
 + */
 +void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
 +{
 +   // the status we output
 +   ostringstream status;
 +
 +   if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
 +      std::clog << "got from dpkg '" << line << "'" << std::endl;
 +
 +
 +   /* dpkg sends strings like this:
 +      'status:   <pkg>:  <pkg  qstate>'
 +      errors look like this:
 +      'status: /var/cache/apt/archives/krecipes_0.8.1-0ubuntu1_i386.deb : error : trying to overwrite `/usr/share/doc/kde/HTML/en/krecipes/krectip.png', which is also in package krecipes-data 
 +      and conffile-prompt like this
 +      'status: conffile-prompt: conffile : 'current-conffile' 'new-conffile' useredited distedited
 +          
 +   */
 +   char* list[5];
 +   //        dpkg sends multiline error messages sometimes (see
 +   //        #374195 for a example. we should support this by
 +   //        either patching dpkg to not send multiline over the
 +   //        statusfd or by rewriting the code here to deal with
 +   //        it. for now we just ignore it and not crash
 +   TokSplitString(':', line, list, sizeof(list)/sizeof(list[0]));
 +   if( list[0] == NULL || list[1] == NULL || list[2] == NULL) 
 +   {
 +      if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
 +       std::clog << "ignoring line: not enough ':'" << std::endl;
 +      return;
 +   }
 +   char *pkg = list[1];
 +   char *action = _strstrip(list[2]);
 +
 +   if(strncmp(action,"error",strlen("error")) == 0)
 +   {
 +      status << "pmerror:" << list[1]
 +           << ":"  << (PackagesDone/float(PackagesTotal)*100.0) 
 +           << ":" << list[3]
 +           << endl;
 +      if(OutStatusFd > 0)
 +       write(OutStatusFd, status.str().c_str(), status.str().size());
 +      if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
 +       std::clog << "send: '" << status.str() << "'" << endl;
 +      return;
 +   }
 +   if(strncmp(action,"conffile",strlen("conffile")) == 0)
 +   {
 +      status << "pmconffile:" << list[1]
 +           << ":"  << (PackagesDone/float(PackagesTotal)*100.0) 
 +           << ":" << list[3]
 +           << endl;
 +      if(OutStatusFd > 0)
 +       write(OutStatusFd, status.str().c_str(), status.str().size());
 +      if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
 +       std::clog << "send: '" << status.str() << "'" << endl;
 +      return;
 +   }
 +
 +   vector<struct DpkgState> &states = PackageOps[pkg];
 +   const char *next_action = NULL;
 +   if(PackageOpsDone[pkg] < states.size())
 +      next_action = states[PackageOpsDone[pkg]].state;
 +   // check if the package moved to the next dpkg state
 +   if(next_action && (strcmp(action, next_action) == 0)) 
 +   {
 +      // only read the translation if there is actually a next
 +      // action
 +      const char *translation = _(states[PackageOpsDone[pkg]].str);
 +      char s[200];
 +      snprintf(s, sizeof(s), translation, pkg);
 +
 +      // we moved from one dpkg state to a new one, report that
 +      PackageOpsDone[pkg]++;
 +      PackagesDone++;
 +      // build the status str
 +      status << "pmstatus:" << pkg 
 +           << ":"  << (PackagesDone/float(PackagesTotal)*100.0) 
 +           << ":" << s
 +           << endl;
 +      if(OutStatusFd > 0)
 +       write(OutStatusFd, status.str().c_str(), status.str().size());
 +      if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
 +       std::clog << "send: '" << status.str() << "'" << endl;
 +   }
 +   if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) 
 +      std::clog << "(parsed from dpkg) pkg: " << pkg 
 +              << " action: " << action << endl;
 +}
 +
 +// DPkgPM::DoDpkgStatusFd                                             /*{{{*/
 +// ---------------------------------------------------------------------
 +/*
 + */
 +void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd)
 +{
 +   char *p, *q;
 +   int len;
 +
 +   len=read(statusfd, &dpkgbuf[dpkgbuf_pos], sizeof(dpkgbuf)-dpkgbuf_pos);
 +   dpkgbuf_pos += len;
 +   if(len <= 0)
 +      return;
 +
 +   // process line by line if we have a buffer
 +   p = q = dpkgbuf;
 +   while((q=(char*)memchr(p, '\n', dpkgbuf+dpkgbuf_pos-p)) != NULL)
 +   {
 +      *q = 0;
 +      ProcessDpkgStatusLine(OutStatusFd, p);
 +      p=q+1; // continue with next line
 +   }
 +
 +   // now move the unprocessed bits (after the final \n that is now a 0x0) 
 +   // to the start and update dpkgbuf_pos
 +   p = (char*)memrchr(dpkgbuf, 0, dpkgbuf_pos);
 +   if(p == NULL)
 +      return;
 +
 +   // we are interessted in the first char *after* 0x0
 +   p++;
 +
 +   // move the unprocessed tail to the start and update pos
 +   memmove(dpkgbuf, p, p-dpkgbuf);
 +   dpkgbuf_pos = dpkgbuf+dpkgbuf_pos-p;
 +}
 +                                                                      /*}}}*/
 +
 +bool pkgDPkgPM::OpenLog()
 +{
 +   string logdir = _config->FindDir("Dir::Log");
 +   if(not FileExists(logdir))
 +      return _error->Error(_("Directory '%s' missing"), logdir.c_str());
 +   string logfile_name = flCombine(logdir,
 +                                 _config->Find("Dir::Log::Terminal"));
 +   if (!logfile_name.empty())
 +   {
 +      term_out = fopen(logfile_name.c_str(),"a");
 +      chmod(logfile_name.c_str(), 0600);
 +      // output current time
 +      char outstr[200];
 +      time_t t = time(NULL);
 +      struct tm *tmp = localtime(&t);
 +      strftime(outstr, sizeof(outstr), "%F  %T", tmp);
 +      fprintf(term_out, "\nLog started: ");
 +      fprintf(term_out, outstr);
 +      fprintf(term_out, "\n");
 +   }
 +   return true;
 +}
 +
 +bool pkgDPkgPM::CloseLog()
 +{
 +   if(term_out)
 +   {
 +      char outstr[200];
 +      time_t t = time(NULL);
 +      struct tm *tmp = localtime(&t);
 +      strftime(outstr, sizeof(outstr), "%F  %T", tmp);
 +      fprintf(term_out, "Log ended: ");
 +      fprintf(term_out, outstr);
 +      fprintf(term_out, "\n");
 +      fclose(term_out);
 +   }
 +   term_out = NULL;
 +   return true;
 +}
 +
 +/*{{{*/
 +// This implements a racy version of pselect for those architectures
 +// that don't have a working implementation.
 +// FIXME: Probably can be removed on Lenny+1
 +static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds,
 +   fd_set *exceptfds, const struct timespec *timeout,
 +   const sigset_t *sigmask)
 +{
 +   sigset_t origmask;
 +   struct timeval tv;
 +   int retval;
 +
 +   tv.tv_sec = timeout->tv_sec;
 +   tv.tv_usec = timeout->tv_nsec/1000;
 +
 +   sigprocmask(SIG_SETMASK, sigmask, &origmask);
 +   retval = select(nfds, readfds, writefds, exceptfds, &tv);
 +   sigprocmask(SIG_SETMASK, &origmask, 0);
 +   return retval;
 +}
 +/*}}}*/
 +
  // DPkgPM::Go - Run the sequence                                      /*{{{*/
  // ---------------------------------------------------------------------
  /* This globs the operations and calls dpkg 
@@@ -588,45 -295,49 +527,45 @@@ bool pkgDPkgPM::Go(int OutStatusFd
     if (RunScriptsWithPkgs("DPkg::Pre-Install-Pkgs") == false)
        return false;
     
 -   // prepare the progress reporting 
 -   int Done = 0;
 -   int Total = 0;
     // map the dpkg states to the operations that are performed
     // (this is sorted in the same way as Item::Ops)
 -   static const struct DpkgState DpkgStatesOpMap[][5] = {
 +   static const struct DpkgState DpkgStatesOpMap[][7] = {
        // Install operation
        { 
 -       {"half-installed", _("Preparing %s")}, 
 -       {"unpacked", _("Unpacking %s") }, 
 +       {"half-installed", N_("Preparing %s")}, 
 +       {"unpacked", N_("Unpacking %s") }, 
         {NULL, NULL}
        },
        // Configure operation
        { 
 -       {"unpacked",_("Preparing to configure %s") },
 -       {"half-configured", _("Configuring %s") },
 -       { "installed", _("Installed %s")},
 +       {"unpacked",N_("Preparing to configure %s") },
 +       {"half-configured", N_("Configuring %s") },
 +#if 0
 +       {"triggers-awaited", N_("Processing triggers for %s") },
 +       {"triggers-pending", N_("Processing triggers for %s") },
 +#endif
 +       { "installed", N_("Installed %s")},
         {NULL, NULL}
        },
        // Remove operation
        { 
 -       {"half-configured", _("Preparing for removal of %s")},
 -       {"half-installed", _("Removing %s")},
 -       {"config-files",  _("Removed %s")},
 +       {"half-configured", N_("Preparing for removal of %s")},
 +#if 0
 +       {"triggers-awaited", N_("Preparing for removal of %s")},
 +       {"triggers-pending", N_("Preparing for removal of %s")},
 +#endif
 +       {"half-installed", N_("Removing %s")},
 +       {"config-files",  N_("Removed %s")},
         {NULL, NULL}
        },
        // Purge operation
        { 
 -       {"config-files", _("Preparing to completely remove %s")},
 -       {"not-installed", _("Completely removed %s")},
 +       {"config-files", N_("Preparing to completely remove %s")},
 +       {"not-installed", N_("Completely removed %s")},
         {NULL, NULL}
        },
     };
  
 -   // the dpkg states that the pkg will run through, the string is 
 -   // the package, the vector contains the dpkg states that the package
 -   // will go through
 -   map<string,vector<struct DpkgState> > PackageOps;
 -   // the dpkg states that are already done; the string is the package
 -   // the int is the state that is already done (e.g. a package that is
 -   // going to be install is already in state "half-installed")
 -   map<string,int> PackageOpsDone;
 -
     // init the PackageOps map, go over the list of packages that
     // that will be [installed|configured|removed|purged] and add
     // them to the PackageOps map (the dpkg states it goes through)
        for(int i=0; (DpkgStatesOpMap[(*I).Op][i]).state != NULL;  i++) 
        {
         PackageOps[name].push_back(DpkgStatesOpMap[(*I).Op][i]);
 -       Total++;
 +       PackagesTotal++;
        }
     }   
  
 +   stdin_is_dev_null = false;
 +
 +   // create log
 +   OpenLog();
 +
     // this loop is runs once per operation
     for (vector<Item>::iterator I = List.begin(); I != List.end();)
     {
         case Item::Install:
         Args[n++] = "--unpack";
         Size += strlen(Args[n-1]);
 +       Args[n++] = "--auto-deconfigure";
 +       Size += strlen(Args[n-1]);
         break;
        }
        
         it doesn't die but we do! So we must also ignore it */
        sighandler_t old_SIGQUIT = signal(SIGQUIT,SIG_IGN);
        sighandler_t old_SIGINT = signal(SIGINT,SIG_IGN);
 -      
 +
 +      struct  termios tt;
 +      struct  winsize win;
 +      int     master;
 +      int     slave;
 +
 +      // FIXME: setup sensible signal handling (*ick*)
 +      tcgetattr(0, &tt);
 +      ioctl(0, TIOCGWINSZ, (char *)&win);
 +      if (openpty(&master, &slave, NULL, &tt, &win) < 0) 
 +      {
 +       const char *s = _("Can not write log, openpty() "
 +                         "failed (/dev/pts not mounted?)\n");
 +       fprintf(stderr, "%s",s);
 +       fprintf(term_out, "%s",s);
 +       master = slave = -1;
 +      }  else {
 +       struct termios rtt;
 +       rtt = tt;
 +       cfmakeraw(&rtt);
 +       rtt.c_lflag &= ~ECHO;
 +       tcsetattr(0, TCSAFLUSH, &rtt);
 +      }
 +
         // Fork dpkg
        pid_t Child;
        _config->Set("APT::Keep-Fds::",fd[1]);
        // This is the child
        if (Child == 0)
        {
 +       if(slave >= 0 && master >= 0) 
 +       {
 +          setsid();
 +          ioctl(slave, TIOCSCTTY, 0);
 +          close(master);
 +          dup2(slave, 0);
 +          dup2(slave, 1);
 +          dup2(slave, 2);
 +          close(slave);
 +       }
         close(fd[0]); // close the read end of the pipe
 -       
 +
         if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0)
            _exit(100);
         
            if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0)
               _exit(100);
         }
 -       
 +
 +
         /* No Job Control Stop Env is a magic dpkg var that prevents it
            from using sigstop */
 -       putenv("DPKG_NO_TSTP=yes");
 +       putenv((char *)"DPKG_NO_TSTP=yes");
         execvp(Args[0],(char **)Args);
         cerr << "Could not exec dpkg!" << endl;
         _exit(100);
  
        // we read from dpkg here
        int _dpkgin = fd[0];
 -      fcntl(_dpkgin, F_SETFL, O_NONBLOCK);
        close(fd[1]);                        // close the write end of the pipe
  
 -      // the read buffers for the communication with dpkg
 -      char line[1024] = {0,};
 -      char buf[2] = {0,0};
 -      
        // the result of the waitpid call
        int res;
 -
 +      if(slave > 0)
 +       close(slave);
 +
 +      // setups fds
 +      fd_set rfds;
 +      struct timespec tv;
 +      sigset_t sigmask;
 +      sigset_t original_sigmask;
 +      sigemptyset(&sigmask);
 +      sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask);
 +
 +      int select_ret;
        while ((res=waitpid(Child,&Status, WNOHANG)) != Child) {
         if(res < 0) {
            // FIXME: move this to a function or something, looks ugly here
            signal(SIGINT,old_SIGINT);
            return _error->Errno("waitpid","Couldn't wait for subprocess");
         }
 -       
 -       // read a single char, make sure that the read can't block 
 -       // (otherwise we may leave zombies)
 -         int len = read(_dpkgin, buf, 1);
  
 -       // nothing to read, wait a bit for more
 -       if(len <= 0)
 -       {
 -          usleep(1000);
 -          continue;
 -       }
 +       // wait for input or output here
 +       FD_ZERO(&rfds);
 +       if (!stdin_is_dev_null)
 +          FD_SET(0, &rfds); 
 +       FD_SET(_dpkgin, &rfds);
 +       if(master >= 0)
 +          FD_SET(master, &rfds);
 +       tv.tv_sec = 1;
 +       tv.tv_nsec = 0;
 +       select_ret = pselect(max(master, _dpkgin)+1, &rfds, NULL, NULL, 
 +                            &tv, &original_sigmask);
 +       if (select_ret < 0 && (errno == EINVAL || errno == ENOSYS))
 +          select_ret = racy_pselect(max(master, _dpkgin)+1, &rfds, NULL,
 +                                    NULL, &tv, &original_sigmask);
 +       if (select_ret == 0) 
 +          continue;
 +       else if (select_ret < 0 && errno == EINTR)
 +          continue;
 +       else if (select_ret < 0) 
 +       {
 +          perror("select() returned error");
 +          continue;
 +       } 
         
 -       // sanity check (should never happen)
 -       if(strlen(line) >= sizeof(line)-10)
 -       {
 -          _error->Error("got a overlong line from dpkg: '%s'",line);
 -          line[0]=0;
 -       }
 -       // append to line, check if we got a complete line
 -       strcat(line, buf);
 -       if(buf[0] != '\n')
 -          continue;
 -
 -       if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
 -          std::clog << "got from dpkg '" << line << "'" << std::endl;
 -
 -       // the status we output
 -       ostringstream status;
 -
 -       /* dpkg sends strings like this:
 -          'status:   <pkg>:  <pkg  qstate>'
 -          errors look like this:
 -          'status: /var/cache/apt/archives/krecipes_0.8.1-0ubuntu1_i386.deb : error : trying to overwrite `/usr/share/doc/kde/HTML/en/krecipes/krectip.png', which is also in package krecipes-data 
 -          and conffile-prompt like this
 -          'status: conffile-prompt: conffile : 'current-conffile' 'new-conffile' useredited distedited
 -          
 -       */
 -       char* list[5];
 -       TokSplitString(':', line, list, sizeof(list)/sizeof(list[0]));
 -       char *pkg = list[1];
 -       char *action = _strstrip(list[2]);
 -
 -       if(strncmp(action,"error",strlen("error")) == 0)
 -       {
 -          status << "pmerror:" << list[1]
 -                 << ":"  << (Done/float(Total)*100.0) 
 -                 << ":" << list[3]
 -                 << endl;
 -          if(OutStatusFd > 0)
 -             write(OutStatusFd, status.str().c_str(), status.str().size());
 -          line[0]=0;
 -          if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
 -             std::clog << "send: '" << status.str() << "'" << endl;
 -          continue;
 -       }
 -       if(strncmp(action,"conffile",strlen("conffile")) == 0)
 -       {
 -          status << "pmconffile:" << list[1]
 -                 << ":"  << (Done/float(Total)*100.0) 
 -                 << ":" << list[3]
 -                 << endl;
 -          if(OutStatusFd > 0)
 -             write(OutStatusFd, status.str().c_str(), status.str().size());
 -          line[0]=0;
 -          if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
 -             std::clog << "send: '" << status.str() << "'" << endl;
 -          continue;
 -       }
 -
 -       vector<struct DpkgState> &states = PackageOps[pkg];
 -       const char *next_action = NULL;
 -       if(PackageOpsDone[pkg] < states.size())
 -          next_action = states[PackageOpsDone[pkg]].state;
 -       // check if the package moved to the next dpkg state
 -       if(next_action && (strcmp(action, next_action) == 0)) 
 -       {
 -          // only read the translation if there is actually a next
 -          // action
 -          const char *translation = states[PackageOpsDone[pkg]].str;
 -          char s[200];
 -          snprintf(s, sizeof(s), translation, pkg);
 -
 -          // we moved from one dpkg state to a new one, report that
 -          PackageOpsDone[pkg]++;
 -          Done++;
 -          // build the status str
 -          status << "pmstatus:" << pkg 
 -                 << ":"  << (Done/float(Total)*100.0) 
 -                 << ":" << s
 -                 << endl;
 -          if(OutStatusFd > 0)
 -             write(OutStatusFd, status.str().c_str(), status.str().size());
 -          if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
 -             std::clog << "send: '" << status.str() << "'" << endl;
 -
 -       }
 -       if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) 
 -          std::clog << "(parsed from dpkg) pkg: " << pkg 
 -                    << " action: " << action << endl;
 -
 -       // reset the line buffer
 -       line[0]=0;
 +       if(master >= 0 && FD_ISSET(master, &rfds))
 +          DoTerminalPty(master);
 +       if(master >= 0 && FD_ISSET(0, &rfds))
 +          DoStdin(master);
 +       if(FD_ISSET(_dpkgin, &rfds))
 +          DoDpkgStatusFd(_dpkgin, OutStatusFd);
        }
        close(_dpkgin);
  
        // Restore sig int/quit
        signal(SIGQUIT,old_SIGQUIT);
        signal(SIGINT,old_SIGINT);
 +
 +      if(master >= 0) 
 +      {
 +       tcsetattr(0, TCSAFLUSH, &tt);
 +       close(master);
 +      }
         
        // Check for an error code.
        if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
        {
 -       RunScripts("DPkg::Post-Invoke");
 -       if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV)
 -          return _error->Error("Sub-process %s received a segmentation fault.",Args[0]);
 -
 -       if (WIFEXITED(Status) != 0)
 -          return _error->Error("Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status));
 +       // if it was set to "keep-dpkg-runing" then we won't return
 +       // here but keep the loop going and just report it as a error
 +       // for later
 +       bool stopOnError = _config->FindB("Dpkg::StopOnError",true);
         
 -       return _error->Error("Sub-process %s exited unexpectedly",Args[0]);
 +       if(stopOnError)
 +          RunScripts("DPkg::Post-Invoke");
 +
 +       if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) 
 +          _error->Error("Sub-process %s received a segmentation fault.",Args[0]);
 +       else if (WIFEXITED(Status) != 0)
 +          _error->Error("Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status));
 +       else 
 +          _error->Error("Sub-process %s exited unexpectedly",Args[0]);
 +
 +       if(stopOnError) 
 +       {
 +          CloseLog();
 +          return false;
 +       }
        }      
     }
 +   CloseLog();
  
     if (RunScripts("DPkg::Post-Invoke") == false)
        return false;
diff --combined apt-pkg/deb/dpkgpm.h
index 81a888f057a15729fc0e47c832fdd4c1b77eba73,2ff8a9ac71ffb4d5cec6d8adb9282963283810d3..ebc7e32bf9fc3c3ddf204b66708363fc152a308b
  #ifndef PKGLIB_DPKGPM_H
  #define PKGLIB_DPKGPM_H
  
 -#ifdef __GNUG__
 -#pragma interface "apt-pkg/dpkgpm.h"
 -#endif
 -
  #include <apt-pkg/packagemanager.h>
  #include <vector>
 +#include <map>
  #include <stdio.h>
  
  using std::vector;
 +using std::map;
 +
  
  class pkgDPkgPM : public pkgPackageManager
  {
 +   private:
 +
 +   bool stdin_is_dev_null;
 +
 +   // the buffer we use for the dpkg status-fd reading
 +   char dpkgbuf[1024];
 +   int dpkgbuf_pos;
 +   FILE *term_out;
 +   
     protected:
  
 -   // used for progress reporting
 +   // progress reporting
     struct DpkgState 
     {
        const char *state;     // the dpkg state (e.g. "unpack")
        const char *str;       // the human readable translation of the state
     };
 -   
 +
 +   // the dpkg states that the pkg will run through, the string is 
 +   // the package, the vector contains the dpkg states that the package
 +   // will go through
 +   map<string,vector<struct DpkgState> > PackageOps;
 +   // the dpkg states that are already done; the string is the package
 +   // the int is the state that is already done (e.g. a package that is
 +   // going to be install is already in state "half-installed")
 +   map<string,unsigned int> PackageOpsDone;
 +   // progress reporting
 +   unsigned int PackagesDone;
 +   unsigned int PackagesTotal;
 +  
     struct Item
     {
        enum Ops {Install, Configure, Remove, Purge} Op;
     vector<Item> List;
  
     // Helpers
--   bool RunScripts(const char *Cnf);
     bool RunScriptsWithPkgs(const char *Cnf);
     bool SendV2Pkgs(FILE *F);
 +
 +   // dpkg log
 +   bool OpenLog();
 +   bool CloseLog();
     
 +   // input processing
 +   void DoStdin(int master);
 +   void DoTerminalPty(int master);
 +   void DoDpkgStatusFd(int statusfd, int OutStatusFd);
 +   void ProcessDpkgStatusLine(int OutStatusFd, char *line);
 +
     // The Actuall installation implementation
     virtual bool Install(PkgIterator Pkg,string File);
     virtual bool Configure(PkgIterator Pkg);
diff --combined cmdline/apt-get.cc
index 53c657e8a748132508a53ea10ffb36a1aa39879d,ed99d431a6e7683bd55037324572af9d75777f0b..5f46dd605a95e7816eaac1a25a28c27503b20f23
@@@ -53,7 -53,6 +53,7 @@@
  #include <termios.h>
  #include <sys/ioctl.h>
  #include <sys/stat.h>
 +#include <sys/statfs.h>
  #include <sys/statvfs.h>
  #include <signal.h>
  #include <unistd.h>
  #include <errno.h>
  #include <regex.h>
  #include <sys/wait.h>
 +#include <sstream>
                                                                        /*}}}*/
  
 +#define RAMFS_MAGIC     0x858458f6
 +
  using namespace std;
  
  ostream c0out(0);
@@@ -632,8 -628,6 +632,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;
  
     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)
@@@ -838,16 -820,16 +838,16 @@@ bool InstallPackages(CacheFile &Cache,b
     if (DebBytes != FetchBytes)
        ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"),
               SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
 -   else
 +   else if (DebBytes != 0)
        ioprintf(c1out,_("Need to get %sB of archives.\n"),
               SizeToStr(DebBytes).c_str());
  
     // Size delta
     if (Cache->UsrSize() >= 0)
 -      ioprintf(c1out,_("After unpacking %sB of additional disk space will be used.\n"),
 +      ioprintf(c1out,_("After this operation, %sB of additional disk space will be used.\n"),
               SizeToStr(Cache->UsrSize()).c_str());
     else
 -      ioprintf(c1out,_("After unpacking %sB disk space will be freed.\n"),
 +      ioprintf(c1out,_("After this operation, %sB disk space will be freed.\n"),
               SizeToStr(-1*Cache->UsrSize()).c_str());
  
     if (_error->PendingError() == true)
         return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
                              OutputDir.c_str());
        if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
 -       return _error->Error(_("You don't have enough free space in %s."),
 -                            OutputDir.c_str());
 +      {
 +         struct statfs Stat;
 +         if (statfs(OutputDir.c_str(),&Stat) != 0 ||
 +                       unsigned(Stat.f_type) != RAMFS_MAGIC)
 +            return _error->Error(_("You don't have enough free space in %s."),
 +                OutputDir.c_str());
 +      }
     }
     
     // Fail safe check
        pkgAcquire::UriIterator I = Fetcher.UriBegin();
        for (; I != Fetcher.UriEnd(); I++)
         cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
 -             I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
 +             I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
        return true;
     }
  
         cerr << _("Unable to correct missing packages.") << endl;
         return _error->Error(_("Aborting install."));
        }
 -               
 +
        _system->UnLock();
        int status_fd = _config->FindI("APT::Status-Fd",-1);
        pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd);
@@@ -1168,11 -1145,9 +1168,11 @@@ bool TryToInstall(pkgCache::PkgIterato
     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;
  }
                                                                        /*}}}*/
@@@ -1351,14 -1326,15 +1351,15 @@@ bool DoUpdate(CommandLine &CmdL
         return _error->Error(_("Unable to lock the list directory"));
     }
     
-    // Create the download object
+    // Create the progress
     AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
-    pkgAcquire Fetcher(&Stat);
-    
+       
     // Just print out the uris an exit if the --print-uris flag was used
     if (_config->FindB("APT::Get::Print-URIs") == true)
     {
+       // get a fetcher
+       pkgAcquire Fetcher(&Stat);
        // Populate it with the source selection and get all Indexes 
        // (GetAll=true)
        if (List.GetIndexes(&Fetcher,true) == false)
        pkgAcquire::UriIterator I = Fetcher.UriBegin();
        for (; I != Fetcher.UriEnd(); I++)
         cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
 -             I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
 +             I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
        return true;
     }
  
-    // Populate it with the source selection
-    if (List.GetIndexes(&Fetcher) == false)
-        return false;
-    
-    // Run it
-    if (Fetcher.Run() == pkgAcquire::Failed)
-       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 (!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)
-        return false;
-    }
-    
-    // Prepare the cache.   
+    // do the work
     CacheFile Cache;
+    bool res = Cache.ListUpdate(Stat, List);
+      
+    // Rebuild the cache.   
     if (Cache.BuildCaches() == false)
        return false;
     
-    if (TransientNetworkFailure == true)
-       _error->Warning(_("Some index files failed to download, they have been ignored, or old ones used instead."));
-    else if (Failed == true)
 -   if (res == false)
--      return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
 -   
     return true;
  }
                                                                        /*}}}*/
 +// DoAutomaticRemove - Remove all automatic unused packages           /*{{{*/
 +// ---------------------------------------------------------------------
 +/* Remove unused automatic packages */
 +bool DoAutomaticRemove(CacheFile &Cache)
 +{
 +   bool Debug = _config->FindI("Debug::pkgAutoRemove",false);
 +   bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false);
 +   bool hideAutoRemove = _config->FindB("APT::Get::HideAutoRemove");
 +   pkgDepCache::ActionGroup group(*Cache);
 +
 +   if(Debug)
 +      std::cout << "DoAutomaticRemove()" << std::endl;
 +
 +   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
 +   for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg)
 +   {
 +      if (Cache[Pkg].Garbage)
 +      {
 +       if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
 +          if(Debug)
 +             std::cout << "We could delete %s" <<  Pkg.Name() << std::endl;
 +        
 +       // only show stuff in the list that is not yet marked for removal
 +       if(Cache[Pkg].Delete() == false) 
 +       {
 +          autoremovelist += string(Pkg.Name()) + " ";
 +          autoremoveversions += string(Cache[Pkg].CandVersion) + "\n";
 +       }
 +       if (doAutoRemove)
 +       {
 +          if(Pkg.CurrentVer() != 0 && 
 +             Pkg->CurrentState != pkgCache::State::ConfigFiles)
 +             Cache->MarkDelete(Pkg, _config->FindB("APT::Get::Purge", false));
 +          else
 +             Cache->MarkKeep(Pkg, false, false);
 +       }
 +      }
 +   }
 +   if (!hideAutoRemove) 
 +      ShowList(c1out, _("The following packages were automatically installed and are no longer required:"), autoremovelist, autoremoveversions);
 +   if (!doAutoRemove && !hideAutoRemove && autoremovelist.size() > 0)
 +      c1out << _("Use 'apt-get autoremove' to remove them.") << std::endl;
 +
 +   // Now see if we destroyed anything
 +   if (Cache->BrokenCount() != 0)
 +   {
 +      c1out << _("Hmm, seems like the AutoRemover destroyed something which really\n"
 +               "shouldn't happen. Please file a bug report against apt.") << endl;
 +      c1out << endl;
 +      c1out << _("The following information may help to resolve the situation:") << endl;
 +      c1out << endl;
 +      ShowBroken(c1out,Cache,false);
 +
 +      return _error->Error(_("Internal Error, AutoRemover broke stuff"));
 +   }
 +   return true;
 +}
 +
  // DoUpgrade - Upgrade all packages                                   /*{{{*/
  // ---------------------------------------------------------------------
  /* Upgrade all packages without installing new packages or erasing old
@@@ -1509,53 -1381,6 +1470,53 @@@ 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,
 +                  bool Remove)
 +{
 +   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:.*[, ]%s([, ]|$)", taskname);
 +   if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0)
 +      return _error->Error("Failed to compile task regexp");
 +   
 +   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,Remove,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 */
@@@ -1571,7 -1396,6 +1532,7 @@@ bool DoInstall(CommandLine &CmdL
     if (Cache->BrokenCount() != 0)
        BrokenFix = true;
     
 +   unsigned int AutoMarkChanged = 0;
     unsigned int ExpectedInst = 0;
     unsigned int Packages = 0;
     pkgProblemResolver Fix(Cache);
     bool DefRemove = false;
     if (strcasecmp(CmdL.FileList[0],"remove") == 0)
        DefRemove = true;
 -
 -   for (const char **I = CmdL.FileList + 1; *I != 0; I++)
 +   else if (strcasecmp(CmdL.FileList[0], "purge") == 0)
     {
 -      // Duplicate the string
 -      unsigned int Length = strlen(*I);
 -      char S[300];
 -      if (Length >= sizeof(S))
 -       continue;
 -      strcpy(S,*I);
 -      
 -      // See if we are removing and special indicators..
 -      bool Remove = DefRemove;
 -      char *VerTag = 0;
 -      bool VerIsRel = false;
 -      while (Cache->FindPkg(S).end() == true)
 +      _config->Set("APT::Get::Purge", true);
 +      DefRemove = true;
 +   }
 +   else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0)
 +   {
 +      _config->Set("APT::Get::AutomaticRemove", "true");
 +      DefRemove = true;
 +   }
 +   // new scope for the ActionGroup
 +   {
 +      pkgDepCache::ActionGroup group(Cache);
 +      for (const char **I = CmdL.FileList + 1; *I != 0; I++)
        {
 -       // Handle an optional end tag indicating what to do
 -       if (Length >= 1 && S[Length - 1] == '-')
 -       {
 -          Remove = true;
 -          S[--Length] = 0;
 +       // Duplicate the string
 +       unsigned int Length = strlen(*I);
 +       char S[300];
 +       if (Length >= sizeof(S))
            continue;
 -       }
 -       
 -       if (Length >= 1 && S[Length - 1] == '+')
 +       strcpy(S,*I);
 +      
 +       // See if we are removing and special indicators..
 +       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, Remove);
 +            continue;
 +         }
 +
 +       while (Cache->FindPkg(S).end() == true)
         {
 -          Remove = false;
 -          S[--Length] = 0;
 -          continue;
 -       }
 +          // Handle an optional end tag indicating what to do
 +          if (Length >= 1 && S[Length - 1] == '-')
 +          {
 +             Remove = true;
 +             S[--Length] = 0;
 +             continue;
 +          }
         
 -       char *Slash = strchr(S,'=');
 -       if (Slash != 0)
 -       {
 -          VerIsRel = false;
 -          *Slash = 0;
 -          VerTag = Slash + 1;
 -       }
 +          if (Length >= 1 && S[Length - 1] == '+')
 +          {
 +             Remove = false;
 +             S[--Length] = 0;
 +             continue;
 +          }
         
 -       Slash = strchr(S,'/');
 -       if (Slash != 0)
 -       {
 -          VerIsRel = true;
 -          *Slash = 0;
 -          VerTag = Slash + 1;
 -       }
 +          char *Slash = strchr(S,'=');
 +          if (Slash != 0)
 +          {
 +             VerIsRel = false;
 +             *Slash = 0;
 +             VerTag = Slash + 1;
 +          }
         
 -       break;
 -      }
 -      
 -      // Locate the package
 -      pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
 -      Packages++;
 -      if (Pkg.end() == true)
 -      {
 -       // Check if the name is a regex
 -       const char *I;
 -       for (I = S; *I != 0; I++)
 -          if (*I == '?' || *I == '*' || *I == '|' ||
 -              *I == '[' || *I == '^' || *I == '$')
 -             break;
 -       if (*I == 0)
 -          return _error->Error(_("Couldn't find package %s"),S);
 -
 -       // Regexs must always be confirmed
 -       ExpectedInst += 1000;
 +          Slash = strchr(S,'/');
 +          if (Slash != 0)
 +          {
 +             VerIsRel = true;
 +             *Slash = 0;
 +             VerTag = Slash + 1;
 +          }
         
 -       // Compile the regex pattern
 -       regex_t Pattern;
 -       int Res;
 -       if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE |
 -                   REG_NOSUB)) != 0)
 -       {
 -          char Error[300];        
 -          regerror(Res,&Pattern,Error,sizeof(Error));
 -          return _error->Error(_("Regex compilation error - %s"),Error);
 +          break;
         }
 -       
 -       // Run over the matches
 -       bool Hit = false;
 -       for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++)
 +      
 +       // Locate the package
 +       pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
 +       Packages++;
 +       if (Pkg.end() == true)
         {
 -          if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0)
 -             continue;
 +          // Check if the name is a regex
 +          const char *I;
 +          for (I = S; *I != 0; I++)
 +             if (*I == '?' || *I == '*' || *I == '|' ||
 +                 *I == '[' || *I == '^' || *I == '$')
 +                break;
 +          if (*I == 0)
 +             return _error->Error(_("Couldn't find package %s"),S);
 +
 +          // Regexs must always be confirmed
 +          ExpectedInst += 1000;
 +       
 +          // Compile the regex pattern
 +          regex_t Pattern;
 +          int Res;
 +          if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE |
 +                             REG_NOSUB)) != 0)
 +          {
 +             char Error[300];     
 +             regerror(Res,&Pattern,Error,sizeof(Error));
 +             return _error->Error(_("Regex compilation error - %s"),Error);
 +          }
 +       
 +          // Run over the matches
 +          bool Hit = false;
 +          for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++)
 +          {
 +             if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0)
 +                continue;
 +          
 +             ioprintf(c1out,_("Note, selecting %s for regex '%s'\n"),
 +                      Pkg.Name(),S);
            
 -          ioprintf(c1out,_("Note, selecting %s for regex '%s'\n"),
 -                   Pkg.Name(),S);
 +             if (VerTag != 0)
 +                if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
 +                   return false;
            
 +             Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
 +                                 ExpectedInst,false);
 +          }
 +          regfree(&Pattern);
 +       
 +          if (Hit == false)
 +             return _error->Error(_("Couldn't find package %s"),S);
 +       }
 +       else
 +       {
            if (VerTag != 0)
               if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
                  return false;
 -          
 -          Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
 -                              ExpectedInst,false);
 -       }
 -       regfree(&Pattern);
 -       
 -       if (Hit == false)
 -          return _error->Error(_("Couldn't find package %s"),S);
 -      }
 -      else
 -      {
 -       if (VerTag != 0)
 -          if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
 +          if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false)
               return false;
 -       if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false)
 -          return false;
 -      }      
 -   }
  
 -   /* If we are in the Broken fixing mode we do not attempt to fix the
 -      problems. This is if the user invoked install without -f and gave
 -      packages */
 -   if (BrokenFix == true && Cache->BrokenCount() != 0)
 -   {
 -      c1out << _("You might want to run `apt-get -f install' to correct these:") << endl;
 -      ShowBroken(c1out,Cache,false);
 +          // see if we need to fix the auto-mark flag 
 +          // e.g. apt-get install foo 
 +          // where foo is marked automatic
 +          if(!Remove && 
 +             Cache[Pkg].Install() == false && 
 +             (Cache[Pkg].Flags & pkgCache::Flag::Auto) &&
 +             _config->FindB("APT::Get::ReInstall",false) == false)
 +          {
 +             ioprintf(c1out,_("%s set to manually installed.\n"),
 +                      Pkg.Name());
 +             Cache->MarkAuto(Pkg,false);
 +             AutoMarkChanged++;
 +          }
 +       }      
 +      }
  
 -      return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
 -   }
 +      /* If we are in the Broken fixing mode we do not attempt to fix the
 +       problems. This is if the user invoked install without -f and gave
 +       packages */
 +      if (BrokenFix == true && Cache->BrokenCount() != 0)
 +      {
 +       c1out << _("You might want to run `apt-get -f install' to correct these:") << endl;
 +       ShowBroken(c1out,Cache,false);
 +
 +       return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
 +      }
     
 -   // Call the scored problem resolver
 -   Fix.InstallProtect();
 -   if (Fix.Resolve(true) == false)
 -      _error->Discard();
 +      // Call the scored problem resolver
 +      Fix.InstallProtect();
 +      if (Fix.Resolve(true) == false)
 +       _error->Discard();
  
 -   // Now we check the state of the packages,
 -   if (Cache->BrokenCount() != 0)
 -   {
 -      c1out << 
 -       _("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" 
 -       "distribution that some required packages have not yet been created\n"
 -       "or been moved out of Incoming.") << endl;
 -      if (Packages == 1)
 +      // Now we check the state of the packages,
 +      if (Cache->BrokenCount() != 0)
        {
 -       c1out << endl;
         c1out << 
 -        _("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.") << endl;
 -      }
 +          _("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" 
 +            "distribution that some required packages have not yet been created\n"
 +            "or been moved out of Incoming.") << endl;
 +       if (Packages == 1)
 +       {
 +          c1out << endl;
 +          c1out << 
 +             _("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.") << endl;
 +       }
 +
 +       c1out << _("The following information may help to resolve the situation:") << endl;
 +       c1out << endl;
 +       ShowBroken(c1out,Cache,false);
 +       return _error->Error(_("Broken packages"));
 +      }   
 +   }
 +   if (!DoAutomaticRemove(Cache)) 
 +      return false;
  
 -      c1out << _("The following information may help to resolve the situation:") << endl;
 -      c1out << endl;
 -      ShowBroken(c1out,Cache,false);
 -      return _error->Error(_("Broken packages"));
 -   }   
 -   
     /* Print out a list of packages that are going to be installed extra
        to what the user asked */
     if (Cache->InstCount() != ExpectedInst)
         
         if (*J == 0) {
            List += string(I.Name()) + " ";
 -        VersionsList += string(Cache[I].CandVersion) + "\n";
 -     }
 +          VersionsList += string(Cache[I].CandVersion) + "\n";
 +       }
        }
        
        ShowList(c1out,_("The following extra packages will be installed:"),List,VersionsList);
        string SuggestsVersions, RecommendsVersions;
        for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
        {
 -       pkgCache::PkgIterator I(Cache,Cache.List[J]);
 +       pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
  
         /* Just look at the ones we want to install */
 -       if ((*Cache)[I].Install() == false)
 +       if ((*Cache)[Pkg].Install() == false)
           continue;
  
 -       for (pkgCache::VerIterator V = I.VersionList(); V.end() == false; V++)
 -         {
 -           for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; )
 -             {
 -               pkgCache::DepIterator Start;
 -               pkgCache::DepIterator End;
 -               D.GlobOr(Start,End); // advances D
 -
 -               /* 
 -                * If this is a virtual package, we need to check the list of
 -                * packages that provide it and see if any of those are
 -                * installed
 -                */
 -               
 -               bool providedBySomething = false;
 -               for (pkgCache::PrvIterator Prv = Start.TargetPkg().ProvidesList();
 -                      Prv.end() != true;
 -                      Prv++)
 -                  if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
 -                    {
 -                     providedBySomething = true;
 -                     break;
 -                  }
 -
 -               if (providedBySomething) continue;
 -            
 -                 for(;;)
 -                 {
 -                     /* Skip if package is  installed already, or is about to be */
 -                     string target = string(Start.TargetPkg().Name()) + " ";
 -
 -                     if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install
 -                         || Cache[Start.TargetPkg()].Install())
 -                       break;
 -
 -                     /* Skip if we already saw it */
 -                     if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1)
 -                       break; 
 -
 -                   if (Start->Type == pkgCache::Dep::Suggests) {
 -                     SuggestsList += target;
 -                     SuggestsVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
 -                   }
 -                   
 -                   if (Start->Type == pkgCache::Dep::Recommends) {
 -                     RecommendsList += target;
 -                     RecommendsVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
 -                   }
 -
 -                     if (Start >= End)
 -                        break;
 -                     Start++;
 -                 }
 -             }
 -         }
 +       // get the recommends/suggests for the candidate ver
 +       pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
 +       for (pkgCache::DepIterator D = CV.DependsList(); D.end() == false; )
 +       {
 +          pkgCache::DepIterator Start;
 +          pkgCache::DepIterator End;
 +          D.GlobOr(Start,End); // advances D
 +
 +          // FIXME: we really should display a or-group as a or-group to the user
 +          //        the problem is that ShowList is incapable of doing this
 +          string RecommendsOrList,RecommendsOrVersions;
 +          string SuggestsOrList,SuggestsOrVersions;
 +          bool foundInstalledInOrGroup = false;
 +          for(;;)
 +          {
 +             /* Skip if package is  installed already, or is about to be */
 +             string target = string(Start.TargetPkg().Name()) + " ";
 +             
 +             if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install
 +                 || Cache[Start.TargetPkg()].Install())
 +             {
 +                foundInstalledInOrGroup=true;
 +                break;
 +             }
 +
 +             /* Skip if we already saw it */
 +             if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1)
 +             {
 +                foundInstalledInOrGroup=true;
 +                break; 
 +             }
 +
 +             // this is a dep on a virtual pkg, check if any package that provides it
 +             // should be installed
 +             if(Start.TargetPkg().ProvidesList() != 0)
 +             {
 +                pkgCache::PrvIterator I = Start.TargetPkg().ProvidesList();
 +                for (; I.end() == false; I++)
 +                {
 +                   pkgCache::PkgIterator Pkg = I.OwnerPkg();
 +                   if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer() && 
 +                       Pkg.CurrentVer() != 0)
 +                      foundInstalledInOrGroup=true;
 +                }
 +             }
 +
 +             if (Start->Type == pkgCache::Dep::Suggests) 
 +             {
 +                SuggestsOrList += target;
 +                SuggestsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
 +             }
 +             
 +             if (Start->Type == pkgCache::Dep::Recommends) 
 +             {
 +                RecommendsOrList += target;
 +                RecommendsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
 +             }
 +
 +             if (Start >= End)
 +                break;
 +             Start++;
 +          }
 +          
 +          if(foundInstalledInOrGroup == false)
 +          {
 +             RecommendsList += RecommendsOrList;
 +             RecommendsVersions += RecommendsOrVersions;
 +             SuggestsList += SuggestsOrList;
 +             SuggestsVersions += SuggestsOrVersions;
 +          }
 +             
 +       }
        }
 +
        ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions);
        ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions);
  
     }
  
 +   // if nothing changed in the cache, but only the automark information
 +   // we write the StateFile here, otherwise it will be written in 
 +   // cache.commit()
 +   if (AutoMarkChanged > 0 &&
 +       Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
 +       Cache->BadCount() == 0)
 +      Cache->writeStateFile(NULL);
 +
     // See if we need to prompt
     if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
        return InstallPackages(Cache,false,false);
@@@ -1932,8 -1689,6 +1893,8 @@@ bool DoDSelectUpgrade(CommandLine &CmdL
     if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
        return false;
     
 +   pkgDepCache::ActionGroup group(Cache);
 +
     // Install everything with the install flag set
     pkgCache::PkgIterator I = Cache->PkgBegin();
     for (;I.end() != true; I++)
@@@ -2152,11 -1907,6 +2113,11 @@@ bool DoSource(CommandLine &CmdL
             I->Type != "tar")
            continue;
  
 +       // Dsc only mode only fetches .dsc files
 +       if (_config->FindB("APT::Get::Dsc-Only",false) == true &&
 +           I->Type != "dsc")
 +          continue;
 +
         // don't download the same uri twice (should this be moved to
         // the fetcher interface itself?)
         if(queued.find(Last->Index().ArchiveURI(I->Path)) != queued.end())
        return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
                           OutputDir.c_str());
     if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
 -      return _error->Error(_("You don't have enough free space in %s"),
 -                         OutputDir.c_str());
 +     {
 +       struct statfs Stat;
 +       if (statfs(OutputDir.c_str(),&Stat) != 0 || 
 +           unsigned(Stat.f_type) != RAMFS_MAGIC) 
 +          return _error->Error(_("You don't have enough free space in %s"),
 +              OutputDir.c_str());
 +      }
     
     // Number of bytes
     if (DebBytes != FetchBytes)
        pkgAcquire::UriIterator I = Fetcher.UriBegin();
        for (; I != Fetcher.UriEnd(); I++)
         cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
 -             I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
 +             I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
        return true;
     }
     
@@@ -2485,7 -2230,6 +2446,7 @@@ bool DoBuildDep(CommandLine &CmdL
                             break;
                   }
                   if (CV.end() == true)
 +               {
                   if (hasAlternatives)
                   {
                      continue;
                                             Last->BuildDepType((*D).Type),Src.c_str(),
                                             (*D).Package.c_str());
                   }
 +               }
              }
              else
              {
@@@ -2598,8 -2341,8 +2559,8 @@@ bool DoMoo(CommandLine &CmdL
  /* */
  bool ShowHelp(CommandLine &CmdL)
  {
 -   ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
 -          COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
 +   ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION,
 +          COMMON_ARCH,__DATE__,__TIME__);
            
     if (_config->FindB("version") == true)
     {
        "   upgrade - Perform an upgrade\n"
        "   install - Install new packages (pkg is libc6 not libc6.deb)\n"
        "   remove - Remove packages\n"
 +      "   autoremove - Remove all automatic unused packages\n"
 +      "   purge - Remove and purge packages\n"
        "   source - Download source archives\n"
        "   build-dep - Configure build-dependencies for source packages\n"
        "   dist-upgrade - Distribution upgrade, see apt-get(8)\n"
@@@ -2700,7 -2441,6 +2661,7 @@@ 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                               /*{{{*/
@@@ -2748,8 -2488,7 +2709,8 @@@ int main(int argc,const char *argv[]
        {0,"force-yes","APT::Get::force-yes",0},
        {0,"print-uris","APT::Get::Print-URIs",0},
        {0,"diff-only","APT::Get::Diff-Only",0},
 -      {0,"tar-only","APT::Get::tar-Only",0},
 +      {0,"tar-only","APT::Get::Tar-Only",0},
 +      {0,"dsc-only","APT::Get::Dsc-Only",0},
        {0,"purge","APT::Get::Purge",0},
        {0,"list-cleanup","APT::Get::List-Cleanup",0},
        {0,"reinstall","APT::Get::ReInstall",0},
        {0,"remove","APT::Get::Remove",0},
        {0,"only-source","APT::Get::Only-Source",0},
        {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}};
                                     {"upgrade",&DoUpgrade},
                                     {"install",&DoInstall},
                                     {"remove",&DoInstall},
 +                                   {"purge",&DoInstall},
 +                                 {"autoremove",&DoInstall},
 +                                 {"purge",&DoInstall},
                                     {"dist-upgrade",&DoDistUpgrade},
                                     {"dselect-upgrade",&DoDSelectUpgrade},
                                   {"build-dep",&DoBuildDep},
diff --combined debian/changelog
index 52625ee2decae6c4faa13931771f0049bca033ab,6ce11aafbbdc1a4394b43d32d8172be27d7fb144..ee5384c42a78d8393eea31c54e668f523467ec15
 +apt (0.7.10) UNRELEASED; urgency=low
 +
 +  [ Otavio Salvador ]
 +  * Applied patch from Mike O'Connor <stew@vireo.org> to add a manpage to
 +    apt-mark, closes: #430207.
 +  * Applied patch from Andrei Popescu <andreimpopescu@gmail.com> to add a
 +    note about some frontends in apt.8 manpage, closes: #438545.
 +  * Applied patch from Aurelien Jarno <aurel32@debian.org> to avoid CPU
 +    getting crazy when /dev/null is redirected to stdin (which breaks
 +    buildds), closes: #452858.
 +  * Applied patch from Aurelien Jarno <aurel32@debian.org> to fix building
 +    with newest dpkg-shlibdeps changing the packaging building order and a
 +    patch from Robert Millan <rmh@aybabtu.com> to fix parallel building,
 +    closes: #452862.
 +  * Applied patch from Alexander Winston <alexander.winston@comcast.net>
 +    to use 'min' as symbol for minute, closes: #219034.
 +  * Applied patch from Amos Waterland <apw@us.ibm.com> to allow apt to
 +    work properly in initramfs, closes: #448316.
 +  * Applied patch from Robert Millan <rmh@aybabtu.com> to make apt-key and
 +    apt-get to ignore time conflicts, closes: #451328.
 +  * Applied patch from Peter Eisentraut <peter_e@gmx.net> to fix a
 +    grammatical error ("manual installed" -> "manually installed"),
 +    closes: #438136.
 +  * Fix cron.daily job to not call fail if apt isn't installed, closes:
 +    #443286.
 +
 +  [ Program translations ]
 +    - Basque updated. Closes: #453088
 +    - Vietnamese updated. Closes: #453774
 +    - Japanese updated. Closes: #456909
 +    - French updated.
 +
 +  [ Michael Vogt ]
 +  * debian/rules
 +    - fix https install location
 +  * debian/apt.conf.daily:
 +    - print warning if the cache can not be locked (closes: #454561),
 +      thanks to Bastian Kleineidam
 +  * methods/gpgv.cc:
 +    - remove cruft code that caused timestamp/I-M-S issues
 +  * ftparchive/contents.cc:
 +    - fix error output
 +  * apt-pkg/acquire-item.{cc,h}:
 +    - make the authentication download code more robust against
 +      servers/proxies with broken If-Range implementations
 +  * apt-pkg/packagemanager.{cc,h}:
 +    - propergate the Immediate flag to make hitting the 
 +      "E: Internal Error, Could not perform immediate configuration (2)"
 +      harder
 +  * debian/control:
 +    - build against libdb-dev (instead of libdb4.4-dev)
++  * merged the apt--DoListUpdate branch, this provides a common interface
++    for apt-get update like operations for the frontends and also provides
++    hooks to run stuff in APT::Update::{Pre,Post}-Invoke
 +
 +  [ Chris Cheney ]
 +  * ftparchive/contents.cc:
 +    - support lzma data members
 +  * ftparchive/multicompress.cc:
 +    - support lzma output
 +  
 +  [ Daniel Burrows ]
 +  * apt-pkg/contrib/configuration.cc:
 +    - if RootDir is set, then FindFile and FindDir will return paths
 +      relative to the directory stored in RootDir, closes: #456457.
 +
 +  [ Christian Perrier ]
 +  * Fix wording for "After unpacking...". Thans to Michael Gilbert
 +    for the patch. Closes: #260825
 +
 + -- Christian Perrier <bubulle@debian.org>  Mon, 17 Dec 2007 10:10:17 +0530
 +
 +apt (0.7.9) unstable; urgency=low
 +
 +  [ Christian Perrier ]
 +  * Add several languages to LINGUAS and, therefore, really ship the relevant
 +    translation:
 +    Arabic, Dzongkha, Khmer, Marathi, Nepali, Thai
 +    Thanks to Theppitak Karoonboonyanan for checking this out. Closes: #448321
 +
 +  [ Program translations ]
 +    - Korean updated. Closes: #448430
 +    - Galician updated. Closes: #448497
 +    - Swedish updated.
 +
 +  [ Otavio Salvador ]
 +  * Fix configure script to check for CURL library and headers presense.
 +  * Applied patch from Brian M. Carlson <sandals@crustytoothpaste.ath.cx>
 +    to add backward support for arches that lacks pselect support,
 +    closes: #448406.
 +  * Umount CD-ROM when calling apt-cdrom ident, except when called with
 +    -m, closes: #448521.
 +
 + -- Otavio Salvador <otavio@debian.org>  Wed, 31 Oct 2007 13:37:26 -0200
 +
 +apt (0.7.8) unstable; urgency=low
 +
 +  * Applied patch from Daniel Leidert <daniel.leidert@wgdd.de> to fix
 +    APT::Acquire::Translation "none" support, closes: #437523.
 +  * Applied patch from Daniel Burrows <dburrows@debian.org> to add support
 +    for the Homepage field (ABI break), closes: #447970.
 +  * Applied patch from Frans Pop <elendil@planet.nl> to fix a trailing
 +    space after cd label, closes: #448187.
 +
 + -- Otavio Salvador <otavio@debian.org>  Fri, 26 Oct 2007 18:20:13 -0200
 +
 +apt (0.7.7) unstable; urgency=low
 +
 +  [ Michael Vogt ]
 +  * apt-inst/contrib/extracttar.cc:
 +    - fix fd leak for zero size files (thanks to Bill Broadley for
 +      reporting this bug)
 +  * apt-pkg/acquire-item.cc:
 +    - remove zero size files on I-M-S hit
 +  * methods/https.cc:
 +    - only send LastModified if we actually have a file
 +    - send range request with if-range 
 +    - delete failed downloads
 +    - delete zero size I-M-S hits
 +  * apt-pkg/deb/dpkgpm.{cc,h}:
 +    - merged dpkg-log branch, this lets you specify a 
 +      Dir::Log::Terminal file to log dpkg output to
 +      (ABI break)
 +    - fix parse error when dpkg sends unexpected data
 +  * merged apt--sha256 branch to fully support the new
 +    sha256 checksums in the Packages and Release files
 +    (ABI break)
 +  * apt-pkg/pkgcachegen.cc:
 +    - increase default mmap size
 +  * tests/local-repo:
 +    - added local repository testcase
 +  * apt-pkg/acquire.cc:
 +    - increase MaxPipeDepth for the internal worker<->method
 +      communication to 1000 for the debtorrent backend
 +  * make apt build with g++ 4.3
 +  * fix missing SetExecClose() call when the status-fd is used
 +  * debian/apt.cron.daily:
 +    - move unattended-upgrade before apt-get autoclean
 +  * fix "purge" commandline argument, closes: #133421
 +    (thanks to Julien Danjou for the patch)
 +  * cmdline/apt-get.cc:
 +    - do not change the auto-installed information if a package
 +      is reinstalled
 +  * apt-pkg/acquire-item.cc:
 +    - fix crash in diff acquire code
 +  * cmdline/apt-mark:
 +    - Fix chmoding after have renamed the extended-states file (LP: #140019)
 +      (thanks to Laurent Bigonville)
 +  * apt-pkg/depcache.cc:
 +    - set "APT::Install-Recommends" to true by default (OMG!)
 +  * debian/apt.cron.daily:
 +    - only run the cron job if apt-get check succeeds (LP: #131719)
 +  
 +  [ Program translations ]
 +    - French updated
 +    - Basque updated. Closes: #436425
 +    - Fix the zh_CN translator's name in debian/changelog for 0.7.2
 +      Closes: #423272
 +    - Vietnamese updated. Closes: #440611
 +    - Danish updated. Closes: #441102
 +    - Thai added. Closes: #442833
 +    - Swedish updated.
 +    - Galician updated. Closes: #446626
 +
 +  [ Otavio Salvador ]
 +  * Add hash support to copy method. Thanks Anders Kaseorg by the patch
 +    (closes: #436055)
 +  * Reset curl options and timestamp between downloaded files. Thanks to
 +    Ryan Murray <rmurray@debian.org> for the patch (closes: #437150)
 +  * Add support to apt-key to export keys to stdout. Thanks to "Dwayne
 +    C. Litzenberger" <dlitz@dlitz.net> for the patch (closes: #441942)
 +  * Fix compilation warnings:
 +    - apt-pkg/indexfile.cc: conversion from string constant to 'char*';
 +    - apt-pkg/acquire-item.cc: likewise;
 +    - apt-pkg/cdrom.cc: '%lu' expects 'long unsigned int', but argument
 +      has type 'size_t';
 +    - apt-pkg/deb/dpkgpm.cc: initialization order and conversion from
 +      string constant to 'char*';
 +    - methods/gpgv.cc: conversion from string constant to 'char*';
 +    - methods/ftp.cc: likewise;
 +    - cmdline/apt-extracttemplates.cc: likewise;
 +    - apt-pkg/deb/debmetaindex.cc: comparison with string literal results
 +      in unspecified behaviour;
 +  * cmdline/apt-get.cc: adds 'autoremove' as a valid comment to usage
 +    statement of apt-get (closes: #445468).
 +  * cmdline/apt-get.cc: really applies Julien Danjou <acid@debian.org>
 +    patch to add 'purge' command line argument (closes: #133421).
 +
 +  [ Ian Jackson ]
 +  * dpkg-triggers: Deal properly with new package states.
 +
 +  [ Colin Watson ]
 +  * apt-pkg/contrib/mmap.cc:
 +    - don't fail if msync() returns > 0
 + 
 + -- Michael Vogt <mvo@debian.org>  Tue, 23 Oct 2007 14:58:03 +0200
 +
 +apt (0.7.6) unstable; urgency=low
 +
 +  * Applied patch from Aurelien Jarno <aurel32@debian.org> to fix wrong
 +    directory downloading on non-linux architectures (closes: #435597)
 +
 + -- Otavio Salvador <otavio@debian.org>  Wed, 01 Aug 2007 19:49:51 -0300
 +
 +apt (0.7.6) unstable; urgency=low
 +
 +  * Applied patch from Aurelien Jarno <aurel32@debian.org> to fix wrong
 +    directory downloading on non-linux architectures (closes: #435597)
 +
 + -- Otavio Salvador <otavio@debian.org>  Wed, 01 Aug 2007 19:49:51 -0300
 +
 +apt (0.7.5) unstable; urgency=low
 +
 +  [ Otavio Salvador ]
 +  * Applied patch from Guillem Jover <guillem@debian.org> to use
 +    dpkg-architecture to get the host architecture (closes: #407187)
 +  * Applied patch from Guillem Jover <guillem@debian.org> to add
 +    support to add lzma support (closes: #408201)
 +
 +  [ Michael Vogt ]
 +  * apt-pkg/depcache.cc:
 +    - support a list of sections for:
 +      APT::Install-Recommends-Sections
 +      APT::Never-MarkAuto-Sections
 +  * methods/makefile:
 +    - install lzma symlink method (for full lzma support)
 +  * debian/control:
 +    - suggest "lzma"
 +
 + -- Otavio Salvador <otavio@ossystems.com.br>  Wed, 25 Jul 2007 20:16:46 -0300
 +
 +apt (0.7.4) unstable; urgency=low
 +
 +  [ Michael Vogt ]
 +  * cmdline/apt-get.cc:
 +    - fix in the task-install code regexp (thanks to Adam Conrad and
 +      Colin Watson)
 +    - support task removal too: apt-get remove taskname^
 +      (thanks to Matt Zimmerman reporting this problem)
 +
 +  [ Otavio Salvador ]
 +  * Fix a typo on 0.7.3 changelog entry about g++ (7.3 to 4.3)
 +  * Fix compilation warnings:
 +    - apt-pkg/contrib/configuration.cc: wrong argument type;
 +    - apt-pkg/deb/dpkgpm.cc: wrong signess;
 +    - apt-pkg-acquire-item.cc: wrong signess and orderned initializers;
 +    - methods/https.cc:
 +      - type conversion;
 +      - unused variable;
 +      - changed SetupProxy() method to void;
 +  * Simplified HttpMethod::Fetch on http.cc removing Tail variable;
 +  * Fix pipeline handling on http.cc (closes: #413324)
 +  * Fix building to properly support binNMUs. Thanks to Daniel Schepler
 +    <schepler@math.unipd.it> by the patch (closes: #359634)
 +  * Fix example for Install-{Recommends,Suggests} options on
 +    configure-index example file. Thanks to Peter Eisentraut
 +    <peter_e@gmx.net> by the patch (closes: #432223)
 +
 +  [ Christian Perrier ]
 +  * Basque translation update. Closes: ##423766
 +  * Unfuzzy formerly complete translations
 +  * French translation update
 +  * Re-generate PO(T) files
 +  * Spanish translation update
 +  * Swedish translation update
 +
 + -- Otavio Salvador <otavio@debian.org>  Tue, 24 Jul 2007 09:55:50 -0300
 +
 +apt (0.7.3) unstable; urgency=low
 +
 +  * fixed compile errors with g++ 4.3 (thanks to 
 +    Daniel Burrows, closes: #429378)
 +  * fixes in the auto-mark code (thanks to Daniel
 +    Burrows)
 +  * fix FTFBFS by changing build-depends to
 +    libcurl4-gnutls-dev (closes: #428363)
 +  * cmdline/apt-get.cc:
 +    - fix InstallTask code when a pkgRecord ends 
 +      with a single '\n' (thanks to Soren Hansen for reporting)
 +  * merged from Christian Perrier:
 +        * vi.po: completed to 532t, again. Closes: #429899
 +        * gl.po: completed to 532t. Closes: #429506
 +        * vi.po: completed to 532t. Closes: #428672
 +        * Update all PO and the POT. Gives 514t14f4u for formerly
 +          complete translations
 +        * fr.po: completed to 532t
 +        * ku.po, uk.po, LINGUAS: reintegrate those translations
 +          which disappeared from the BZR repositories
 +
 + -- Michael Vogt <mvo@debian.org>  Sun, 01 Jul 2007 12:31:29 +0200
 +
 +apt (0.7.2-0.1) unstable; urgency=low
 +
 +  * Non-maintainer upload.
 +  * Build-depend on libcurl4-gnutls-dev instead of the obsolete
 +    libcurl3-gnutls-dev.  Closes: #428363.
 +
 + -- Steve Langasek <vorlon@debian.org>  Thu, 28 Jun 2007 18:46:53 -0700
 +
 +apt (0.7.2) unstable; urgency=low
 +  
 +  * merged the debian/experimental changes back
 +    into the debian/sid branch
 +  * merged from Christian Perrier:
 +    * mr.po: New Marathi translation  Closes: #416806
 +    * zh_CN.po: Updated by Kov Chai  Closes: #416822
 +    * tl.po: Updated by Eric Pareja   Closes: #416638
 +    * gl.po: Updated by Jacobo Tarrio
 +           Closes: #412828
 +    * da.po: Updated by Claus Hindsgaul
 +           Closes: #409483
 +    * fr.po: Remove a non-breakable space for usability
 +           issues. Closes: #408877
 +    * ru.po: Updated Russian translation. Closes: #405476
 +    * *.po: Unfuzzy after upstream typo corrections
 +  * buildlib/archtable:
 +    - added support for sh3/sh4 (closes: #424870)
 +    - added support for m32r (closes: #394096)
 +  * buildlib/systemtable:
 +    - added support for lpia
 +  * configure.in:
 +    - check systemtable for architecture mapping too
 +  * fix error in AutocleanInterval, closes: #319339
 +    (thanks to Israel G. Lugo for the patch)
 +  * add "purge" commandline argument, closes: #133421)
 +    (thanks to Julien Danjou for the patch)
 +  * add "purge" commandline argument, closes: #133421)
 +    (thanks to Julien Danjou for the patch)
 +  * fix FTBFS with gcc 4.3, closes: #417090
 +    (thanks to Martin Michlmayr for the patch)
 +  * add --dsc-only option, thanks to K. Richard Pixley
 +  * Removed the more leftover #pragma interface/implementation
 +    closes: #306937 (thanks to Andreas Henriksson for the patch)
 +  
 + -- Michael Vogt <mvo@debian.org>  Wed, 06 Jun 2007 23:19:50 +0200
 +
 +apt (0.7.1) experimental; urgency=low
 +
 +  * ABI library name change because its build against
 +    new glibc
 +  * implement SourceVer() in pkgRecords 
 +     (thanks to Daniel Burrows for the patch!)
 +  * apt-pkg/algorithm.cc:
 +    - use clog for all debugging
 +    - only increase the score of installed applications if they 
 +      are not obsolete 
 +    - fix resolver bug on removal triggered by weak-dependencies 
 +      with or-groups
 +  * methods/http.cc:
 +    - send apt version in User-Agent
 +  * apt-pkg/deb/debrecords.cc:
 +    - fix SHA1Hash() return value
 +  * apt-pkg/cdrom.cc:
 +    - only unmount if APT::CDROM::NoMount is false
 +  * methods/cdrom.cc:  
 +    - only umount if it was mounted by the method before
 +  * po/gl.po:
 +    - fix error translation that causes trouble to lsb_release
 +  * apt-pkg/acquire-item.cc:
 +    - if decompression of a index fails, delete the index 
 +  * apt-pkg/acquire.{cc,h}:
 +    - deal better with duplicated sources.list entries (avoid
 +      double queuing of  URLs) - this fixes hangs in bzip/gzip
 +  * merged from Christian Perrier:
 +    * mr.po: New Marathi translation  Closes: #416806
 +    * zh_CN.po: Updated by Eric Pareja  Closes: #416822
 +    * tl.po: Updated by Eric Pareja   Closes: #416638
 +    * gl.po: Updated by Jacobo Tarrio
 +             Closes: #412828
 +    * da.po: Updated by Claus Hindsgaul
 +             Closes: #409483
 +    * fr.po: Remove a non-breakable space for usability
 +             issues. Closes: #408877
 +    * ru.po: Updated Russian translation. Closes: #405476
 +    * *.po: Unfuzzy after upstream typo corrections
 +    * vi.po: Updated to 515t. Closes: #426976
 +    * eu.po: Updated to 515t. Closes: #423766
 +    * pt.po: 515t. Closes: #423111
 +    * fr.po: Updated by Christian Perrier
 +    * Update all PO and the POT. Gives 513t2f for formerly
 +      complete translations
 +  * apt-pkg/policy.cc:
 +    - allow multiple packages (thanks to David Foerster)
 +
 + -- Michael Vogt <mvo@debian.org>  Wed,  2 May 2007 13:43:44 +0200
 +
 +apt (0.7.0) experimental; urgency=low
 +
 +  * Package that contains tall the new features
 +  * Removed all #pragma interface/implementation
 +  * Branch that contains tall the new features:
 +  * translated package descriptions
 +  * task install support
 +  * automatic dependency removal (thanks to Daniel Burrows)
 +  * merged support for the new dpkg "Breaks" field 
 +    (thanks to Ian Jackson)
 +  * handle network failures more gracefully on "update"
 +  * support for unattended-upgrades (via unattended-upgrades
 +    package)
 +  * added apt-transport-https method
 +
 + -- Michael Vogt <mvo@debian.org>  Fri, 12 Jan 2007 20:48:07 +0100
 +
 +apt (0.6.46.4-0.1) unstable; urgency=emergency
 +  
 +  * NMU
 +  * Fix broken use of awk in apt-key that caused removal of the wrong keys
 +    from the keyring. Closes: #412572
 +
 + -- Joey Hess <joeyh@debian.org>  Mon, 26 Feb 2007 16:00:22 -0500
 +
 +apt (0.6.46.4) unstable; urgency=high
 +
 +  * ack NMU (closes: #401017)
 +  * added apt-secure.8 to "See also" section
 +  * apt-pkg/deb/dpkgpm.cc:
 +    - added "Dpkg::StopOnError" variable that controls if apt
 +      will abort on errors from dpkg
 +  * apt-pkg/deb/debsrcrecords.{cc,h}:
 +    - make the Buffer grow dynmaically (closes: #400874)
 +  * Merged from Christian Perrier bzr branch:
 +    - uk.po: New Ukrainian translation: 483t28f3u
 +    - el.po: Update to 503t9f2u
 +    - de.po: Updates and corrections.
 +  * apt-pkg/contrib/progress.cc:
 +    - OpProgress::CheckChange optimized, thanks to Paul Brook
 +      (closes: #398381)
 +  * apt-pkg/contrib/sha256.cc:
 +    - fix building with noopt
 +
 + -- Michael Vogt <mvo@debian.org>  Thu,  7 Dec 2006 10:49:50 +0100
 +
 +apt (0.6.46.3-0.2) unstable; urgency=high
 +
 +  * Non-maintainer upload with permission of Michael Vogt.
 +  * Fix FTBFS on most arches (regression from the fix of #400874)
 +
 + -- Andreas Barth <aba@not.so.argh.org>  Tue,  5 Dec 2006 15:51:22 +0000 
 +  
 +apt (0.6.46.3-0.1) unstable; urgency=high
 +
 +  * Non-maintainer upload with permission of Michael Vogt.
 +  * Fix segfault at apt-get source. Closes: #400874
 +  * Add apt-key update in postinst, so that debian-archive-keyring doesn't
 +    need to depend on apt >= 0.6. Closes: #401114
 +  * Don't double-queue pdiff files. Closes: #401017
 +  
 + -- Andreas Barth <aba@not.so.argh.org>  Tue,  5 Dec 2006 10:34:56 +0000
 +
 +apt (0.6.46.3) unstable; urgency=low
 +
 +  * apt-pkg/deb/dpkgpm.cc:
 +    - make progress reporting robust against multiline error
 +      messages 
 +
 +  * Merged from Christian Perrier bzr branch:
 +    - ca.po: Updated to 514t
 +    - be.po: Updated to 514t
 +    - it.po: Updated to 514t
 +    - hu.po: Updated to 514t
 +    - zh_TW.po: Updated to 514t
 +    - ar.po: Updated to 293t221u.
 +    - ru.po: Updated to 514t. Closes: #392466
 +    - nb.po: Updated to 514t. Closes: #392466
 +    - pt.po: Updated to 514t. Closes: #393199
 +    - fr.po: One spelling error corrected: s/accèder/accéder
 +    - km.po: Updated to 514t.
 +    - ko.po: Updated to 514t.
 +    - bg.po: Updated to 514t.
 +    - de.po: Updated to 514t.
 +    - en_GB.po: Updated to 514t.
 +
 + -- Michael Vogt <mvo@debian.org>  Thu,  2 Nov 2006 11:37:58 +0100
 +
 +apt (0.6.46.2) unstable; urgency=low
 +
 +  * debian/control:
 +    - depend on debian-archive-keyring to offer clean upgrade path 
 +      (closes: #386800)
 +  * Merged from Christian Perrier bzr branch:
 +    - es.po: Updated to 514t. Closes: #391661
 +    - da.po: Updated to 514t. Closes: #391424
 +    - cs.po: Updated. Closes: #391064
 +    - es.po: Updated to 514t. Closes: #391661
 +    - da.po: Updated to 514t. Closes: #391424
 +
 + -- Michael Vogt <mvo@debian.org>  Wed, 11 Oct 2006 09:03:15 +0200
 +
 +apt (0.6.46.1) unstable; urgency=low
 +
 +  * merged "install-recommends" branch (ABI break): 
 +    - new "--install-recommends"
 +    - install new recommends on "upgrade" if --install-recommends is 
 +      given
 +    - new "--fix-policy" option to install all packages with unmet
 +      important dependencies (usefull with --install-recommends to
 +      see what not-installed recommends are on the system)
 +    - fix of recommended packages display (only show CandidateVersion
 +      fix or-group handling)
 +  * merged "install-task" branch (use with "apt-get install taskname^")
 +  * methods/gzip.cc:
 +    - deal with empty files 
 +  * Applied patch from Daniel Schepler to make apt bin-NMU able.
 +    (closes: bug#359634)
 +  * rebuild against current g++ because of:
 +    http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29289
 +    (closes: #390189)
 +  * fix broken i18n in the dpkg progress reporting, thanks to 
 +    Frans Pop and Steinar Gunderson. (closes: #389261)
 +  * Merged from Christian Perrier bzr branch:
 +    * fi.po: Updated to 514t. Closes: #390149
 +    * eu.po: Updated to 514t. Closes: #389725
 +    * vi.po: Updated to 514t. Closes: #388555
 +  * make the internal buffer in pkgTagFile grow dynamically
 +    (closes: #388708)
 +  
 + -- Michael Vogt <mvo@debian.org>  Mon,  2 Oct 2006 20:42:20 +0200
 +
 +apt (0.6.46) unstable; urgency=low
 +
 +  * debian/control:
 +    - switched to libdb4.4 for building (closes: #381019)
 +  * cmdline/apt-get.cc:
 +    - show only the recommends/suggests for the candidate-version, not for all
 +      versions of the package (closes: #257054)
 +    - properly handle recommends/suggests or-groups when printing the list of
 +      suggested/recommends packages (closes: #311619)
 +  * methods/http.cc:
 +    - check more careful for incorrect proxy settings (closes: #378868)
 +  * methods/gzip.cc:
 +    - don't hang when /var is full (closes: #341537), thanks to
 +      Luis Rodrigo Gallardo Cruz for the patch
 +  * doc/examples/sources.list:
 +    - removed non-us.debian.org from the example (closes: #380030,#316196)
 +  * Merged from Christian Perrier bzr branch:
 +    * ro.po: Updated to 514t. Closes: #388402
 +    * dz.po: Updated to 514t. Closes: #388184
 +    * it.po: Fixed typos. Closes: #387812
 +    * ku.po: New kurdish translation. Closes: #387766
 +    * sk.po: Updated to 514t. Closes: #386851
 +    * ja.po: Updated to 514t. Closes: #386537
 +    * gl.po: Updated to 514t. Closes: #386397
 +    * fr.po: Updated to 516t.
 +    * fi.po: Updated to 512t. Closes: #382702
 +  * share/archive-archive.gpg:
 +    - removed the outdated amd64 and debian-2004 keys
 +  * apt-pkg/tagfile.cc:
 +    - applied patch from Jeroen van Wolffelaar to make the tags
 +      caseinsensitive (closes: #384182)
 +    - reverted MMap use in the tagfile because it does not work 
 +      across pipes (closes: #383487) 
 +  
 + -- Michael Vogt <mvo@debian.org>  Thu, 21 Sep 2006 10:25:03 +0200
 +
 +apt (0.6.45) unstable; urgency=low
 +
 +  * apt-pkg/contrib/sha256.cc:
 +    - fixed the sha256 generation (closes: #378183)
 +  * ftparchive/cachedb.cc:
 +    - applied patch from Anthony Towns to fix Clean() function
 +      (closes: #379576)
 +  * doc/apt-get.8.xml:
 +    - fix path to the apt user build (Closes: #375640)
 +  * doc/apt-cache.8.xml:
 +    - typo (Closes: #376408)
 +  * apt-pkg/deb/dpkgpm.cc:
 +    - make progress reporting more robust against multiline error
 +      messages (first half of a fix for #374195)
 +  * doc/examples/configure-index:
 +    - document Debug::pkgAcquire::Auth     
 +  * methods/gpgv.cc:
 +    - deal with gpg error "NODATA". Closes: #296103, Thanks to 
 +      Luis Rodrigo Gallardo Cruz for the patch
 +  * apt-inst/contrib/extracttar.cc:
 +    - fix for string mangling, closes: #373864
 +  * apt-pkg/acquire-item.cc:
 +    - check for bzip2 in /bin (closes: #377391)
 +  * apt-pkg/tagfile.cc:
 +    - make it work on non-mapable files again, thanks 
 +      to James Troup for confirming the fix (closes: #376777)
 +  * Merged from Christian Perrier bzr branch:
 +    * ko.po: Updated to 512t. Closes: #378901
 +    * hu.po: Updated to 512t. Closes: #376330
 +    * km.po: New Khmer translation: 506t6f. Closes: #375068
 +    * ne.po: New Nepali translation: 512t. Closes: #373729
 +    * vi.po: Updated to 512t. Closes: #368038
 +    * zh_TW.po: Remove an extra %s in one string. Closes: #370551
 +    * dz.po: New Dzongkha translation: 512t
 +    * ro.po: Updated to 512t
 +    * eu.po: Updated
 +    * eu.po: Updated
 +  * fix apt-get dist-upgrade
 +  * fix warning if no /var/lib/apt/extended_states is present
 +  * don't download Translations for deb-src sources.list lines
 +  * apt-pkg/tagfile.cc:
 +    - support not-mmapable files again
 +
 + -- Michael Vogt <mvo@debian.org>  Thu, 27 Jul 2006 00:52:05 +0200
 +
 +apt (0.6.44.2exp1) experimental; urgency=low
 +
 +  * added support for i18n of the package descriptions
 +  * added support for aptitude like auto-install tracking (a HUGE
 +    HUGE thanks to Daniel Burrows who made this possible) 
 +  * synced with the http://people.debian.org/~mvo/bzr/apt/debian-sid branch
 +  * build from http://people.debian.org/~mvo/bzr/apt/debian-experimental
 +
 + -- Michael Vogt <mvo@debian.org>  Mon,  3 Jul 2006 21:50:31 +0200
 +
 +apt (0.6.44.2) unstable; urgency=low
 +
 +  * apt-pkg/depcache.cc:
 +    - added Debug::pkgDepCache::AutoInstall (thanks to infinity)
 +  * apt-pkg/acquire-item.cc:
 +    - fix missing chmod() in the new aquire code 
 +      (thanks to Bastian Blank, Closes: #367425)
 +  * merged from 
 +    http://www.perrier.eu.org/debian/packages/d-i/level4/apt-main:
 +    * sk.po: Completed to 512t
 +    * eu.po: Completed to 512t
 +    * fr.po: Completed to 512t
 +    * sv.po: Completed to 512t
 +    * Update all PO and the POT. Gives 506t6f for formerly
 +      complete translations
 +
 + -- Michael Vogt <mvo@debian.org>  Wed, 14 Jun 2006 12:00:57 +0200
 +
 +apt (0.6.44.1-0.1) unstable; urgency=low
 +
 +  * Non-maintainer upload.
 +  * Don't give an error when parsing empty Packages/Sources files.
 +    (Closes: #366931, #367086, #370160)
 +
 + -- Steinar H. Gunderson <sesse@debian.org>  Fri,  9 Jun 2006 00:52:21 +0200
 +
  apt (0.6.44.1) unstable; urgency=low
  
 +  * apt-pkg/acquire-item.cc:
 +    - fix reversed logic of the "Acquire::PDiffs" option
    * merged from 
      http://www.perrier.eu.org/debian/packages/d-i/level4/apt-main:
      - po/LINGUAS: added "bg" Closes: #360262
      - po/gl.po: Galician translation update. Closes: #366849
      - po/hu.po: Hungarian translation update. Closes: #365448
      - po/cs.po: Czech translation updated. Closes: #367244
 +  * apt-pkg/contrib/sha256.cc:
 +    - applied patch to fix unaligned access problem. Closes: #367417
 +      (thanks to David Mosberger)
  
 - --
 + -- Michael Vogt <mvo@debian.org>  Tue, 16 May 2006 21:51:16 +0200
  
  apt (0.6.44) unstable; urgency=low
  
    * apt-pkg/acquire.cc: don't show ETA if it is 0 or absurdely large
 +  * apt-pkg/contrib/sha256.{cc,h},hashes.{cc,h}: support for sha256 
 +    (thanks to Anthony Towns)
 +  * ftparchive/cachedb.{cc,h},writer.{cc,h}: optimizations 
 +    (thanks to Anthony Towns)
 +  * apt pdiff support from experimental merged
 +  * apt-pkg/deb/dpkgpm.cc: wording fixes (thanks to Matt Zimmerman)
    * apt-pkg/deb/dpkgpm.cc: 
      - wording fixes (thanks to Matt Zimmerman)
 -    - fix error in dpkg interaction (closes: #364513, 
 -      thanks to Martin Dickopp)
 +    - fix error in dpkg interaction (closes: #364513, thanks to Martin Dickopp)
    * apt-pkg/tagfile.{cc,h}:
      - use MMap to read the entries (thanks to Zephaniah E. Hull for the
        patch) Closes: #350025
@@@ -852,7 -210,7 +855,7 @@@ apt (0.6.42) unstable; urgency=lo
    * cmdline/apt-cdrom.cc: 
      - fix some missing gettext() calls (closes: #334539)
    * doc/apt-cache.8.xml: fix typo (closes: #334714)
 -  
 +
   -- Michael Vogt <mvo@debian.org>  Wed, 19 Oct 2005 22:02:09 +0200
  
  apt (0.6.41) unstable; urgency=low
@@@ -952,7 -310,6 +955,7 @@@ apt (0.6.37) breezy; urgency=lo
    * Add Welsh translation from Dafydd Harries
      (daf@muse.19inch.net--2005/apt--main--0--patch-1)
    * Change debian/bugscript to use #!/bin/bash (Closes: #313402)
 +  * Fix a incorrect example in the man-page (closes: #282918)
  
   -- Matt Zimmerman <mdz@ubuntu.com>  Tue, 24 May 2005 14:38:25 -0700
  
@@@ -2800,3 -2157,4 +2803,3 @@@ apt (0.0.1) unstable; urgency=lo
    * Initial Release.
  
   -- Scott K. Ellis <scott@debian.org>  Tue, 31 Mar 1998 12:49:28 -0500
 -
index ba3ed3892d5a42ed293f5eafccf81db6ab910dd0,c5e8ba7013b3ad5d6cc1498c39359bf0137e2390..8893b5b74808aeb1b56c245f27865efdebfcb320
@@@ -24,16 -24,11 +24,16 @@@ AP
  {
    Architecture "i386";
    Build-Essential "build-essential";
 -  
 +
 +  NeverAutoRemove  { "linux-kernel.*";  };  // packages that should never
 +                                            // considered for autoRemove
 +
    // Options for apt-get
    Get 
    {
       Arch-Only "false";
 +     AutomaticRemove "false";       
 +     HideAutoRemove "false";
       Download-Only "false";
       Simulate "false";
       Assume-Yes "false";
       NoAct "false";
    };
  
+   Update
+   {
+      Pre-Invoke {"touch /var/lib/apt/pre-update-stamp"; };
+      Post-Invoke {"touch /var/lib/apt/post-update-stamp"; };
+   };
    Authentication
    {
       TrustCDROM "false";            // consider the CDROM always trusted
    Cache-Limit "4194304";
    Default-Release "";
  
 +  // consider Recommends, Suggests as important dependencies that should
 +  // be installed by default
 +  Install-Recommends "false";
 +  Install-Suggests "false";
 +
 +  // consider dependencies of packages in this section manual
 +  Never-MarkAuto-Sections {"metapackages"; "universe/metapackages"; };
  
    // Write progress messages on this fd (for stuff like base-config)
    Status-Fd "-1";
@@@ -116,8 -110,6 +122,8 @@@ Acquir
    Queue-Mode "host";       // host|access
    Retries "0";
    Source-Symlinks "true";
 +
 +  PDiffs "true";     // try to get the IndexFile diffs
    
    // HTTP method configuration
    http 
      Dl-Limit "7";        // 7Kb/sec maximum download rate
    };
  
 +  // HTTPS method configuration:
 +  // - uses the http proxy config 
 +  // - uses the http cache-control values
 +  // - uses the http Dl-Limit values
 +  https 
 +  {
 +      Verify-Peer "false";
 +      SslCert "/etc/apt/some.pem";
 +        CaPath  "/etc/ssl/certs";
 +        Verify-Host" "2";
 +  };
 +
    ftp
    {
      Proxy "ftp://127.0.0.1/";
@@@ -227,11 -207,6 +233,11 @@@ Dir "/
       apt-get "/usr/bin/apt-get";
       apt-cache "/usr/bin/apt-cache";
    };
 +
 +  // Location of the logfile
 +  Log "var/log/apt" {
 +      Terminal "term.log";
 +  };
  };
  
  // Things that effect the APT dselect method
@@@ -268,10 -243,6 +274,10 @@@ DPk
     // Control the size of the command line passed to dpkg.
     MaxBytes 1024;
     MaxArgs 350;
 +
 +   // controls if apt will apport on the first dpkg error or if it 
 +   // tries to install as many packages as possible
 +   StopOnError "true";
  }
  
  /* Options you can set to see some debugging text They correspond to names
@@@ -282,17 -253,14 +288,17 @@@ Debu
    pkgDepCache::AutoInstall "false"; // what packages apt install to satify dependencies
    pkgAcquire "false";
    pkgAcquire::Worker "false";
 +  pkgAcquire::Auth "false";
    pkgDPkgPM "false";
    pkgDPkgProgressReporting "false";
    pkgOrderList "false";
 -  
 +  pkgAutoRemove "false";   // show information about automatic removes
 +  BuildDeps "false";
    pkgInitialize "false";   // This one will dump the configuration space
    NoLocking "false";
    Acquire::Ftp "false";    // Show ftp command traffic
    Acquire::Http "false";   // Show http command traffic
 +  Acquire::Https "false";   // Show https debug
    Acquire::gpgv "false";   // Show the gpgv traffic
    aptcdrom "false";        // Show found package files
    IdentCdrom "false";