]> git.saurik.com Git - apt.git/commitdiff
* merged the apt-breaks-iwj branch
authorMichael Vogt <egon@bottom>
Thu, 14 Dec 2006 11:39:29 +0000 (12:39 +0100)
committerMichael Vogt <egon@bottom>
Thu, 14 Dec 2006 11:39:29 +0000 (12:39 +0100)
* pulled in the other remaining ubuntu changes

1  2 
apt-pkg/acquire-item.cc
apt-pkg/acquire-item.h
apt-pkg/algorithms.cc
apt-pkg/deb/debsrcrecords.h
apt-pkg/depcache.cc
apt-pkg/pkgcache.cc
apt-pkg/pkgcache.h
cmdline/apt-get.cc
debian/changelog
debian/rules

diff --combined apt-pkg/acquire-item.cc
index bcffa77f5fda92b4cd78c19d9a1694af6a8f4be5,94288a1321a3b5306a70bb6ceded729a1ce5e9f4..020047c06e1d66d438d7c8d62756713f7a096847
@@@ -24,8 -24,6 +24,8 @@@
  #include <apt-pkg/strutl.h>
  #include <apt-pkg/fileutl.h>
  #include <apt-pkg/md5.h>
 +#include <apt-pkg/sha1.h>
 +#include <apt-pkg/tagfile.h>
  
  #include <apti18n.h>
      
@@@ -33,7 -31,6 +33,7 @@@
  #include <unistd.h>
  #include <errno.h>
  #include <string>
 +#include <sstream>
  #include <stdio.h>
                                                                        /*}}}*/
  
@@@ -78,7 -75,7 +78,7 @@@ void pkgAcquire::Item::Failed(string Me
         Dequeue();
         return;
        }
-       
        Status = StatError;
        Dequeue();
     }   
@@@ -103,8 -100,7 +103,8 @@@ void pkgAcquire::Item::Done(string Mess
  {
     // We just downloaded something..
     string FileName = LookupTag(Message,"Filename");
 -   if (Complete == false && FileName == DestFile)
 +   // we only inform the Log class if it was actually not a local thing
 +   if (Complete == false && !Local && FileName == DestFile)
     {
        if (Owner->Log != 0)
         Owner->Log->Fetched(Size,atoi(LookupTag(Message,"Resume-Point","0").c_str()));
@@@ -135,433 -131,14 +135,433 @@@ void pkgAcquire::Item::Rename(string Fr
  }
                                                                        /*}}}*/
  
 +
 +// AcqDiffIndex::AcqDiffIndex - Constructor                   
 +// ---------------------------------------------------------------------
 +/* Get the DiffIndex file first and see if there are patches availabe 
 + * If so, create a pkgAcqIndexDiffs fetcher that will get and apply the
 + * patches. If anything goes wrong in that process, it will fall back to
 + * the original packages file
 + */
 +pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
 +                               string URI,string URIDesc,string ShortDesc,
 +                               string ExpectedMD5)
 +   : Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5), Description(URIDesc)
 +{
 +   
 +   Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
 +
 +   Desc.Description = URIDesc + "/DiffIndex";
 +   Desc.Owner = this;
 +   Desc.ShortDesc = ShortDesc;
 +   Desc.URI = URI + ".diff/Index";
 +
 +   DestFile = _config->FindDir("Dir::State::lists") + "partial/";
 +   DestFile += URItoFileName(URI) + string(".DiffIndex");
 +
 +   if(Debug)
 +      std::clog << "pkgAcqDiffIndex: " << Desc.URI << std::endl;
 +
 +   // look for the current package file
 +   CurrentPackagesFile = _config->FindDir("Dir::State::lists");
 +   CurrentPackagesFile += URItoFileName(RealURI);
 +
 +   // FIXME: this file:/ check is a hack to prevent fetching
 +   //        from local sources. this is really silly, and
 +   //        should be fixed cleanly as soon as possible
 +   if(!FileExists(CurrentPackagesFile) || 
 +      Desc.URI.substr(0,strlen("file:/")) == "file:/")
 +   {
 +      // we don't have a pkg file or we don't want to queue
 +      if(Debug)
 +       std::clog << "No index file, local or canceld by user" << std::endl;
 +      Failed("", NULL);
 +      return;
 +   }
 +
 +   if(Debug) 
 +      std::clog << "pkgAcqIndexDiffs::pkgAcqIndexDiffs(): " 
 +              << CurrentPackagesFile << std::endl;
 +   
 +   QueueURI(Desc);
 +
 +}
 +
 +// AcqIndex::Custom600Headers - Insert custom request headers         /*{{{*/
 +// ---------------------------------------------------------------------
 +/* The only header we use is the last-modified header. */
 +string pkgAcqDiffIndex::Custom600Headers()
 +{
 +   string Final = _config->FindDir("Dir::State::lists");
 +   Final += URItoFileName(RealURI) + string(".IndexDiff");
 +   
 +   if(Debug)
 +      std::clog << "Custom600Header-IMS: " << Final << std::endl;
 +
 +   struct stat Buf;
 +   if (stat(Final.c_str(),&Buf) != 0)
 +      return "\nIndex-File: true";
 +   
 +   return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 +}
 +
 +
 +bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)
 +{
 +   if(Debug)
 +      std::clog << "pkgAcqIndexDiffs::ParseIndexDiff() " << IndexDiffFile 
 +              << std::endl;
 +
 +   pkgTagSection Tags;
 +   string ServerSha1;
 +   vector<DiffInfo> available_patches;
 +   
 +   FileFd Fd(IndexDiffFile,FileFd::ReadOnly);
 +   pkgTagFile TF(&Fd);
 +   if (_error->PendingError() == true)
 +      return false;
 +
 +   if(TF.Step(Tags) == true)
 +   {
 +      string local_sha1;
 +      bool found = false;
 +      DiffInfo d;
 +      string size;
 +
 +      string tmp = Tags.FindS("SHA1-Current");
 +      std::stringstream ss(tmp);
 +      ss >> ServerSha1;
 +
 +      FileFd fd(CurrentPackagesFile, FileFd::ReadOnly);
 +      SHA1Summation SHA1;
 +      SHA1.AddFD(fd.Fd(), fd.Size());
 +      local_sha1 = string(SHA1.Result());
 +
 +      if(local_sha1 == ServerSha1) 
 +      {
 +       // we have the same sha1 as the server
 +       if(Debug)
 +          std::clog << "Package file is up-to-date" << std::endl;
 +       // set found to true, this will queue a pkgAcqIndexDiffs with
 +       // a empty availabe_patches
 +       found = true;
 +      } 
 +      else 
 +      {
 +       if(Debug)
 +          std::clog << "SHA1-Current: " << ServerSha1 << std::endl;
 +
 +       // check the historie and see what patches we need
 +       string history = Tags.FindS("SHA1-History");     
 +       std::stringstream hist(history);
 +       while(hist >> d.sha1 >> size >> d.file) 
 +       {
 +          d.size = atoi(size.c_str());
 +          // read until the first match is found
 +          if(d.sha1 == local_sha1) 
 +             found=true;
 +          // from that point on, we probably need all diffs
 +          if(found) 
 +          {
 +             if(Debug)
 +                std::clog << "Need to get diff: " << d.file << std::endl;
 +             available_patches.push_back(d);
 +          }
 +       }
 +      }
 +
 +      // we have something, queue the next diff
 +      if(found) 
 +      {
 +       // queue the diffs
 +      int last_space = Description.rfind(" ");
 +      if(last_space != string::npos)
 +        Description.erase(last_space, Description.size()-last_space);
 +       new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
 +                            ExpectedMD5, available_patches);
 +       Complete = false;
 +       Status = StatDone;
 +       Dequeue();
 +       return true;
 +      }
 +   }
 +
 +   // Nothing found, report and return false
 +   // Failing here is ok, if we return false later, the full
 +   // IndexFile is queued
 +   if(Debug)
 +      std::clog << "Can't find a patch in the index file" << std::endl;
 +   return false;
 +}
 +
 +void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 +{
 +   if(Debug)
 +      std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << std::endl
 +              << "Falling back to normal index file aquire" << std::endl;
 +
 +   new pkgAcqIndex(Owner, RealURI, Description, Desc.ShortDesc, 
 +                 ExpectedMD5);
 +
 +   Complete = false;
 +   Status = StatDone;
 +   Dequeue();
 +}
 +
 +void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,
 +                         pkgAcquire::MethodConfig *Cnf)
 +{
 +   if(Debug)
 +      std::clog << "pkgAcqDiffIndex::Done(): " << Desc.URI << std::endl;
 +
 +   Item::Done(Message,Size,Md5Hash,Cnf);
 +
 +   string FinalFile;
 +   FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(RealURI);
 +
 +   // sucess in downloading the index
 +   // rename the index
 +   FinalFile += string(".IndexDiff");
 +   if(Debug)
 +      std::clog << "Renaming: " << DestFile << " -> " << FinalFile 
 +              << std::endl;
 +   Rename(DestFile,FinalFile);
 +   chmod(FinalFile.c_str(),0644);
 +   DestFile = FinalFile;
 +
 +   if(!ParseDiffIndex(DestFile))
 +      return Failed("", NULL);
 +
 +   Complete = true;
 +   Status = StatDone;
 +   Dequeue();
 +   return;
 +}
 +
 +
 +
 +// AcqIndexDiffs::AcqIndexDiffs - Constructor                 
 +// ---------------------------------------------------------------------
 +/* The package diff is added to the queue. one object is constructed
 + * for each diff and the index
 + */
 +pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
 +                                 string URI,string URIDesc,string ShortDesc,
 +                                 string ExpectedMD5, vector<DiffInfo> diffs)
 +   : Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5), 
 +     available_patches(diffs)
 +{
 +   
 +   DestFile = _config->FindDir("Dir::State::lists") + "partial/";
 +   DestFile += URItoFileName(URI);
 +
 +   Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
 +
 +   Description = URIDesc;
 +   Desc.Owner = this;
 +   Desc.ShortDesc = ShortDesc;
 +
 +   if(available_patches.size() == 0) 
 +   {
 +      // we are done (yeah!)
 +      Finish(true);
 +   }
 +   else
 +   {
 +      // get the next diff
 +      State = StateFetchDiff;
 +      QueueNextDiff();
 +   }
 +}
 +
 +
 +void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 +{
 +   if(Debug)
 +      std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << std::endl
 +              << "Falling back to normal index file aquire" << std::endl;
 +   new pkgAcqIndex(Owner, RealURI, Description,Desc.ShortDesc, 
 +                 ExpectedMD5);
 +   Finish();
 +}
 +
 +
 +// helper that cleans the item out of the fetcher queue
 +void pkgAcqIndexDiffs::Finish(bool allDone)
 +{
 +   // we restore the original name, this is required, otherwise
 +   // the file will be cleaned
 +   if(allDone) 
 +   {
 +      DestFile = _config->FindDir("Dir::State::lists");
 +      DestFile += URItoFileName(RealURI);
 +
 +      // do the final md5sum checking
 +      MD5Summation sum;
 +      FileFd Fd(DestFile, FileFd::ReadOnly);
 +      sum.AddFD(Fd.Fd(), Fd.Size());
 +      Fd.Close();
 +      string MD5 = (string)sum.Result();
 +
 +      if (!ExpectedMD5.empty() && MD5 != ExpectedMD5)
 +      {
 +       Status = StatAuthError;
 +       ErrorText = _("MD5Sum mismatch");
 +       Rename(DestFile,DestFile + ".FAILED");
 +       Dequeue();
 +       return;
 +      }
 +
 +      // this is for the "real" finish
 +      Complete = true;
 +      Status = StatDone;
 +      Dequeue();
 +      if(Debug)
 +       std::clog << "\n\nallDone: " << DestFile << "\n" << std::endl;
 +      return;
 +   }
 +
 +   if(Debug)
 +      std::clog << "Finishing: " << Desc.URI << std::endl;
 +   Complete = false;
 +   Status = StatDone;
 +   Dequeue();
 +   return;
 +}
 +
 +
 +
 +bool pkgAcqIndexDiffs::QueueNextDiff()
 +{
 +
 +   // calc sha1 of the just patched file
 +   string FinalFile = _config->FindDir("Dir::State::lists");
 +   FinalFile += URItoFileName(RealURI);
 +
 +   FileFd fd(FinalFile, FileFd::ReadOnly);
 +   SHA1Summation SHA1;
 +   SHA1.AddFD(fd.Fd(), fd.Size());
 +   string local_sha1 = string(SHA1.Result());
 +   if(Debug)
 +      std::clog << "QueueNextDiff: " 
 +              << FinalFile << " (" << local_sha1 << ")"<<std::endl;
 +
 +   // remove all patches until the next matching patch is found
 +   // this requires the Index file to be ordered
 +   for(vector<DiffInfo>::iterator I=available_patches.begin();
 +       available_patches.size() > 0 && 
 +        I != available_patches.end() &&
 +        (*I).sha1 != local_sha1; 
 +       I++) 
 +   {
 +      available_patches.erase(I);
 +   }
 +
 +   // error checking and falling back if no patch was found
 +   if(available_patches.size() == 0) 
 +   { 
 +      Failed("", NULL);
 +      return false;
 +   }
 +
 +   // queue the right diff
 +   Desc.URI = string(RealURI) + ".diff/" + available_patches[0].file + ".gz";
 +   Desc.Description = Description + " " + available_patches[0].file + string(".pdiff");
 +
 +   DestFile = _config->FindDir("Dir::State::lists") + "partial/";
 +   DestFile += URItoFileName(RealURI + ".diff/" + available_patches[0].file);
 +
 +   if(Debug)
 +      std::clog << "pkgAcqIndexDiffs::QueueNextDiff(): " << Desc.URI << std::endl;
 +   
 +   QueueURI(Desc);
 +
 +   return true;
 +}
 +
 +
 +
 +void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,
 +                          pkgAcquire::MethodConfig *Cnf)
 +{
 +   if(Debug)
 +      std::clog << "pkgAcqIndexDiffs::Done(): " << Desc.URI << std::endl;
 +
 +   Item::Done(Message,Size,Md5Hash,Cnf);
 +
 +   string FinalFile;
 +   FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(RealURI);
 +
 +   // sucess in downloading a diff, enter ApplyDiff state
 +   if(State == StateFetchDiff) 
 +   {
 +
 +      if(Debug)
 +       std::clog << "Sending to gzip method: " << FinalFile << std::endl;
 +
 +      string FileName = LookupTag(Message,"Filename");
 +      State = StateUnzipDiff;
 +      Local = true;
 +      Desc.URI = "gzip:" + FileName;
 +      DestFile += ".decomp";
 +      QueueURI(Desc);
 +      Mode = "gzip";
 +      return;
 +   } 
 +
 +   // sucess in downloading a diff, enter ApplyDiff state
 +   if(State == StateUnzipDiff) 
 +   {
 +
 +      // rred excepts the patch as $FinalFile.ed
 +      Rename(DestFile,FinalFile+".ed");
 +
 +      if(Debug)
 +       std::clog << "Sending to rred method: " << FinalFile << std::endl;
 +
 +      State = StateApplyDiff;
 +      Local = true;
 +      Desc.URI = "rred:" + FinalFile;
 +      QueueURI(Desc);
 +      Mode = "rred";
 +      return;
 +   } 
 +
 +
 +   // success in download/apply a diff, queue next (if needed)
 +   if(State == StateApplyDiff)
 +   {
 +      // remove the just applied patch
 +      available_patches.erase(available_patches.begin());
 +
 +      // move into place
 +      if(Debug) 
 +      {
 +       std::clog << "Moving patched file in place: " << std::endl
 +                 << DestFile << " -> " << FinalFile << std::endl;
 +      }
 +      Rename(DestFile,FinalFile);
 +      chmod(FinalFile.c_str(),0644);
 +
 +      // see if there is more to download
 +      if(available_patches.size() > 0) {
 +       new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
 +                            ExpectedMD5, available_patches);
 +       return Finish();
 +      } else 
 +       return Finish(true);
 +   }
 +}
 +
 +
  // AcqIndex::AcqIndex - Constructor                                   /*{{{*/
  // ---------------------------------------------------------------------
  /* The package file is added to the queue and a second class is 
     instantiated to fetch the revision file */   
  pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
                         string URI,string URIDesc,string ShortDesc,
 -                       string ExpectedMD5, string comprExt) :
 -   Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5)
 +                       string ExpectedMD5, string comprExt)
 +   Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5)
  {
     Decompression = false;
     Erase = false;
@@@ -773,8 -350,9 +773,9 @@@ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquir
     DestFile = _config->FindDir("Dir::State::lists") + "partial/";
     DestFile += URItoFileName(URI);
  
-    // remove any partial downloaded sig-file. it may confuse proxies
-    // and is too small to warrant a partial download anyway
+    // remove any partial downloaded sig-file in partial/. 
+    // it may confuse proxies and is too small to warrant a 
+    // partial download anyway
     unlink(DestFile.c_str());
  
     // Create the item
@@@ -841,17 -419,22 +842,22 @@@ void pkgAcqMetaSig::Done(string Message
                                                                        /*}}}*/
  void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
  {
+    string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
  
     // if we get a network error we fail gracefully
-    if(LookupTag(Message,"FailReason") == "Timeout" || 
-       LookupTag(Message,"FailReason") == "TmpResolveFailure" ||
-       LookupTag(Message,"FailReason") == "ConnectionRefused") {
+    if(Status == StatTransientNetworkError)
+    {
        Item::Failed(Message,Cnf);
+       // move the sigfile back on network failures (and re-authenticated?)
+       if(FileExists(DestFile))
+        Rename(DestFile,Final);
+       // set the status back to , Item::Failed likes to reset it
+       Status = pkgAcquire::Item::StatTransientNetworkError;
        return;
     }
  
     // Delete any existing sigfile when the acquire failed
-    string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
     unlink(Final.c_str());
  
     // queue a pkgAcqMetaIndex with no sigfile
@@@ -984,7 -567,6 +990,7 @@@ void pkgAcqMetaIndex::RetrievalDone(str
        // Move it into position
        Rename(DestFile,FinalFile);
     }
 +   chmod(FinalFile.c_str(),0644);
     DestFile = FinalFile;
  }
  
@@@ -1054,14 -636,9 +1060,14 @@@ void pkgAcqMetaIndex::QueueIndexes(boo
           }
        }
        
 -      // Queue Packages file
 -      new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
 -                      (*Target)->ShortDesc, ExpectedIndexMD5);
 +      // Queue Packages file (either diff or full packages files, depending
 +      // on the users option)
 +      if(_config->FindB("Acquire::PDiffs",true) == true) 
 +       new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description,
 +                           (*Target)->ShortDesc, ExpectedIndexMD5);
 +      else 
 +       new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
 +                          (*Target)->ShortDesc, ExpectedIndexMD5);
     }
  }
  
diff --combined apt-pkg/acquire-item.h
index cc46282d66c1c05ab2d3293f0b34d25849930620,3a0a690e1e86fe3c255619b82094b5230b08ebed..f5272ed8623f4562d521417f0f55b8a2e77d9371
  #include <apt-pkg/pkgrecords.h>
  #include <apt-pkg/indexrecords.h>
  
 -#ifdef __GNUG__
 -#pragma interface "apt-pkg/acquire-item.h"
 -#endif 
  
 -// Item to acquire
 +/** \addtogroup acquire
 + *  @{
 + *
 + *  \file acquire-item.h
 + */
 +
 +/** \brief Represents the process by which a pkgAcquire object should
 + *  retrieve a file or a collection of files.
 + *
 + *  By convention, Item subclasses should insert themselves into the
 + *  acquire queue when they are created by calling QueueURI(), and
 + *  remove themselves by calling Dequeue() when either Done() or
 + *  Failed() is invoked.  Item objects are also responsible for
 + *  notifying the download progress indicator (accessible via
 + *  #Owner->Log) of their status.
 + *
 + *  \see pkgAcquire
 + */
  class pkgAcquire::Item
  {  
     protected:
     
 -   // Some private helper methods for registering URIs
 +   /** \brief The acquire object with which this item is associated. */
     pkgAcquire *Owner;
 +
 +   /** \brief Insert this item into its owner's queue.
 +    *
 +    *  \param ItemDesc Metadata about this item (its URI and
 +    *  description).
 +    */
     inline void QueueURI(ItemDesc &Item)
                   {Owner->Enqueue(Item);};
 +
 +   /** \brief Remove this item from its owner's queue. */
     inline void Dequeue() {Owner->Dequeue(this);};
     
 -   // Safe rename function with timestamp preservation
 +   /** \brief Rename a file without modifying its timestamp.
 +    *
 +    *  Many item methods call this as their final action.
 +    *
 +    *  \param From The file to be renamed.
 +    *
 +    *  \param To The new name of #From.  If #To exists it will be
 +    *  overwritten.
 +    */
     void Rename(string From,string To);
     
     public:
  
 -   // State of the item
 -   enum {StatIdle, StatFetching, StatDone, StatError, 
 -       StatAuthError, StatTransientNetworkError} Status;
 +   /** \brief The current status of this item. */
 +   enum ItemState
 +     {
 +       /** \brief The item is waiting to be downloaded. */
 +       StatIdle,
 +
 +       /** \brief The item is currently being downloaded. */
 +       StatFetching,
 +
 +       /** \brief The item has been successfully downloaded. */
 +       StatDone,
 +
 +       /** \brief An error was encountered while downloading this
 +      *  item.
 +      */
 +       StatError,
 +
 +       /** \brief The item was downloaded but its authenticity could
 +      *  not be verified.
 +      */
-        StatAuthError
++       StatAuthError,
++
++       /** \brief The item was could not be downloaded because of 
++      *  a transient network error (e.g. network down)
++      */
++       StatTransientNetworkError
 +     } Status;
 +
 +   /** \brief Contains a textual description of the error encountered
 +    *  if #Status is #StatError or #StatAuthError.
 +    */
     string ErrorText;
 +
 +   /** \brief The size of the object to fetch. */
     unsigned long FileSize;
 -   unsigned long PartialSize;   
 +
 +   /** \brief How much of the object was already fetched. */
 +   unsigned long PartialSize;
 +
 +   /** \brief If not \b NULL, contains the name of a subprocess that
 +    *  is operating on this object (for instance, "gzip" or "gpgv").
 +    */
     const char *Mode;
 +
 +   /** \brief A client-supplied unique identifier.
 +    * 
 +    *  This field is initalized to 0; it is meant to be filled in by
 +    *  clients that wish to use it to uniquely identify items.
 +    *
 +    *  \todo it's unused in apt itself
 +    */
     unsigned long ID;
 +
 +   /** \brief If \b true, the entire object has been successfully fetched.
 +    *
 +    *  Subclasses should set this to \b true when appropriate.
 +    */
     bool Complete;
 +
 +   /** \brief If \b true, the URI of this object is "local".
 +    *
 +    *  The only effect of this field is to exclude the object from the
 +    *  download progress indicator's overall statistics.
 +    */
     bool Local;
  
 -   // Number of queues we are inserted into
 +   /** \brief The number of fetch queues into which this item has been
 +    *  inserted.
 +    *
 +    *  There is one queue for each source from which an item could be
 +    *  downloaded.
 +    *
 +    *  \sa pkgAcquire
 +    */
     unsigned int QueueCounter;
     
 -   // File to write the fetch into
 +   /** \brief The name of the file into which the retrieved object
 +    *  will be written.
 +    */
     string DestFile;
  
 -   // Action members invoked by the worker
 +   /** \brief Invoked by the acquire worker when the object couldn't
 +    *  be fetched.
 +    *
 +    *  This is a branch of the continuation of the fetch process.
 +    *
 +    *  \param Message An RFC822-formatted message from the acquire
 +    *  method describing what went wrong.  Use LookupTag() to parse
 +    *  it.
 +    *
 +    *  \param Cnf The method via which the worker tried to fetch this object.
 +    *
 +    *  \sa pkgAcqMethod
 +    */
     virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
 +
 +   /** \brief Invoked by the acquire worker when the object was
 +    *  fetched successfully.
 +    *
 +    *  Note that the object might \e not have been written to
 +    *  DestFile; check for the presence of an Alt-Filename entry in
 +    *  Message to find the file to which it was really written.
 +    *
 +    *  Done is often used to switch from one stage of the processing
 +    *  to the next (e.g. fetching, unpacking, copying).  It is one
 +    *  branch of the continuation of the fetch process.
 +    *
 +    *  \param Message Data from the acquire method.  Use LookupTag()
 +    *  to parse it.
 +    *  \param Size The size of the object that was fetched.
 +    *  \param Md5Hash The MD5Sum of the object that was fetched.
 +    *  \param Cnf The method via which the object was fetched.
 +    *
 +    *  \sa pkgAcqMethod
 +    */
     virtual void Done(string Message,unsigned long Size,string Md5Hash,
                     pkgAcquire::MethodConfig *Cnf);
 +
 +   /** \brief Invoked when the worker starts to fetch this object.
 +    *
 +    *  \param Message RFC822-formatted data from the worker process.
 +    *  Use LookupTag() to parse it.
 +    *
 +    *  \param Size The size of the object being fetched.
 +    *
 +    *  \sa pkgAcqMethod
 +    */
     virtual void Start(string Message,unsigned long Size);
 +
 +   /** \brief Custom headers to be sent to the fetch process.
 +    *
 +    *  \return a string containing RFC822-style headers that are to be
 +    *  inserted into the 600 URI Acquire message sent to the fetch
 +    *  subprocess.  The headers are inserted after a newline-less
 +    *  line, so they should (if nonempty) have a leading newline and
 +    *  no trailing newline.
 +    */
     virtual string Custom600Headers() {return string();};
 +
 +   /** \brief A "descriptive" URI-like string.
 +    *
 +    *  \return a URI that should be used to describe what is being fetched.
 +    */
     virtual string DescURI() = 0;
 +   /** \brief Short item description.
 +    *
 +    *  \return a brief description of the object being fetched.
 +    */
     virtual string ShortDesc() {return DescURI();}
 +
 +   /** \brief Invoked by the worker when the download is completely done. */
     virtual void Finished() {};
     
 -   // Inquire functions
 +   /** \brief MD5Sum.
 +    *
 +    *  \return the MD5Sum of this object, if applicable; otherwise, an
 +    *  empty string.
 +    */
     virtual string MD5Sum() {return string();};
 +
 +   /** \return the acquire process with which this item is associated. */
     pkgAcquire *GetOwner() {return Owner;};
 +
 +   /** \return \b true if this object is being fetched from a trusted source. */
     virtual bool IsTrusted() {return false;};
 -   
 +
 +   /** \brief Initialize an item.
 +    *
 +    *  Adds the item to the list of items known to the acquire
 +    *  process, but does not place it into any fetch queues (you must
 +    *  manually invoke QueueURI() to do so).
 +    *
 +    *  Initializes all fields of the item other than Owner to 0,
 +    *  false, or the empty string.
 +    *
 +    *  \param Owner The new owner of this item.
 +    */
     Item(pkgAcquire *Owner);
 +
 +   /** \brief Remove this item from its owner's queue by invoking
 +    *  pkgAcquire::Remove.
 +    */
     virtual ~Item();
  };
  
 -// Item class for index files
 -class pkgAcqIndex : public pkgAcquire::Item
 +/** \brief Information about an index patch (aka diff). */
 +struct DiffInfo {
 +   /** The filename of the diff. */
 +   string file;
 +
 +   /** The sha1 hash of the diff. */
 +   string sha1;
 +
 +   /** The size of the diff. */
 +   unsigned long size;
 +};
 +
 +/** \brief An item that is responsible for fetching an index file of
 + *  package list diffs and starting the package list's download.
 + *
 + *  This item downloads the Index file and parses it, then enqueues
 + *  additional downloads of either the individual patches (using
 + *  pkgAcqIndexDiffs) or the entire Packages file (using pkgAcqIndex).
 + *
 + *  \sa pkgAcqIndexDiffs, pkgAcqIndex
 + */
 +class pkgAcqDiffIndex : public pkgAcquire::Item
  {
 + protected:
 +   /** \brief If \b true, debugging information will be written to std::clog. */
 +   bool Debug;
 +
 +   /** \brief The item that is currently being downloaded. */
 +   pkgAcquire::ItemDesc Desc;
 +
 +   /** \brief The URI of the index file to recreate at our end (either
 +    *  by downloading it or by applying partial patches).
 +    */
 +   string RealURI;
 +
 +   /** \brief The MD5Sum that the real index file should have after
 +    *  all patches have been applied.
 +    */
 +   string ExpectedMD5;
 +
 +   /** \brief The index file which will be patched to generate the new
 +    *  file.
 +    */
 +   string CurrentPackagesFile;
 +
 +   /** \brief A description of the Packages file (stored in
 +    *  pkgAcquire::ItemDesc::Description).
 +    */
 +   string Description;
 +
 + public:
 +   // Specialized action members
 +   virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
 +   virtual void Done(string Message,unsigned long Size,string Md5Hash,
 +                   pkgAcquire::MethodConfig *Cnf);
 +   virtual string DescURI() {return RealURI + "Index";};
 +   virtual string Custom600Headers();
 +
 +   /** \brief Parse the Index file for a set of Packages diffs.
 +    *
 +    *  Parses the Index file and creates additional download items as
 +    *  necessary.
 +    *
 +    *  \param IndexDiffFile The name of the Index file.
 +    *
 +    *  \return \b true if the Index file was successfully parsed, \b
 +    *  false otherwise.
 +    */
 +   bool ParseDiffIndex(string IndexDiffFile);
 +   
 +
 +   /** \brief Create a new pkgAcqDiffIndex.
 +    *
 +    *  \param Owner The Acquire object that owns this item.
 +    *
 +    *  \param URI The URI of the list file to download.
 +    *
 +    *  \param URIDesc A long description of the list file to download.
 +    *
 +    *  \param ShortDesc A short description of the list file to download.
 +    *
 +    *  \param ExpectedMD5 The list file's MD5 signature.
 +    */
 +   pkgAcqDiffIndex(pkgAcquire *Owner,string URI,string URIDesc,
 +                 string ShortDesc, string ExpectedMD5);
 +};
 +
 +/** \brief An item that is responsible for fetching all the patches
 + *  that need to be applied to a given package index file.
 + *
 + *  After downloading and applying a single patch, this item will
 + *  enqueue a new pkgAcqIndexDiffs to download and apply the remaining
 + *  patches.  If no patch can be found that applies to an intermediate
 + *  file or if one of the patches cannot be downloaded, falls back to
 + *  downloading the entire package index file using pkgAcqIndex.
 + *
 + *  \sa pkgAcqDiffIndex, pkgAcqIndex
 + */
 +class pkgAcqIndexDiffs : public pkgAcquire::Item
 +{
 +   private:
 +
 +   /** \brief Queue up the next diff download.
 +    *
 +    *  Search for the next available diff that applies to the file
 +    *  that currently exists on disk, and enqueue it by calling
 +    *  QueueURI().
 +    *
 +    *  \return \b true if an applicable diff was found, \b false
 +    *  otherwise.
 +    */
 +   bool QueueNextDiff();
 +
 +   /** \brief Handle tasks that must be performed after the item
 +    *  finishes downloading.
 +    *
 +    *  Dequeues the item and checks the resulting file's md5sum
 +    *  against ExpectedMD5 after the last patch was applied.
 +    *  There is no need to check the md5/sha1 after a "normal" 
 +    *  patch because QueueNextDiff() will check the sha1 later.
 +    *
 +    *  \param allDone If \b true, the file was entirely reconstructed,
 +    *  and its md5sum is verified. 
 +    */
 +   void Finish(bool allDone=false);
 +
     protected:
 +
 +   /** \brief If \b true, debugging output will be written to
 +    *  std::clog.
 +    */
 +   bool Debug;
 +
 +   /** \brief A description of the item that is currently being
 +    *  downloaded.
 +    */
 +   pkgAcquire::ItemDesc Desc;
 +
 +   /** \brief The URI of the package index file that is being
 +    *  reconstructed.
 +    */
 +   string RealURI;
 +
 +   /** \brief The MD5Sum of the package index file that is being
 +    *  reconstructed.
 +    */
 +   string ExpectedMD5;
 +
 +   /** A description of the file being downloaded. */
 +   string Description;
 +
 +   /** The patches that remain to be downloaded, including the patch
 +    *  being downloaded right now.  This list should be ordered so
 +    *  that each diff appears before any diff that depends on it.
 +    *
 +    *  \todo These are indexed by sha1sum; why not use some sort of
 +    *  dictionary instead of relying on ordering and stripping them
 +    *  off the front?
 +    */
 +   vector<DiffInfo> available_patches;
 +   /** The current status of this patch. */
 +   enum DiffState
 +     {
 +      /** \brief The diff is in an unknown state. */
 +       StateFetchUnkown,
 +
 +       /** \brief The diff is currently being fetched. */
 +       StateFetchDiff,
 +       
 +       /** \brief The diff is currently being uncompressed. */
 +       StateUnzipDiff,
 +
 +       /** \brief The diff is currently being applied. */
 +       StateApplyDiff
 +   } State;
 +
 +   public:
     
 +   /** \brief Called when the patch file failed to be downloaded.
 +    *
 +    *  This method will fall back to downloading the whole index file
 +    *  outright; its arguments are ignored.
 +    */
 +   virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
 +
 +   virtual void Done(string Message,unsigned long Size,string Md5Hash,
 +                   pkgAcquire::MethodConfig *Cnf);
 +   virtual string DescURI() {return RealURI + "Index";};
 +
 +   /** \brief Create an index diff item.
 +    *
 +    *  After filling in its basic fields, this invokes Finish(true) if
 +    *  #diffs is empty, or QueueNextDiff() otherwise.
 +    *
 +    *  \param Owner The pkgAcquire object that owns this item.
 +    *
 +    *  \param URI The URI of the package index file being
 +    *  reconstructed.
 +    *
 +    *  \param URIDesc A long description of this item.
 +    *
 +    *  \param ShortDesc A brief description of this item.
 +    *
 +    *  \param ExpectedMD5 The expected md5sum of the completely
 +    *  reconstructed package index file; the index file will be tested
 +    *  against this value when it is entirely reconstructed.
 +    *
 +    *  \param diffs The remaining diffs from the index of diffs.  They
 +    *  should be ordered so that each diff appears before any diff
 +    *  that depends on it.
 +    */
 +   pkgAcqIndexDiffs(pkgAcquire *Owner,string URI,string URIDesc,
 +                  string ShortDesc, string ExpectedMD5,
 +                  vector<DiffInfo> diffs=vector<DiffInfo>());
 +};
 +
 +/** \brief An acquire item that is responsible for fetching an index
 + *  file (e.g., Packages or Sources).
 + *
 + *  \sa pkgAcqDiffIndex, pkgAcqIndexDiffs, pkgAcqIndexTrans
 + *
 + *  \todo Why does pkgAcqIndex have protected members?
 + */
 +class pkgAcqIndex : public pkgAcquire::Item
 +{
 +   protected:
 +
 +   /** \brief If \b true, the index file has been decompressed. */
     bool Decompression;
 +
 +   /** \brief If \b true, the partially downloaded file will be
 +    *  removed when the download completes.
 +    */
     bool Erase;
 +
 +   /** \brief The download request that is currently being
 +    *   processed.
 +    */
     pkgAcquire::ItemDesc Desc;
 +
 +   /** \brief The object that is actually being fetched (minus any
 +    *  compression-related extensions).
 +    */
     string RealURI;
 +
 +   /** \brief The expected md5sum of the decompressed index file. */
     string ExpectedMD5;
 +
 +   /** \brief The compression-related file extension that is being
 +    *  added to the downloaded file (e.g., ".gz" or ".bz2").
 +    */
     string CompressionExtension;
  
     public:
     virtual string Custom600Headers();
     virtual string DescURI() {return RealURI + CompressionExtension;};
  
 +   /** \brief Create a pkgAcqIndex.
 +    *
 +    *  \param Owner The pkgAcquire object with which this item is
 +    *  associated.
 +    *
 +    *  \param URI The URI of the index file that is to be downloaded.
 +    *
 +    *  \param URIDesc A "URI-style" description of this index file.
 +    *
 +    *  \param ShortDesc A brief description of this index file.
 +    *
 +    *  \param ExpectedMD5 The expected md5sum of this index file.
 +    *
 +    *  \param compressExt The compression-related extension with which
 +    *  this index file should be downloaded, or "" to autodetect
 +    *  (".bz2" is used if bzip2 is installed, ".gz" otherwise).
 +    */
     pkgAcqIndex(pkgAcquire *Owner,string URI,string URIDesc,
 -             string ShortDesct, string ExpectedMD5, string compressExt="");
 +             string ShortDesc, string ExpectedMD5, string compressExt="");
  };
  
 -// Item class for translated package index files
 +/** \brief An acquire item that is responsible for fetching a
 + *  translated index file.
 + *
 + *  The only difference from pkgAcqIndex is that transient failures
 + *  are suppressed: no error occurs if the translated index file is
 + *  missing.
 + */
  class pkgAcqIndexTrans : public pkgAcqIndex
  {
     public:
    
     virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
 +
 +   /** \brief Create a pkgAcqIndexTrans.
 +    *
 +    *  \param Owner The pkgAcquire object with which this item is
 +    *  associated.
 +    *
 +    *  \param URI The URI of the index file that is to be downloaded.
 +    *
 +    *  \param URIDesc A "URI-style" description of this index file.
 +    *
 +    *  \param ShortDesc A brief description of this index file.
 +    *
 +    *  \param ExpectedMD5 The expected md5sum of this index file.
 +    *
 +    *  \param compressExt The compression-related extension with which
 +    *  this index file should be downloaded, or "" to autodetect
 +    *  (".bz2" is used if bzip2 is installed, ".gz" otherwise).
 +    */
     pkgAcqIndexTrans(pkgAcquire *Owner,string URI,string URIDesc,
 -                  string ShortDesct);
 +                  string ShortDesc);
  };
  
 +/** \brief Information about an index file. */
  struct IndexTarget
  {
 +   /** \brief A URI from which the index file can be downloaded. */
     string URI;
 +
 +   /** \brief A description of the index file. */
     string Description;
 +
 +   /** \brief A shorter description of the index file. */
     string ShortDesc;
 +
 +   /** \brief The key by which this index file should be
 +    *  looked up within the meta signature file.
 +    */
     string MetaKey;
  };
  
 -// Item class for index signatures
 +/** \brief An acquire item that downloads the detached signature
 + *  of a meta-index (Release) file, then queues up the release
 + *  file itself.
 + *
 + *  \todo Why protected members?
 + *
 + *  \sa pkgAcqMetaIndex
 + */
  class pkgAcqMetaSig : public pkgAcquire::Item
  {
     protected:
 -   
 +   /** \brief The fetch request that is currently being processed. */
     pkgAcquire::ItemDesc Desc;
 -   string RealURI,MetaIndexURI,MetaIndexURIDesc,MetaIndexShortDesc;
 +
 +   /** \brief The URI of the signature file.  Unlike Desc.URI, this is
 +    *  never modified; it is used to determine the file that is being
 +    *  downloaded.
 +    */
 +   string RealURI;
 +
 +   /** \brief The URI of the meta-index file to be fetched after the signature. */
 +   string MetaIndexURI;
 +
 +   /** \brief A "URI-style" description of the meta-index file to be
 +    *  fetched after the signature.
 +    */
 +   string MetaIndexURIDesc;
 +
 +   /** \brief A brief description of the meta-index file to be fetched
 +    *  after the signature.
 +    */
 +   string MetaIndexShortDesc;
 +
 +   /** \brief A package-system-specific parser for the meta-index file. */
     indexRecords* MetaIndexParser;
 +
 +   /** \brief The index files which should be looked up in the meta-index
 +    *  and then downloaded.
 +    *
 +    *  \todo Why a list of pointers instead of a list of structs?
 +    */
     const vector<struct IndexTarget*>* IndexTargets;
  
     public:
     virtual string Custom600Headers();
     virtual string DescURI() {return RealURI; };
  
 +   /** \brief Create a new pkgAcqMetaSig. */
     pkgAcqMetaSig(pkgAcquire *Owner,string URI,string URIDesc, string ShortDesc,
                 string MetaIndexURI, string MetaIndexURIDesc, string MetaIndexShortDesc,
                 const vector<struct IndexTarget*>* IndexTargets,
                 indexRecords* MetaIndexParser);
  };
  
 -// Item class for index signatures
 +/** \brief An item that is responsible for downloading the meta-index
 + *  file (i.e., Release) itself and verifying its signature.
 + *
 + *  Once the download and verification are complete, the downloads of
 + *  the individual index files are queued up using pkgAcqDiffIndex.
 + *  If the meta-index file had a valid signature, the expected md5sums
 + *  of the index files will be the md5sums listed in the meta-index;
 + *  otherwise, the expected md5sums will be "" (causing the
 + *  authentication of the index files to be bypassed).
 + */
  class pkgAcqMetaIndex : public pkgAcquire::Item
  {
     protected:
 -   
 +   /** \brief The fetch command that is currently being processed. */
     pkgAcquire::ItemDesc Desc;
 -   string RealURI; // FIXME: is this redundant w/ Desc.URI?
 +
 +   /** \brief The URI that is actually being downloaded; never
 +    *  modified by pkgAcqMetaIndex.
 +    */
 +   string RealURI;
 +
 +   /** \brief The file in which the signature for this index was stored.
 +    *
 +    *  If empty, the signature and the md5sums of the individual
 +    *  indices will not be checked.
 +    */
     string SigFile;
 +
 +   /** \brief The index files to download. */
     const vector<struct IndexTarget*>* IndexTargets;
 +
 +   /** \brief The parser for the meta-index file. */
     indexRecords* MetaIndexParser;
 +
 +   /** \brief If \b true, the index's signature is currently being verified.
 +    */
     bool AuthPass;
     // required to deal gracefully with problems caused by incorrect ims hits
     bool IMSHit; 
  
 +   /** \brief Check that the release file is a release file for the
 +    *  correct distribution.
 +    *
 +    *  \return \b true if no fatal errors were encountered.
 +    */
     bool VerifyVendor(string Message);
 +
 +   /** \brief Called when a file is finished being retrieved.
 +    *
 +    *  If the file was not downloaded to DestFile, a copy process is
 +    *  set up to copy it to DestFile; otherwise, Complete is set to \b
 +    *  true and the file is moved to its final location.
 +    *
 +    *  \param Message The message block received from the fetch
 +    *  subprocess.
 +    */
     void RetrievalDone(string Message);
 +
 +   /** \brief Called when authentication succeeded.
 +    *
 +    *  Sanity-checks the authenticated file, queues up the individual
 +    *  index files for download, and saves the signature in the lists
 +    *  directory next to the authenticated list file.
 +    *
 +    *  \param Message The message block received from the fetch
 +    *  subprocess.
 +    */
     void AuthDone(string Message);
 +
 +   /** \brief Starts downloading the individual index files.
 +    *
 +    *  \param verify If \b true, only indices whose expected md5sum
 +    *  can be determined from the meta-index will be downloaded, and
 +    *  the md5sums of indices will be checked (reporting
 +    *  #StatAuthError if there is a mismatch).  If verify is \b false,
 +    *  no md5sum checking will be performed.
 +    */
     void QueueIndexes(bool verify);
     
     public:
     virtual string Custom600Headers();
     virtual string DescURI() {return RealURI; };
  
 +   /** \brief Create a new pkgAcqMetaIndex. */
     pkgAcqMetaIndex(pkgAcquire *Owner,
                   string URI,string URIDesc, string ShortDesc,
                   string SigFile,
                   indexRecords* MetaIndexParser);
  };
  
 -// Item class for archive files
 +/** \brief An item that is responsible for fetching a package file.
 + *
 + *  If the package file already exists in the cache, nothing will be
 + *  done.
 + */
  class pkgAcqArchive : public pkgAcquire::Item
  {
     protected:
 -   
 -   // State information for the retry mechanism
 +   /** \brief The package version being fetched. */
     pkgCache::VerIterator Version;
 +
 +   /** \brief The fetch command that is currently being processed. */
     pkgAcquire::ItemDesc Desc;
 +
 +   /** \brief The list of sources from which to pick archives to
 +    *  download this package from.
 +    */
     pkgSourceList *Sources;
 +
 +   /** \brief A package records object, used to look up the file
 +    *  corresponding to each version of the package.
 +    */
     pkgRecords *Recs;
 +
 +   /** \brief The md5sum of this package. */
     string MD5;
 +
 +   /** \brief A location in which the actual filename of the package
 +    *  should be stored.
 +    */
     string &StoreFilename;
 +
 +   /** \brief The next file for this version to try to download. */
     pkgCache::VerFileIterator Vf;
 +
 +   /** \brief How many (more) times to try to find a new source from
 +    *  which to download this package version if it fails.
 +    *
 +    *  Set from Acquire::Retries.
 +    */
     unsigned int Retries;
 +
 +   /** \brief \b true if this version file is being downloaded from a
 +    *  trusted source.
 +    */
     bool Trusted; 
  
 -   // Queue the next available file for download.
 +   /** \brief Queue up the next available file for this version. */
     bool QueueNext();
     
     public:
     
 -   // Specialized action members
     virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
     virtual void Done(string Message,unsigned long Size,string Md5Hash,
                     pkgAcquire::MethodConfig *Cnf);
     virtual string DescURI() {return Desc.URI;};
     virtual string ShortDesc() {return Desc.ShortDesc;};
     virtual void Finished();
 +
     virtual bool IsTrusted();
     
 +   /** \brief Create a new pkgAcqArchive.
 +    *
 +    *  \param Owner The pkgAcquire object with which this item is
 +    *  associated.
 +    *
 +    *  \param Sources The sources from which to download version
 +    *  files.
 +    *
 +    *  \param Recs A package records object, used to look up the file
 +    *  corresponding to each version of the package.
 +    *
 +    *  \param Version The package version to download.
 +    *
 +    *  \param StoreFilename A location in which the actual filename of
 +    *  the package should be stored.  It will be set to a guessed
 +    *  basename in the constructor, and filled in with a fully
 +    *  qualified filename once the download finishes.
 +    */
     pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources,
                 pkgRecords *Recs,pkgCache::VerIterator const &Version,
                 string &StoreFilename);
  };
  
 -// Fetch a generic file to the current directory
 +/** \brief Retrieve an arbitrary file to the current directory.
 + *
 + *  The file is retrieved even if it is accessed via a URL type that
 + *  normally is a NOP, such as "file".  If the download fails, the
 + *  partial file is renamed to get a ".FAILED" extension.
 + */
  class pkgAcqFile : public pkgAcquire::Item
  {
 +   /** \brief The currently active download process. */
     pkgAcquire::ItemDesc Desc;
 +
 +   /** \brief The md5sum of the file to download, if it is known. */
     string Md5Hash;
 +
 +   /** \brief How many times to retry the download, set from
 +    *  Acquire::Retries.
 +    */
     unsigned int Retries;
     
     public:
     virtual string MD5Sum() {return Md5Hash;};
     virtual string DescURI() {return Desc.URI;};
  
 -   // If DestFilename is empty, download to DestDir/<basename> if
 -   // DestDir is non-empty, $CWD/<basename> otherwise.  If
 -   // DestFilename is NOT empty, DestDir is ignored and DestFilename
 -   // is the absolute name to which the file should be downloaded.
 +   /** \brief Create a new pkgAcqFile object.
 +    *
 +    *  \param Owner The pkgAcquire object with which this object is
 +    *  associated.
 +    *
 +    *  \param URI The URI to download.
 +    *
 +    *  \param MD5 The md5sum of the file to download, if it is known;
 +    *  otherwise "".
 +    *
 +    *  \param Size The size of the file to download, if it is known;
 +    *  otherwise 0.
 +    *
 +    *  \param Desc A description of the file being downloaded.
 +    *
 +    *  \param ShortDesc A brief description of the file being
 +    *  downloaded.
 +    *
 +    *  \param DestDir The directory the file should be downloaded into.
 +    *
 +    *  \param DestFilename The filename+path the file is downloaded to.
 +    *
 +    *
 +    * If DestFilename is empty, download to DestDir/<basename> if
 +    * DestDir is non-empty, $CWD/<basename> otherwise.  If
 +    * DestFilename is NOT empty, DestDir is ignored and DestFilename
 +    * is the absolute name to which the file should be downloaded.
 +    */
 +
     pkgAcqFile(pkgAcquire *Owner, string URI, string MD5, unsigned long Size,
              string Desc, string ShortDesc,
              const string &DestDir="", const string &DestFilename="");
  };
  
 +/** @} */
 +
  #endif
diff --combined apt-pkg/algorithms.cc
index 8a22819bf168e40f49de876433e029ff8fddfe8b,723c8ea3ab4a22f11d71081e82128a31a15dd160..58498aa19560f6b5993191e17b0f362834cadf58
@@@ -102,6 -102,7 +102,7 @@@ bool pkgSimulate::Install(PkgIterator i
         DepIterator End;
         D.GlobOr(Start,End);
         if (Start->Type == pkgCache::Dep::Conflicts ||
+            Start->Type == pkgCache::Dep::DpkgBreaks ||
             Start->Type == pkgCache::Dep::Obsoletes ||
             End->Type == pkgCache::Dep::PreDepends)
           {
@@@ -151,6 -152,8 +152,8 @@@ bool pkgSimulate::Configure(PkgIterato
            cout << " Obsoletes:" << D.TargetPkg().Name();
         else if (D->Type == pkgCache::Dep::Conflicts)
            cout << " Conflicts:" << D.TargetPkg().Name();
+        else if (D->Type == pkgCache::Dep::DpkgBreaks)
+           cout << " Breaks:" << D.TargetPkg().Name();
         else
            cout << " Depends:" << D.TargetPkg().Name();
        }           
@@@ -651,6 -654,7 +654,7 @@@ bool pkgProblemResolver::DoUpgrade(pkgC
               /* We let the algorithm deal with conflicts on its next iteration,
                it is much smarter than us */
               if (Start->Type == pkgCache::Dep::Conflicts || 
+                  Start->Type == pkgCache::Dep::DpkgBreaks || 
                   Start->Type == pkgCache::Dep::Obsoletes)
                   break;
               
@@@ -800,7 -804,7 +804,7 @@@ bool pkgProblemResolver::Resolve(bool B
            continue;
         
         if (Debug == true)
 -          cout << "Investigating " << I.Name() << endl;
 +          clog << "Investigating " << I.Name() << endl;
         
         // Isolate the problem dependency
         PackageKill KillList[100];
            SPtrArray<pkgCache::Version *> VList = Start.AllTargets();
            if (*VList == 0 && (Flags[I->ID] & Protected) != Protected &&
                Start->Type != pkgCache::Dep::Conflicts &&
+               Start->Type != pkgCache::Dep::DpkgBreaks &&
                Start->Type != pkgCache::Dep::Obsoletes &&
                Cache[I].NowBroken() == false)
            {          
               if (Scores[I->ID] <= Scores[Pkg->ID] ||
                   ((Cache[Start] & pkgDepCache::DepNow) == 0 &&
                    End->Type != pkgCache::Dep::Conflicts &&
+                   End->Type != pkgCache::Dep::DpkgBreaks &&
                    End->Type != pkgCache::Dep::Obsoletes))
               {
                  // Try a little harder to fix protected packages..
                      (Start->Type == pkgCache::Dep::Conflicts ||
                       Start->Type == pkgCache::Dep::Obsoletes))
                     continue;
-                 
+                 if (Start->Type == pkgCache::Dep::DpkgBreaks)
+                 {
+                    /* Would it help if we upgraded? */
+                    if (Cache[End] & pkgDepCache::DepGCVer) {
+                       if (Debug)
+                          clog << "  Upgrading " << Pkg.Name() << " due to Breaks field in " << I.Name() << endl;
+                       Cache.MarkInstall(Pkg, false, 0, false);
+                       continue;
+                    }
+                    if (Debug)
+                       clog << "  Will not break " << Pkg.Name() << " as stated in Breaks field in " << I.Name() <<endl;
+                    Cache.MarkKeep(I, false, false);
+                    continue;
+                 }
                  // Skip adding to the kill list if it is protected
                  if ((Flags[Pkg->ID] & Protected) != 0)
                     continue;
            // Hm, nothing can possibly satisify this dep. Nuke it.
            if (VList[0] == 0 && 
                Start->Type != pkgCache::Dep::Conflicts &&
+               Start->Type != pkgCache::Dep::DpkgBreaks &&
                Start->Type != pkgCache::Dep::Obsoletes &&
                (Flags[I->ID] & Protected) != Protected)
            {
@@@ -1229,13 -1251,8 +1251,13 @@@ void pkgProblemResolver::InstallProtect
        {
         if ((Flags[I->ID] & ToRemove) == ToRemove)
            Cache.MarkDelete(I);
 -       else
 -          Cache.MarkInstall(I, false, 0, false);
 +       else 
 +       {
 +          // preserver the information if the package was auto
 +          // or manual installed
 +          bool autoInst = (Cache[I].Flags & pkgCache::Flag::Auto);
 +          Cache.MarkInstall(I, false, 0, !autoInst);
 +       }
        }
     }   
  }
index 55fdcb667830b395b16eb0ca3951f8627cc8d435,7645dc564e4078109df8be980bda43e02a67a78d..8b1237ccdc6686a9efb359ce5a391acb95b31de5
@@@ -11,6 -11,9 +11,6 @@@
  #ifndef PKGLIB_DEBSRCRECORDS_H
  #define PKGLIB_DEBSRCRECORDS_H
  
 -#ifdef __GNUG__
 -#pragma interface "apt-pkg/debsrcrecords.h"
 -#endif 
  
  #include <apt-pkg/srcrecords.h>
  #include <apt-pkg/tagfile.h>
@@@ -24,7 -27,7 +24,7 @@@ class debSrcRecordParser : public pkgSr
     char *StaticBinList[400];
     unsigned long iOffset;
     char *Buffer;
-    unsigned long BufSize;
+    unsigned int BufSize;
     
     public:
  
diff --combined apt-pkg/depcache.cc
index 6d74a4db513d95ba8fc2289efa13c3e24e0ad967,4d193dc2e81fd0fc19e567cd15f46d10278ba145..1e4771dda35f242a159431803ffd0aeb18a6465c
@@@ -8,6 -8,9 +8,6 @@@
     ##################################################################### */
                                                                        /*}}}*/
  // Include Files                                                      /*{{{*/
 -#ifdef __GNUG__
 -#pragma implementation "apt-pkg/depcache.h"
 -#endif
  #include <apt-pkg/depcache.h>
  #include <apt-pkg/version.h>
  #include <apt-pkg/error.h>
@@@ -270,7 -273,7 +270,7 @@@ bool pkgDepCache::CheckDep(DepIterator 
        we allow it anyhow because dpkg does. Technically it is a packaging
        bug. Conflicts may never self match */
     if (Dep.TargetPkg() != Dep.ParentPkg() || 
-        (Dep->Type != Dep::Conflicts && Dep->Type != Dep::Obsoletes))
+        (Dep->Type != Dep::Conflicts && Dep->Type != Dep::DpkgBreaks && Dep->Type != Dep::Obsoletes))
     {
        PkgIterator Pkg = Dep.TargetPkg();
        // Check the base package
     {
        /* Provides may never be applied against the same package if it is
           a conflicts. See the comment above. */
-       if (P.OwnerPkg() == Pkg && Dep->Type == Dep::Conflicts)
+       if (P.OwnerPkg() == Pkg &&
+         (Dep->Type == Dep::Conflicts || Dep->Type == Dep::DpkgBreaks))
         continue;
        
        // Check if the provides is a hit
@@@ -454,7 -458,9 +455,9 @@@ void pkgDepCache::BuildGroupOrs(VerIter
  
        /* Invert for Conflicts. We have to do this twice to get the
           right sense for a conflicts group */
-       if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
+       if (D->Type == Dep::Conflicts ||
+         D->Type == Dep::DpkgBreaks ||
+         D->Type == Dep::Obsoletes)
         State = ~State;
        
        // Add to the group if we are within an or..
         Group = 0;
        
        // Invert for Conflicts
-       if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
+       if (D->Type == Dep::Conflicts ||
+         D->Type == Dep::DpkgBreaks ||
+         D->Type == Dep::Obsoletes)
         State = ~State;
     }   
  }
@@@ -598,7 -606,9 +603,9 @@@ void pkgDepCache::Update(OpProgress *Pr
               Group = 0;
  
            // Invert for Conflicts
-           if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
+           if (D->Type == Dep::Conflicts ||
+               D->Type == Dep::DpkgBreaks ||
+               D->Type == Dep::Obsoletes)
               State = ~State;
         }       
        }
@@@ -628,7 -638,9 +635,9 @@@ void pkgDepCache::Update(DepIterator D
        State = DependencyState(D);
      
        // Invert for Conflicts
-       if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
+       if (D->Type == Dep::Conflicts ||
+         D->Type == Dep::DpkgBreaks ||
+         D->Type == Dep::Obsoletes)
         State = ~State;
  
        RemoveStates(D.ParentPkg());
@@@ -700,17 -712,9 +709,17 @@@ void pkgDepCache::MarkKeep(PkgIterator 
     // We dont even try to keep virtual packages..
     if (Pkg->VersionList == 0)
        return;
 -   
 +#if 0 // reseting the autoflag here means we lose the 
 +      // auto-mark information if a user selects a package for removal
 +      // but changes  his mind then and sets it for keep again
 +      // - this makes sense as default when all Garbage dependencies
 +      //   are automatically marked for removal (as aptitude does).
 +      //   setting a package for keep then makes it no longer autoinstalled
 +      //   for all other use-case this action is rather suprising
     if(FromUser && !P.Marked)
       P.Flags &= ~Flag::Auto;
 +#endif
 +
     RemoveSizes(Pkg);
     RemoveStates(Pkg);
  
@@@ -869,7 -873,6 +878,7 @@@ void pkgDepCache::MarkInstall(PkgIterat
         bool found=false;
         VerIterator instVer = Pkg.CurrentVer();
         if(!instVer.end())
 +       {
            for (DepIterator D = instVer.DependsList(); D.end() != true; D++)
            {
               //FIXME: deal better with or-groups(?)
               if(IsImportantDep(D) && Start.TargetPkg() == D.TargetPkg())
                  found=true;
            }
 -       // this is a new dep if it was not found to be already
 -       // a important dep of the installed pacakge
 -       isNewImportantDep = !found;
 +          // this is a new dep if it was not found to be already
 +          // a important dep of the installed pacakge
 +          isNewImportantDep = !found;
 +       }
        }
        if(isNewImportantDep)
         if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
        /* This bit is for processing the possibilty of an install/upgrade
           fixing the problem */
        SPtrArray<Version *> List = Start.AllTargets();
-       if ((DepState[Start->ID] & DepCVer) == DepCVer)
+       if (Start->Type != Dep::DpkgBreaks &&
+         (DepState[Start->ID] & DepCVer) == DepCVer)
        {
         // Right, find the best version to install..
         Version **Cur = List;
               std::clog << "Installing " << InstPkg.Name() 
                         << " as dep of " << Pkg.Name() 
                         << std::endl;
-          MarkInstall(InstPkg, true, Depth + 1, false, ForceImportantDeps);
+           MarkInstall(InstPkg,true,Depth + 1, false, ForceImportantDeps);
+           // Set the autoflag, after MarkInstall because MarkInstall unsets it
+           if (P->CurrentVer == 0)
+              PkgState[InstPkg->ID].Flags |= Flag::Auto;
         }
         continue;
        }
-       
        /* For conflicts we just de-install the package and mark as auto,
-          Conflicts may not have or groups */
-       if (Start->Type == Dep::Conflicts || Start->Type == Dep::Obsoletes)
+          Conflicts may not have or groups.  For dpkg's Breaks we try to
+          upgrade the package. */
+       if (Start->Type == Dep::Conflicts || Start->Type == Dep::Obsoletes ||
+         Start->Type == Dep::DpkgBreaks)
        {
         for (Version **I = List; *I != 0; I++)
         {
            VerIterator Ver(*this,*I);
            PkgIterator Pkg = Ver.ParentPkg();
-       
-           MarkDelete(Pkg);
+           if (Start->Type != Dep::DpkgBreaks)
+              MarkDelete(Pkg);
+           else
+              if (PkgState[Pkg->ID].CandidateVer != *I)
+                 MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps);
         }
         continue;
        }      
@@@ -1095,34 -1108,6 +1115,34 @@@ pkgCache::VerIterator pkgDepCache::Poli
     return Last;
  }
                                                                        /*}}}*/
 +// Policy::IsImportantDep - True if the dependency is important               /*{{{*/
 +// ---------------------------------------------------------------------
 +/* */
 +bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep)
 +{
 +   if(Dep.IsCritical())
 +      return true;
 +   else if(Dep->Type == pkgCache::Dep::Recommends) 
 +   {
 +      if ( _config->FindB("APT::Install-Recommends", false))
 +       return true;
 +      // we suport a special mode to only install-recommends for certain
 +      // sections
 +      // FIXME: this is a meant as a temporarly solution until the 
 +      //        recommends are cleaned up
 +      string s = _config->Find("APT::Install-Recommends-Section","");
 +      if(s.size() > 0) 
 +      {
 +       const char *sec = Dep.TargetPkg().Section();
 +       if (sec && strcmp(sec, s.c_str()) == 0)
 +          return true;
 +      }
 +   }
 +   else if(Dep->Type == pkgCache::Dep::Suggests)
 +     return _config->FindB("APT::Install-Suggests", false);
 +
 +   return false;
 +}
                                                                        /*}}}*/
  
  pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()
@@@ -1326,7 -1311,8 +1346,7 @@@ bool pkgDepCache::Sweep(
       StateCache &state=PkgState[p->ID];
  
       // if it is not marked and it is installed, it's garbage 
 -     if(!state.Marked && (!p.CurrentVer().end() || state.Install()) &&
 -      !state.Delete())
 +     if(!state.Marked && (!p.CurrentVer().end() || state.Install()))
       {
        state.Garbage=true;
        if(_config->FindB("Debug::pkgAutoRemove",false))
  
     return true;
  }
 -
 -// Policy::IsImportantDep - True if the dependency is important               /*{{{*/
 -// ---------------------------------------------------------------------
 -/* */
 -bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep)
 -{
 -   if(Dep.IsCritical())
 -      return true;
 -   else if(Dep->Type == pkgCache::Dep::Recommends)
 -      return  _config->FindB("APT::Install-Recommends", false);
 -   else if(Dep->Type == pkgCache::Dep::Suggests)
 -     return _config->FindB("APT::Install-Suggests", false);
 -
 -   return false;
 -}
 -                                                                      /*}}}*/
diff --combined apt-pkg/pkgcache.cc
index 28c972aed2c2c9191286e291fe87c5bd662927d4,93ad566419a505865d39dca3b20ed1f0898279e8..7e3b9d78c9a5a58ebbb8913d69a5b421dc5f821f
     ##################################################################### */
                                                                        /*}}}*/
  // Include Files                                                      /*{{{*/
 -#ifdef __GNUG__
 -#pragma implementation "apt-pkg/pkgcache.h"
 -#pragma implementation "apt-pkg/cacheiterators.h"
 -#endif 
 -
  #include <apt-pkg/pkgcache.h>
  #include <apt-pkg/indexfile.h>
  #include <apt-pkg/version.h>
@@@ -49,7 -54,7 +49,7 @@@ pkgCache::Header::Header(
     
     /* Whenever the structures change the major version should be bumped,
        whenever the generator changes the minor version should be bumped. */
-    MajorVersion = 5;
+    MajorVersion = 6;
     MinorVersion = 0;
     Dirty = false;
     
@@@ -223,8 -228,8 +223,8 @@@ const char *pkgCache::DepType(unsigned 
  {
     const char *Types[] = {"",_("Depends"),_("PreDepends"),_("Suggests"),
                            _("Recommends"),_("Conflicts"),_("Replaces"),
-                           _("Obsoletes")};
-    if (Type < 8)
+                           _("Obsoletes"),_("Breaks")};
+    if (Type < sizeof(Types)/sizeof(*Types))
        return Types[Type];
     return "";
  }
@@@ -287,10 -292,11 +287,11 @@@ pkgCache::PkgIterator::OkState pkgCache
  // DepIterator::IsCritical - Returns true if the dep is important     /*{{{*/
  // ---------------------------------------------------------------------
  /* Currently critical deps are defined as depends, predepends and
-    conflicts. */
+    conflicts (including dpkg's Breaks fields). */
  bool pkgCache::DepIterator::IsCritical()
  {
     if (Dep->Type == pkgCache::Dep::Conflicts ||
+        Dep->Type == pkgCache::Dep::DpkgBreaks ||
         Dep->Type == pkgCache::Dep::Obsoletes ||
         Dep->Type == pkgCache::Dep::Depends ||
         Dep->Type == pkgCache::Dep::PreDepends)
@@@ -376,6 -382,7 +377,7 @@@ pkgCache::Version **pkgCache::DepIterat
            continue;
  
         if ((Dep->Type == pkgCache::Dep::Conflicts ||
+             Dep->Type == pkgCache::Dep::DpkgBreaks ||
              Dep->Type == pkgCache::Dep::Obsoletes) &&
             ParentPkg() == I.ParentPkg())
            continue;
            continue;
         
         if ((Dep->Type == pkgCache::Dep::Conflicts ||
+             Dep->Type == pkgCache::Dep::DpkgBreaks ||
              Dep->Type == pkgCache::Dep::Obsoletes) &&
             ParentPkg() == I.OwnerPkg())
            continue;
diff --combined apt-pkg/pkgcache.h
index 5ae611ba4cffcbbd830d92af2fc41371b58c80c9,970759492f70674cc09425fbe45d2dbf05813262..83b7548a3da01e7ab5b52492f882e31fd387a826
@@@ -19,6 -19,9 +19,6 @@@
  #ifndef PKGLIB_PKGCACHE_H
  #define PKGLIB_PKGCACHE_H
  
 -#ifdef __GNUG__
 -#pragma interface "apt-pkg/pkgcache.h"
 -#endif 
  
  #include <string>
  #include <time.h>
@@@ -63,10 -66,14 +63,14 @@@ class pkgCach
     class Namespace;
     
     // These are all the constants used in the cache structures
+    // WARNING - if you change these lists you must also edit
+    // the stringification in pkgcache.cc and also consider whether
+    // the cache file will become incompatible.
     struct Dep
     {
        enum DepType {Depends=1,PreDepends=2,Suggests=3,Recommends=4,
-        Conflicts=5,Replaces=6,Obsoletes=7};
+        Conflicts=5,Replaces=6,Obsoletes=7,DpkgBreaks=8};
        enum DepCompareOp {Or=0x10,NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3,
         Greater=0x4,Equals=0x5,NotEquals=0x6};
     };
diff --combined cmdline/apt-get.cc
index 6949dc6eb53df5477dd0d5c4be45830af32ebe05,4bd66383f6bc91c40790167bc92a24adb4ea9f4b..b47c2ec0944d802d5e1f298dd071fbd133bb7020
@@@ -650,7 -650,7 +650,7 @@@ bool CacheFile::CheckDeps(bool AllowBro
         // 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);
 +             DCache->MarkInstall(I,true,0, false, true);
        }
     }
  
@@@ -1372,20 -1372,29 +1372,29 @@@ bool DoUpdate(CommandLine &CmdL
        return false;
  
     bool Failed = false;
+    bool TransientNetworkFailure = false;
     for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
     {
        if ((*I)->Status == pkgAcquire::Item::StatDone)
         continue;
  
        (*I)->Finished();
-       
        fprintf(stderr,_("Failed to fetch %s  %s\n"),(*I)->DescURI().c_str(),
              (*I)->ErrorText.c_str());
+       if ((*I)->Status == pkgAcquire::Item::StatTransientNetworkError) 
+       {
+        TransientNetworkFailure = true;
+        continue;
+       }
        Failed = true;
     }
     
     // Clean out any old list files
-    if (!Failed && _config->FindB("APT::Get::List-Cleanup",true) == true)
+    if (!TransientNetworkFailure &&
+        _config->FindB("APT::Get::List-Cleanup",true) == true)
     {
        if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
          Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
     if (Cache.BuildCaches() == false)
        return false;
     
-    if (Failed == true)
+    if (TransientNetworkFailure == true)
+       _error->Warning(_("Some index files failed to download, they have been ignored, or old ones used instead."));
+    else if (Failed == true)
        return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
-    
     return true;
  }
                                                                        /*}}}*/
  /* Remove unused automatic packages */
  bool DoAutomaticRemove(CacheFile &Cache)
  {
 -   if(_config->FindI("Debug::pkgAutoRemove",false))
 -      std::cout << "DoAutomaticRemove()" << std::endl;
 +   bool Debug = _config->FindI("Debug::pkgAutoRemove",false);
 +   bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false);
 +   pkgDepCache::ActionGroup group(*Cache);
 +   
  
 -   if (_config->FindB("APT::Get::Remove",true) == false)
 -      return _error->Error(_("We are not supposed to delete stuff, can't "
 -                           "start AutoRemover"));
 +   if(Debug)
 +      std::cout << "DoAutomaticRemove()" << std::endl;
  
 +   if (_config->FindB("APT::Get::Remove",true) == false &&
 +       doAutoRemove == true)
     {
 -     pkgDepCache::ActionGroup group(*Cache);
 -
 -     // look over the cache to see what can be removed
 -     for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg)
 -       {
 -       if (Cache[Pkg].Garbage)
 -         {
 -           if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
 -             fprintf(stdout,"We could delete %s\n", Pkg.Name());
 +      c1out << _("We are not supposed to delete stuff, can't start "
 +               "AutoRemover") << std::endl;
 +      doAutoRemove = false;
 +   }
  
 -           if(Pkg.CurrentVer() != 0 && Pkg->CurrentState != pkgCache::State::ConfigFiles)
 +   string autoremovelist, autoremoveversions;
 +   // look over the cache to see what can be removed
 +   for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg)
 +   {
 +      if (Cache[Pkg].Garbage)
 +      {
 +       if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
 +          if(Debug)
 +             std::cout << "We could delete %s" <<  Pkg.Name() << std::endl;
 +         
 +       autoremovelist += string(Pkg.Name()) + " ";
 +       autoremoveversions += string(Cache[Pkg].CandVersion) + " ";
 +       if (doAutoRemove)
 +       {
 +          if(Pkg.CurrentVer() != 0 && 
 +             Pkg->CurrentState != pkgCache::State::ConfigFiles)
               Cache->MarkDelete(Pkg, _config->FindB("APT::Get::Purge", false));
 -           else
 +          else
               Cache->MarkKeep(Pkg, false, false);
 -         }
 -       }
 +       }
 +      }
     }
 +   ShowList(c1out, _("The following packages were automatically installed and are no longer required:"), autoremovelist, autoremoveversions);
 +   if (!doAutoRemove && autoremovelist.size() > 0)
 +      c1out << _("Use 'apt-get autoremove' to remove them.") << std::endl;
  
     // Now see if we destroyed anything
     if (Cache->BrokenCount() != 0)
@@@ -1485,51 -1480,6 +1496,51 @@@ bool DoUpgrade(CommandLine &CmdL
     return InstallPackages(Cache,true);
  }
                                                                        /*}}}*/
 +// DoInstallTask - Install task from the command line                 /*{{{*/
 +// ---------------------------------------------------------------------
 +/* Install named task */
 +bool TryInstallTask(pkgDepCache &Cache, pkgProblemResolver &Fix, 
 +                  bool BrokenFix,
 +                  unsigned int& ExpectedInst, 
 +                  const char *taskname)
 +{
 +   const char *start, *end;
 +   pkgCache::PkgIterator Pkg;
 +   char buf[64*1024];
 +   regex_t Pattern;
 +
 +   // get the records
 +   pkgRecords Recs(Cache);
 +
 +   // build regexp for the task
 +   char S[300];
 +   snprintf(S, sizeof(S), "^Task:.*[^a-z]%s[^a-z].*\n", taskname);
 +   regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
 +   
 +   bool found = false;
 +   bool res = true;
 +   for (Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
 +   {
 +      pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache);
 +      if(ver.end())
 +       continue;
 +      pkgRecords::Parser &parser = Recs.Lookup(ver.FileList());
 +      parser.GetRec(start,end);
 +      strncpy(buf, start, end-start);
 +      buf[end-start] = 0x0;
 +      if (regexec(&Pattern,buf,0,0,0) != 0)
 +       continue;
 +      res &= TryToInstall(Pkg,Cache,Fix,false,BrokenFix,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 */
@@@ -1709,8 -1659,10 +1720,10 @@@ bool DoInstall(CommandLine &CmdL
         return _error->Error(_("Broken packages"));
        }   
     }
-    if (!DoAutomaticRemove(Cache)) 
+    if (_config->FindB("APT::Get::AutomaticRemove")) {
+       if (!DoAutomaticRemove(Cache)) 
         return false;
+    }
  
     /* Print out a list of packages that are going to be installed extra
        to what the user asked */
@@@ -2621,6 -2573,7 +2634,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                               /*{{{*/
diff --combined debian/changelog
index 80c47bdeea6a03f5ac5e40dfe536bc1e11d6efcb,254e603aa35576e925f59309362743254a7411cf..52bdced8f0d3040e3379138d211d2dd40deae0f0
@@@ -1,20 -1,5 +1,31 @@@
 -apt (0.6.46.4) unstable; urgency=low
 +apt (0.7.0) experimental; urgency=low
  
 +  * Branch 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
++  * Removed all #pragma interface/implementation
++  * 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)
++
 +
 + -- Michael Vogt <mvo@debian.org>  Thu, 14 Dec 2006 11:31:41 +0100
 +
 +apt (0.6.46.5) UNRELEASED; urgency=low
 +
 +  * apt-pkg/algorithm.cc:
 +    - use clog for all debugging
 +
 + -- Michael Vogt <mvo@debian.org>  Thu, 14 Dec 2006 11:31:41 +0100
 +
 +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
      - 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
  
        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 
 +    - 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:
@@@ -158,7 -110,7 +169,7 @@@ apt (0.6.45) unstable; urgency=lo
    * apt-pkg/contrib/sha256.cc:
      - fixed the sha256 generation (closes: #378183)
    * ftparchive/cachedb.cc:
 -    - applied patch from Anthony Towns to fix Clean() function
 +    - applied patch from ajt to fix Clean() function
        (closes: #379576)
    * doc/apt-get.8.xml:
      - fix path to the apt user build (Closes: #375640)
      - 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
      * 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.2ubuntu4) edgy; urgency=low
 -
 -  * Make apt-get dselect-upgrade happy again
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Fri, 21 Jul 2006 11:03:02 +0200
 -
 -apt (0.6.44.2ubuntu3) edgy; urgency=low
 -
 -  * Close extended_states file after writing it.
 -
 - -- Colin Watson <cjwatson@ubuntu.com>  Tue, 18 Jul 2006 00:12:13 +0100
 -
 -apt (0.6.44.2ubuntu2) edgy; urgency=low
 + -- Michael Vogt <michael.vogt@ubuntu.com>  Tue, 25 Jul 2006 11:55:22 +0200
  
 -  * create a empty extended_states file if none exists already
 +apt (0.6.44.2exp1) experimental; urgency=low
  
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Tue,  4 Jul 2006 09:23:03 +0200
 +  * 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
  
 -apt (0.6.44.2ubuntu1) edgy; urgency=low
 + -- Michael Vogt <mvo@debian.org>  Mon,  3 Jul 2006 21:50:31 +0200
  
 -  * merged with debian/unstable
 -  * merged the "auto-mark" branch to support aptitude like
 -    marking of automatically installed dependencies and added
 -    "apt-get remove --auto-remove" to remove unused auto-installed
 -    packages again
 -  * changed library version from 3.11 to 3.50 to make it clearly 
 -    different from the debian version (we are ABI incompatible because
 -    of the auto-mark patch)
 +apt (0.6.44.2) unstable; urgency=low
  
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Mon,  3 Jul 2006 18:30:46 +0200
 +  * 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
  
 -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 
 + -- Michael Vogt <mvo@debian.org>  Wed, 14 Jun 2006 12:00:57 +0200
  
  apt (0.6.44.1-0.1) unstable; urgency=low
  
  
  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
    
   -- Michael Vogt <mvo@debian.org>  Mon,  8 May 2006 22:28:53 +0200
  
 -apt (0.6.43.3ubuntu3) dapper; urgency=low
 -
 -  * methods/http.cc:
 -    - fix the user-agent string
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Fri, 26 May 2006 18:09:32 +0200
 -
 -apt (0.6.43.3ubuntu2) dapper; urgency=low
 -
 -  * apt-pkg/deb/dpkgpm.cc: wording fixes (thanks to Matt Zimmerman)
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Tue, 18 Apr 2006 13:24:40 +0200
 -
 -apt (0.6.43.3ubuntu1) dapper; urgency=low
 -
 -  * apt-pkg/acquire.cc: don't show ETA if it is 0 or absurdely large in 
 -    the status-fd (ubuntu #28954)
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Tue, 28 Mar 2006 20:34:46 +0200
 -
  apt (0.6.43.3) unstable; urgency=low
  
    * Merge bubulle@debian.org--2005/apt--main--0 up to patch-186:
      * pl.po: Completed to 512t. Closes: #349514
      * sk.po: Completed to 512t. Closes: #349474
      * gl.po: Completed to 512 strings Closes: #349407
 -    * vi.po: Completed to 512 strings
      * sv.po: Completed to 512 strings Closes: #349210
      * ru.po: Completed to 512 strings Closes: #349154
      * da.po: Completed to 512 strings Closes: #349084
      * fr.po: Completed to 512 strings
 -    * LINGUAS: Add Welsh
 -    * *.po: Updated from sources (512 strings)
      * vi.po: Completed to 511 strings  Closes: #348968
 -  * apt-pkg/deb/deblistparser.cc:
 -    - don't explode on a DepCompareOp in a Provides line, but warn about
 -      it and ignore it otherwise (thanks to James Troup for reporting it)
 -  * cmdline/apt-get.cc:
 -    - don't lock the lists directory in DoInstall, breaks --print-uri 
 -      (thanks to James Troup for reporting it)
 -  * debian/apt.dirs: create /etc/apt/sources.list.d 
 -  * make apt-cache madison work without deb-src entries (#352583)
 -  * cmdline/apt-get.cc: only run the list-cleaner if a update was 
 -    successfull
 -  * apt-get update errors are only warnings nowdays
 -  * be more careful with the signature file on network failures
 -
 - --  Michael Vogt <mvo@debian.org>  Wed, 22 Feb 2006 10:13:04 +0100
 -
 -apt (0.6.43.2ubuntu1) dapper; urgency=low
 -
 -  * Merge bubulle@debian.org--2005/apt--main--0 up to patch-182:
 -  * ca.po: Completed to 512t. Closes: #351592
 -    * eu.po: Completed to 512t. Closes: #350483
 -    * ja.po: Completed to 512t. Closes: #349806
 -    * pl.po: Completed to 512t. Closes: #349514
 -    * sk.po: Completed to 512t. Closes: #349474
 -    * gl.po: Completed to 512 strings Closes: #349407
 -    * vi.po: Completed to 512 strings
 -    * sv.po: Completed to 512 strings Closes: #349210
 -    * ru.po: Completed to 512 strings Closes: #349154
 -    * da.po: Completed to 512 strings Closes: #349084
 -    * fr.po: Completed to 512 strings
 +    * zh_CN.po: Completed to 512t. Closes: #353936
 +    * it.po: Completed to 512t. Closes: #352803
 +    * pt_BR.po: Completed to 512t. Closes: #352419
      * LINGUAS: Add Welsh
      * *.po: Updated from sources (512 strings)
 -    * vi.po: Completed to 511 strings  Closes: #348968
    * apt-pkg/deb/deblistparser.cc:
      - don't explode on a DepCompareOp in a Provides line, but warn about
        it and ignore it otherwise (thanks to James Troup for reporting it)
    * make apt-cache madison work without deb-src entries (#352583)
    * cmdline/apt-get.cc: only run the list-cleaner if a update was 
      successfull
 -  * apt-get update errors are only warnings nowdays
 -  * be more careful with the signature file on network failures
  
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Mon, 20 Feb 2006 22:27:48 +0100
 + -- Michael Vogt <mvo@debian.org>  Wed, 22 Feb 2006 10:13:04 +0100
  
  apt (0.6.43.2) unstable; urgency=low
  
  
   -- Michael Vogt <mvo@debian.org>  Thu, 19 Jan 2006 00:06:33 +0100
  
 -apt (0.6.43.1ubuntu1) dapper; urgency=low
 -
 -  * Merge bubulle@debian.org--2005/apt--main--0 up to patch-159:
 -    - en_GB.po, de.po: fix spaces errors in "Ign " translations
 -      Closes: #347258
 -    - makefile: make update-po a pre-requisite of clean target so
 -              that POT and PO files are always up-to-date
 -    - sv.po: Completed to 511t. Closes: #346450
 -    - sk.po: Completed to 511t. Closes: #346369
 -    - fr.po: Completed to 511t
 -    - *.po: Updated from sources (511 strings)
 -  * add patch to fix http download corruption problem (thanks to
 -    Petr Vandrovec, closes: #280844, #290694)
 -  * added APT::Periodic::Unattended-Upgrade (requires the package
 -    "unattended-upgrade")
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Tue, 10 Jan 2006 17:09:31 +0100
 -
  apt (0.6.43.1) unstable; urgency=low
 -  
 +
    * Merge bubulle@debian.org--2005/apt--main--0 up to patch-148:
      * fr.po: Completed to 510 strings
      * it.po: Completed to 510t
  
   -- Michael Vogt <mvo@debian.org>  Fri,  6 Jan 2006 01:17:08 +0100
  
 -apt (0.6.43ubuntu2) dapper; urgency=low
 -
 -  * merged some missing bits that wheren't merged by baz in the previous
 -    upload (*grumble*)
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Thu,  8 Dec 2005 18:35:58 +0100
 -
 -apt (0.6.43ubuntu1) dapper; urgency=low
 -
 -  * merged with debian
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Fri, 25 Nov 2005 11:36:29 +0100
 -
  apt (0.6.43) unstable; urgency=medium
  
    * Merge bubulle@debian.org--2005/apt--main--0 up to patch-132:  
    
   -- Michael Vogt <mvo@debian.org>  Tue, 29 Nov 2005 00:17:07 +0100
  
 -apt (0.6.42.3ubuntu2) dapper; urgency=low
 -
 -  * Merge bubulle@debian.org--2005/apt--main--0 up to patch-131:  
 -    * zh_CN.po: Completed to 507 strings(Closes: #338267)
 -    * gl.po: Completed to 510 strings (Closes: #338356)
 -  * added support for "/etc/apt/sources.list.d" directory 
 -    (closes: #66325)
 -  
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Mon, 14 Nov 2005 15:30:12 +0100
 -
 -apt (0.6.42.3ubuntu1) dapper; urgency=low
 -
 -  * synced with debian
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Thu, 10 Nov 2005 05:05:56 +0100
 -
  apt (0.6.42.3) unstable; urgency=low
  
    * Merge bubulle@debian.org--2005/apt--main--0 up to patch-129:
@@@ -428,13 -487,13 +439,13 @@@ apt (0.6.42) unstable; urgency=lo
      - unmount the cdrom when apt failed to locate any package files
    * allow cdrom failures and fallback to other sources in that case
      (closes: #44135)
 -  * better error text when dpkg-source fails
 +  * better error text when dpkg-source fails 
    * Merge bubulle@debian.org--2005/apt--main--0 up to patch-115:
      - patch-99: Added Galician translation
      - patch-100: Completed Danish translation (Closes: #325686)
      - patch-104: French translation completed
      - patch-109: Italian translation completed
 -    - patch-112: Swedish translation update
 +    - patch-112: Swedish translation update 
      - patch-115: Basque translation completed (Closes: #333299)
    * applied french man-page update (thanks to Philippe Batailler)
      (closes: #316638, #327456)
    * apt-pkg/contrib/md5.cc:
      - fix a alignment problem on sparc64 that gives random bus errors
        (thanks to Fabbione for providing a test-case)
 -  * init the default ScreenWidth to 79 columns by default
 +  * init the default ScreenWidth to 79 columns by default 
      (Closes: #324921)
 -  * cmdline/apt-cdrom.cc:
 +  * cmdline/apt-cdrom.cc: 
      - fix some missing gettext() calls (closes: #334539)
    * doc/apt-cache.8.xml: fix typo (closes: #334714)
  
@@@ -461,8 -520,8 +472,8 @@@ apt (0.6.41) unstable; urgency=lo
    * improved the support for "error" and "conffile" reporting from
      dpkg, added the format to README.progress-reporting
    * added README.progress-reporting to the apt-doc package
 -  * improved the network timeout handling, if a index file from a
 -    sources.list times out or EAI_AGAIN is returned from getaddrinfo,
 +  * improved the network timeout handling, if a index file from a 
 +    sources.list times out or EAI_AGAIN is returned from getaddrinfo, 
      don't try to get the other files from that entry
    * Support architecture-specific extra overrides
      (closes: #225947). Thanks to  Anthony Towns for idea and
    * Javier Fernandez-Sanguino Pen~a:
      - Added a first version of an apt-secure.8 manpage, and modified
        apt-key and apt.end accordingly. Also added the 'update'
 -      argument to apt-key which was previously not documented
 +      argument to apt-key which was previously not documented 
        (Closes: #322120)
    * Andreas Pakulat:
 -    - added example apt-ftparchive.conf file to doc/examples
 +    - added example apt-ftparchive.conf file to doc/examples 
        (closes: #322483)
    * Fix a incorrect example in the man-page (closes: #282918)
    * Fix a bug for very long lines in the apt-cdrom code (closes: #280356)
    * Change pkgPolicy::Pin from private to protected to let subclasses
      access it too (closes: #321799)
    * add default constructor for PrvIterator (closes: #322267)
 -  * Reread status configuration on debSystem::Initialize()
 +  * Reread status configuration on debSystem::Initialize() 
      (needed for apt-proxy, thanks to Otavio for this patch)
 -
 - -- Michael Vogt <mvo@debian.org>  Mon,  5 Sep 2005 22:59:03 +0200
 -  
 -apt (0.6.40.1ubuntu8) breezy; urgency=low
 -
 -  * Cherry picked michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-62:
 -    - fix for a bad memory/file leak in the mmap code (ubuntu #15603)
 -  * po/de.po, po/fr.po: 
 -    - updated the translations
 -  * po/makefile:
 -    - create a single pot file in each domain dir to make rosetta happy
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Wed, 28 Sep 2005 10:16:06 +0200
 -
 -apt (0.6.40.1ubuntu7) breezy; urgency=low
 -
 -  * updated the pot/po files , no code changes
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Tue, 27 Sep 2005 18:38:16 +0200
 -
 -apt (0.6.40.1ubuntu6) breezy; urgency=low
 -
 -  * Cherry picked michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-56:
 -    - make it possible for apt to handle a failed MediaChange event and
 -      fall back to other sources (ubuntu #13713)
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Tue, 13 Sep 2005 22:09:50 +0200
 -
 -apt (0.6.40.1ubuntu5) breezy; urgency=low
 -
 -  * Cherry picked michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-{50,51}.
 -    This adds media-change reporting to the apt status-fd (ubuntu #15213)
 -  * Cherry picked michael.vogt@ubuntu.com--2005/apt--mvo--0--patch-55:
 -    apt-pkg/cdrom.cc:
 -    - unmount the cdrom when apt failed to locate any package files
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Mon, 12 Sep 2005 15:44:26 +0200
 -
 -apt (0.6.40.1ubuntu4) breezy; urgency=low
 -
 -  * debian/apt.cron.daily:
 -    - fix a embarrassing typo
    
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Wed,  7 Sep 2005 10:10:37 +0200
 -
 -apt (0.6.40.1ubuntu3) breezy; urgency=low
 -
 -  * debian/apt.cron.daily:
 -    - use the ctime as well when figuring what packages need to
 -      be removed. This fixes the problem that packages copied with    
 -      "cp -a" (e.g. from the installer) have old mtimes (ubuntu #14504)
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Tue,  6 Sep 2005 18:30:46 +0200
 -
 -apt (0.6.40.1ubuntu2) breezy; urgency=low
 -
 -  * improved the support for "error" and "conffile" reporting from
 -    dpkg, added the format to README.progress-reporting
 -  * added README.progress-reporting to the apt-doc package
 -  * Do md5sum checking for file and cdrom method (closes: #319142)
 -  * Change pkgPolicy::Pin from private to protected to let subclasses
 -    access it too (closes: #321799)
 -  * methods/connect.cc:
 -    - send failure reason for EAI_AGAIN (TmpResolveFailure) to acuire-item
 -  * apt-pkg/acquire-item.cc:
 -    - fail early if a FailReason is TmpResolveFailure (avoids hangs during
 -      the install when no network is available)
 -  * merged michael.vogt@ubuntu.com--2005/apt--trust-cdrom--0
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Tue, 23 Aug 2005 19:44:55 +0200
 -
 -apt (0.6.40.1ubuntu1) breezy; urgency=low
 -
 -  * Synchronize with Debian
 -
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Fri,  5 Aug 2005 14:20:56 +0200
 + -- Michael Vogt <mvo@debian.org>  Mon,  5 Sep 2005 22:59:03 +0200
  
  apt (0.6.40.1) unstable; urgency=low
  
  
   -- Michael Vogt <mvo@debian.org>  Fri,  5 Aug 2005 13:24:58 +0200
  
 -apt (0.6.40ubuntu1) breezy; urgency=low
 -
 -  * Synchronize with Debian
 -
 - -- Matt Zimmerman <mdz@ubuntu.com>  Thu,  4 Aug 2005 15:53:22 -0700
 -
  apt (0.6.40) unstable; urgency=low
  
    * Patch from Jordi Mallach to mark some additional strings for translation
  
   -- Matt Zimmerman <mdz@debian.org>  Thu, 28 Jul 2005 11:57:32 -0700
  
 -apt (0.6.39ubuntu4) breezy; urgency=low
 -
 -  * Fix keyring paths in apt-key, apt.postinst (I swear I remember doing this
 -    before...)
 -
 - -- Matt Zimmerman <mdz@ubuntu.com>  Wed, 29 Jun 2005 08:39:17 -0700
 -
 -apt (0.6.39ubuntu3) breezy; urgency=low
 -
 -  * Fix keyring locations for Ubuntu in apt-key too.
 -
 - -- Colin Watson <cjwatson@ubuntu.com>  Wed, 29 Jun 2005 14:45:36 +0100
 -
 -apt (0.6.39ubuntu2) breezy; urgency=low
 -
 -  * Install ubuntu-archive.gpg rather than debian-archive.gpg as
 -    /etc/apt/trusted.gpg.
 -
 - -- Colin Watson <cjwatson@ubuntu.com>  Wed, 29 Jun 2005 11:53:34 +0100
 -
 -apt (0.6.39ubuntu1) breezy; urgency=low
 -
 -  * Michael Vogt
 -    - Change debian/bugscript to use #!/bin/bash (Closes: #313402)
 -    - Fix a incorrect example in the man-page (closes: #282918)
 -    - Support architecture-specific extra overrides
 -      (closes: #225947). Thanks to  Anthony Towns for idea and
 -      the patch, thanks to Colin Watson for testing it.
 -    - better report network timeouts from the methods to the acuire code,
 -      only timeout once per sources.list line
 -
 - -- Matt Zimmerman <mdz@ubuntu.com>  Tue, 28 Jun 2005 11:52:24 -0700
 -
  apt (0.6.39) unstable; urgency=low
  
    * Welsh translation update: daf@muse.19inch.net--2005/apt--main--0--patch-6
    * Update priority of apt-utils to important, to match the override file
    * Install only one keyring on each branch (Closes: #316119)
  
 - -- Matt Zimmerman <mdz@debian.org>  Tue, 28 Jun 2005 11:35:21 -0700
 -
 -apt (0.6.38ubuntu1) breezy; urgency=low
 -
 -  * First release from Ubuntu branch
 -  * Merge with --main--0, switch back to Ubuntu keyring
 -
 - -- Matt Zimmerman <mdz@ubuntu.com>  Sat, 25 Jun 2005 16:52:41 -0700
 + -- Matt Zimmerman <mdz@debian.org>  Tue, 28 Jun 2005 11:51:09 -0700
  
  apt (0.6.38) unstable; urgency=low
  
diff --combined debian/rules
index 0413310a7ed25a8596616535829d5b159ad9875a,4e7490bed856734d35718a33b0e47f1abb8d4457..68302daff23ea64f90ed22d065dace57c761ce86
@@@ -210,10 -210,15 +210,15 @@@ apt: build debian/shlibs.loca
  
        cp debian/bugscript debian/$@/usr/share/bug/apt/script
  
 -      cp share/ubuntu-archive.gpg debian/$@/usr/share/$@
 -
 +      cp share/debian-archive.gpg debian/$@/usr/share/$@
 +      cp debian/apt.conf.autoremove debian/$@/etc/apt/apt.conf.d/01autoremove
  #     head -n 500 ChangeLog > debian/ChangeLog
  
+       # make rosetta happy and remove pot files in po/ (but leave stuff
+       # in po/domains/* untouched) and cp *.po into each domain dir
+       rm -f build/po/*.pot
+       rm -f po/*.pot
        dh_installexamples -p$@ $(BLD)/docs/examples/*
        dh_installman -p$@ 
        dh_installcron -p$@