]> git.saurik.com Git - apt.git/commitdiff
merge lp:~mvo/apt/sha512-template to add support for sha512
authorMichael Vogt <michael.vogt@ubuntu.com>
Wed, 8 Jun 2011 10:03:34 +0000 (12:03 +0200)
committerMichael Vogt <michael.vogt@ubuntu.com>
Wed, 8 Jun 2011 10:03:34 +0000 (12:03 +0200)
1  2 
apt-pkg/acquire-item.cc
apt-pkg/acquire-method.cc
apt-pkg/acquire-method.h
apt-pkg/makefile
cmdline/apt-get.cc
debian/changelog
ftparchive/writer.cc
ftparchive/writer.h

diff --combined apt-pkg/acquire-item.cc
index 6785b4e1be9413d1d80787fa340cbed4f5e0ec82,05e2f28a472ca8f696d3a65e5182a5d36a8d3dac..36abe0ac3266a1eab8d3002c3a297d122602b66c
@@@ -17,6 -17,7 +17,6 @@@
  #include <apt-pkg/configuration.h>
  #include <apt-pkg/aptconfiguration.h>
  #include <apt-pkg/sourcelist.h>
 -#include <apt-pkg/vendorlist.h>
  #include <apt-pkg/error.h>
  #include <apt-pkg/strutl.h>
  #include <apt-pkg/fileutl.h>
@@@ -219,8 -220,8 +219,8 @@@ string pkgAcqSubIndex::Custom600Headers
  
     struct stat Buf;
     if (stat(Final.c_str(),&Buf) != 0)
 -      return "\nIndex-File: true";
 -   return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 +      return "\nIndex-File: true\nFail-Ignore: true\n";
 +   return "\nIndex-File: true\nFail-Ignore: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
  }
                                                                        /*}}}*/
  void pkgAcqSubIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)     /*{{{*/
@@@ -834,16 -835,10 +834,16 @@@ string pkgAcqIndex::Custom600Headers(
     if (_config->FindB("Acquire::GzipIndexes",false))
        Final += ".gz";
     
 +   string msg = "\nIndex-File: true";
 +   // FIXME: this really should use "IndexTarget::IsOptional()" but that
 +   //        seems to be difficult without breaking ABI
 +   if (ShortDesc().find("Translation") != 0)
 +      msg += "\nFail-Ignore: true";
     struct stat Buf;
 -   if (stat(Final.c_str(),&Buf) != 0)
 -      return "\nIndex-File: true";
 -   return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 +   if (stat(Final.c_str(),&Buf) == 0)
 +      msg += "\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 +
 +   return msg;
  }
                                                                        /*}}}*/
  void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)        /*{{{*/
@@@ -1007,8 -1002,8 +1007,8 @@@ string pkgAcqIndexTrans::Custom600Heade
  
     struct stat Buf;
     if (stat(Final.c_str(),&Buf) != 0)
 -      return "\nFail-Ignore: true";
 -   return "\nFail-Ignore: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 +      return "\nFail-Ignore: true\nIndex-File: true";
 +   return "\nFail-Ignore: true\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
  }
                                                                        /*}}}*/
  // AcqIndexTrans::Failed - Silence failure messages for missing files /*{{{*/
@@@ -1389,6 -1384,29 +1389,6 @@@ void pkgAcqMetaIndex::QueueIndexes(boo
                                                                        /*}}}*/
  bool pkgAcqMetaIndex::VerifyVendor(string Message)                    /*{{{*/
  {
 -//    // Maybe this should be made available from above so we don't have
 -//    // to read and parse it every time?
 -//    pkgVendorList List;
 -//    List.ReadMainList();
 -
 -//    const Vendor* Vndr = NULL;
 -//    for (std::vector<string>::const_iterator I = GPGVOutput.begin(); I != GPGVOutput.end(); I++)
 -//    {
 -//       string::size_type pos = (*I).find("VALIDSIG ");
 -//       if (_config->FindB("Debug::Vendor", false))
 -//          std::cerr << "Looking for VALIDSIG in \"" << (*I) << "\": pos " << pos 
 -//                    << std::endl;
 -//       if (pos != std::string::npos)
 -//       {
 -//          string Fingerprint = (*I).substr(pos+sizeof("VALIDSIG"));
 -//          if (_config->FindB("Debug::Vendor", false))
 -//             std::cerr << "Looking for \"" << Fingerprint << "\" in vendor..." <<
 -//                std::endl;
 -//          Vndr = List.FindVendor(Fingerprint) != "";
 -//          if (Vndr != NULL);
 -//          break;
 -//       }
 -//    }
     string::size_type pos;
  
     // check for missing sigs (that where not fatal because otherwise we had
@@@ -1502,26 -1520,6 +1502,26 @@@ void pkgAcqMetaIndex::Failed(string Mes
        ReportMirrorFailure("GPGFailure");
     }
  
 +   /* Always move the meta index, even if gpgv failed. This ensures
 +    * that PackageFile objects are correctly filled in */
 +   if (FileExists(DestFile)) {
 +      string FinalFile = _config->FindDir("Dir::State::lists");
 +      FinalFile += URItoFileName(RealURI);
 +      /* InRelease files become Release files, otherwise
 +       * they would be considered as trusted later on */
 +      if (SigFile == DestFile) {
 +       RealURI = RealURI.replace(RealURI.rfind("InRelease"), 9,
 +                                     "Release");
 +       FinalFile = FinalFile.replace(FinalFile.rfind("InRelease"), 9,
 +                                     "Release");
 +       SigFile = FinalFile;
 +      }
 +      Rename(DestFile,FinalFile);
 +      chmod(FinalFile.c_str(),0644);
 +
 +      DestFile = FinalFile;
 +   }
 +
     // No Release file was present, or verification failed, so fall
     // back to queueing Packages files without verification
     QueueIndexes(false);
@@@ -1540,21 -1538,6 +1540,21 @@@ pkgAcqMetaClearSig::pkgAcqMetaClearSig(
     SigFile = DestFile;
  }
                                                                        /*}}}*/
 +// pkgAcqMetaClearSig::Custom600Headers - Insert custom request headers       /*{{{*/
 +// ---------------------------------------------------------------------
 +// FIXME: this can go away once the InRelease file is used widely
 +string pkgAcqMetaClearSig::Custom600Headers()
 +{
 +   string Final = _config->FindDir("Dir::State::lists");
 +   Final += URItoFileName(RealURI);
 +
 +   struct stat Buf;
 +   if (stat(Final.c_str(),&Buf) != 0)
 +      return "\nIndex-File: true\nFail-Ignore: true\n";
 +
 +   return "\nIndex-File: true\nFail-Ignore: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 +}
 +                                                                      /*}}}*/
  void pkgAcqMetaClearSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
  {
     if (AuthPass == false)
@@@ -1645,7 -1628,7 +1645,7 @@@ pkgAcqArchive::pkgAcqArchive(pkgAcquir
  
     // Select a source
     if (QueueNext() == false && _error->PendingError() == false)
 -      _error->Error(_("I wasn't able to locate file for the %s package. "
 +      _error->Error(_("I wasn't able to locate file for the %s package. "
                    "This might mean you need to manually fix this package."),
                    Version.ParentPkg().Name());
  }
@@@ -1682,6 -1665,8 +1682,8 @@@ bool pkgAcqArchive::QueueNext(
        string PkgFile = Parse.FileName();
        if (ForceHash.empty() == false)
        {
+        if(stringcasecmp(ForceHash, "sha512") == 0)
+           ExpectedHash = HashString("SHA512", Parse.SHA512Hash());
         if(stringcasecmp(ForceHash, "sha256") == 0)
            ExpectedHash = HashString("SHA256", Parse.SHA256Hash());
         else if (stringcasecmp(ForceHash, "sha1") == 0)
        else
        {
         string Hash;
-        if ((Hash = Parse.SHA256Hash()).empty() == false)
+        if ((Hash = Parse.SHA512Hash()).empty() == false)
+           ExpectedHash = HashString("SHA512", Hash);
+        else if ((Hash = Parse.SHA256Hash()).empty() == false)
            ExpectedHash = HashString("SHA256", Hash);
         else if ((Hash = Parse.SHA1Hash()).empty() == false)
            ExpectedHash = HashString("SHA1", Hash);
index e9e102488739df093d096e32800244692fe43b4d,bf3beafa25aebfb81d15e4d1ac226b0424eb7c11..8c353beb2ac0c637565da77e0773e50921d946fd
@@@ -23,7 -23,9 +23,7 @@@
  #include <apt-pkg/hashes.h>
  
  #include <iostream>
 -#include <stdarg.h>
  #include <stdio.h>
 -#include <unistd.h>
  #include <sys/signal.h>
                                                                        /*}}}*/
  
@@@ -34,28 -36,32 +34,28 @@@ using namespace std
  /* This constructs the initialization text */
  pkgAcqMethod::pkgAcqMethod(const char *Ver,unsigned long Flags)
  {
 -   char S[300] = "";
 -   char *End = S;
 -   strcat(End,"100 Capabilities\n");
 -   sprintf(End+strlen(End),"Version: %s\n",Ver);
 +   std::cout << "100 Capabilities\n"
 +           << "Version: " << Ver << "\n";
  
     if ((Flags & SingleInstance) == SingleInstance)
 -      strcat(End,"Single-Instance: true\n");
 -   
 +      std::cout << "Single-Instance: true\n";
 +
     if ((Flags & Pipeline) == Pipeline)
 -      strcat(End,"Pipeline: true\n");
 -   
 +      std::cout << "Pipeline: true\n";
 +
     if ((Flags & SendConfig) == SendConfig)
 -      strcat(End,"Send-Config: true\n");
 +      std::cout << "Send-Config: true\n";
  
     if ((Flags & LocalOnly) == LocalOnly)
 -      strcat(End,"Local-Only: true\n");
 +      std::cout <<"Local-Only: true\n";
  
     if ((Flags & NeedsCleanup) == NeedsCleanup)
 -      strcat(End,"Needs-Cleanup: true\n");
 +      std::cout << "Needs-Cleanup: true\n";
  
     if ((Flags & Removable) == Removable)
 -      strcat(End,"Removable: true\n");
 -   strcat(End,"\n");
 +      std::cout << "Removable: true\n";
  
 -   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
 -      exit(100);
 +   std::cout << "\n" << std::flush;
  
     SetNonBlock(STDIN_FILENO,true);
  
@@@ -88,11 -94,13 +88,11 @@@ void pkgAcqMethod::Fail(string Err,boo
        if (*I == '\n') 
         *I = ' ';
     }
 -   
 -   char S[1024];
 -   char *End = S;
 +
     if (Queue != 0)
     {
 -      End += snprintf(S,sizeof(S)-50,"400 URI Failure\nURI: %s\n"
 -                    "Message: %s %s\n",Queue->Uri.c_str(), Err.c_str(), IP.c_str());
 +      std::cout << "400 URI Failure\nURI: " << Queue->Uri << "\n"
 +              << "Message: " << Err << " " << IP << "\n";
        // Dequeue
        FetchItem *Tmp = Queue;
        Queue = Queue->Next;
         QueueBack = Queue;
     }
     else
 -   {
 -      End += snprintf(S,sizeof(S)-50,"400 URI Failure\nURI: <UNKNOWN>\n"
 -                    "Message: %s\n",Err.c_str());
 -   }
 +      std::cout << "400 URI Failure\nURI: <UNKNOWN>\nMessage: " << Err << "\n";
 +
     if(FailReason.empty() == false)
 -      End += snprintf(End,sizeof(S)-50 - (End - S),"FailReason: %s\n",FailReason.c_str());
 +      std::cout << "FailReason: " << FailReason << "\n";
     if (UsedMirror.empty() == false)
 -      End += snprintf(End,sizeof(S)-50 - (End - S),"UsedMirror: %s\n",UsedMirror.c_str());
 -   // Set the transient flag 
 +      std::cout << "UsedMirror: " << UsedMirror << "\n";
 +   // Set the transient flag
     if (Transient == true)
 -      strcat(S,"Transient-Failure: true\n\n");
 -   else
 -      strcat(S,"\n");
 -   
 -   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
 -      exit(100);
 +      std::cout << "Transient-Failure: true\n";
 +
 +   std::cout << "\n" << std::flush;
  }
                                                                        /*}}}*/
  // AcqMethod::URIStart - Indicate a download is starting              /*{{{*/
@@@ -121,22 -134,25 +121,22 @@@ void pkgAcqMethod::URIStart(FetchResul
  {
     if (Queue == 0)
        abort();
 -   
 -   char S[1024] = "";
 -   char *End = S;
 -   
 -   End += snprintf(S,sizeof(S),"200 URI Start\nURI: %s\n",Queue->Uri.c_str());
 +
 +   std::cout << "200 URI Start\n"
 +           << "URI: " << Queue->Uri << "\n";
     if (Res.Size != 0)
 -      End += snprintf(End,sizeof(S)-4 - (End - S),"Size: %lu\n",Res.Size);
 -   
 +      std::cout << "Size: " << Res.Size << "\n";
 +
     if (Res.LastModified != 0)
 -      End += snprintf(End,sizeof(S)-4 - (End - S),"Last-Modified: %s\n",
 -                    TimeRFC1123(Res.LastModified).c_str());
 -   
 +      std::cout << "Last-Modified: " << TimeRFC1123(Res.LastModified) << "\n";
 +
     if (Res.ResumePoint != 0)
 -      End += snprintf(End,sizeof(S)-4 - (End - S),"Resume-Point: %lu\n",
 -                    Res.ResumePoint);
 -      
 -   strcat(End,"\n");
 -   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
 -      exit(100);
 +      std::cout << "Resume-Point: " << Res.ResumePoint << "\n";
 +
 +   if (UsedMirror.empty() == false)
 +      std::cout << "UsedMirror: " << UsedMirror << "\n";
 +
 +   std::cout << "\n" << std::flush;
  }
                                                                        /*}}}*/
  // AcqMethod::URIDone - A URI is finished                             /*{{{*/
@@@ -146,65 -162,81 +146,69 @@@ void pkgAcqMethod::URIDone(FetchResult 
  {
     if (Queue == 0)
        abort();
 -   
 -   char S[1024] = "";
 -   char *End = S;
 -   
 -   End += snprintf(S,sizeof(S),"201 URI Done\nURI: %s\n",Queue->Uri.c_str());
 +
 +   std::cout << "201 URI Done\n"
 +           << "URI: " << Queue->Uri << "\n";
  
     if (Res.Filename.empty() == false)
 -      End += snprintf(End,sizeof(S)-50 - (End - S),"Filename: %s\n",Res.Filename.c_str());
 -   
 +      std::cout << "Filename: " << Res.Filename << "\n";
 +
     if (Res.Size != 0)
 -      End += snprintf(End,sizeof(S)-50 - (End - S),"Size: %lu\n",Res.Size);
 -   
 +      std::cout << "Size: " << Res.Size << "\n";
 +
     if (Res.LastModified != 0)
 -      End += snprintf(End,sizeof(S)-50 - (End - S),"Last-Modified: %s\n",
 -                    TimeRFC1123(Res.LastModified).c_str());
 +      std::cout << "Last-Modified: " << TimeRFC1123(Res.LastModified) << "\n";
  
     if (Res.MD5Sum.empty() == false)
 -   {
 -      End += snprintf(End,sizeof(S)-50 - (End - S),"MD5-Hash: %s\n",Res.MD5Sum.c_str());
 -      End += snprintf(End,sizeof(S)-50 - (End - S),"MD5Sum-Hash: %s\n",Res.MD5Sum.c_str());
 -   }
 +      std::cout << "MD5-Hash: " << Res.MD5Sum << "\n"
 +              << "MD5Sum-Hash: " << Res.MD5Sum << "\n";
     if (Res.SHA1Sum.empty() == false)
 -      End += snprintf(End,sizeof(S)-50 - (End - S),"SHA1-Hash: %s\n",Res.SHA1Sum.c_str());
 +      std::cout << "SHA1-Hash: " << Res.SHA1Sum << "\n";
     if (Res.SHA256Sum.empty() == false)
 -      End += snprintf(End,sizeof(S)-50 - (End - S),"SHA256-Hash: %s\n",Res.SHA256Sum.c_str());
 +      std::cout << "SHA256-Hash: " << Res.SHA256Sum << "\n";
+    if (Res.SHA512Sum.empty() == false)
 -      End += snprintf(End,sizeof(S)-50 - (End - S),"SHA512-Hash: %s\n",Res.SHA512Sum.c_str());
++      std::cout << "SHA512-Hash: " << Res.SHA512Sum << "\n";
     if (UsedMirror.empty() == false)
 -      End += snprintf(End,sizeof(S)-50 - (End - S),"UsedMirror: %s\n",UsedMirror.c_str());
 -   if (Res.GPGVOutput.size() > 0)
 -      End += snprintf(End,sizeof(S)-50 - (End - S),"GPGVOutput:\n");     
 -   for (vector<string>::iterator I = Res.GPGVOutput.begin();
 -      I != Res.GPGVOutput.end(); I++)
 -      End += snprintf(End,sizeof(S)-50 - (End - S), " %s\n", (*I).c_str());
 +      std::cout << "UsedMirror: " << UsedMirror << "\n";
 +   if (Res.GPGVOutput.empty() == false)
 +   {
 +      std::cout << "GPGVOutput:\n";
 +      for (vector<string>::const_iterator I = Res.GPGVOutput.begin();
 +         I != Res.GPGVOutput.end(); ++I)
 +       std::cout << " " << *I << "\n";
 +   }
  
     if (Res.ResumePoint != 0)
 -      End += snprintf(End,sizeof(S)-50 - (End - S),"Resume-Point: %lu\n",
 -                    Res.ResumePoint);
 +      std::cout << "Resume-Point: " << Res.ResumePoint << "\n";
  
     if (Res.IMSHit == true)
 -      strcat(End,"IMS-Hit: true\n");
 -   End = S + strlen(S);
 -   
 +      std::cout << "IMS-Hit: true\n";
 +
     if (Alt != 0)
     {
        if (Alt->Filename.empty() == false)
 -       End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-Filename: %s\n",Alt->Filename.c_str());
 -      
 +       std::cout << "Alt-Filename: " << Alt->Filename << "\n";
 +
        if (Alt->Size != 0)
 -       End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-Size: %lu\n",Alt->Size);
 -      
 +       std::cout << "Alt-Size: " << Alt->Size << "\n";
 +
        if (Alt->LastModified != 0)
 -       End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-Last-Modified: %s\n",
 -                       TimeRFC1123(Alt->LastModified).c_str());
 -      
 +       std::cout << "Alt-Last-Modified: " << TimeRFC1123(Alt->LastModified) << "\n";
 +
        if (Alt->MD5Sum.empty() == false)
 -       End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-MD5-Hash: %s\n",
 -                       Alt->MD5Sum.c_str());
 +       std::cout << "Alt-MD5-Hash: " << Alt->MD5Sum << "\n";
        if (Alt->SHA1Sum.empty() == false)
 -       End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-SHA1-Hash: %s\n",
 -                       Alt->SHA1Sum.c_str());
 +       std::cout << "Alt-SHA1-Hash: " << Alt->SHA1Sum << "\n";
        if (Alt->SHA256Sum.empty() == false)
 -       End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-SHA256-Hash: %s\n",
 -                       Alt->SHA256Sum.c_str());
 +       std::cout << "Alt-SHA256-Hash: " << Alt->SHA256Sum << "\n";
+       if (Alt->SHA512Sum.empty() == false)
 -       End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-SHA512-Hash: %s\n",
 -                       Alt->SHA512Sum.c_str());
++         std::cout << "Alt-SHA512-Hash: " << Alt->SHA512Sum << "\n";
+      
        if (Alt->IMSHit == true)
 -       strcat(End,"Alt-IMS-Hit: true\n");
 +       std::cout << "Alt-IMS-Hit: true\n";
     }
 -   
 -   strcat(End,"\n");
 -   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
 -      exit(100);
 +
 +   std::cout << "\n" << std::flush;
  
     // Dequeue
     FetchItem *Tmp = Queue;
     to be ackd */
  bool pkgAcqMethod::MediaFail(string Required,string Drive)
  {
 -   char S[1024];
 -   snprintf(S,sizeof(S),"403 Media Failure\nMedia: %s\nDrive: %s\n\n",
 +   fprintf(stdout, "403 Media Failure\nMedia: %s\nDrive: %s\n",
            Required.c_str(),Drive.c_str());
 +   std::cout << "\n" << std::flush;
  
 -   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
 -      exit(100);
 -   
     vector<string> MyMessages;
     
     /* Here we read messages until we find a 603, each non 603 message is
@@@ -374,34 -409,28 +378,34 @@@ int pkgAcqMethod::Run(bool Single
     return 0;
  }
                                                                        /*}}}*/
 -// AcqMethod::Log - Send a log message                                        /*{{{*/
 +// AcqMethod::PrintStatus - privately really send a log/status message        /*{{{*/
  // ---------------------------------------------------------------------
  /* */
 -void pkgAcqMethod::Log(const char *Format,...)
 +void pkgAcqMethod::PrintStatus(char const * const header, const char* Format,
 +                             va_list &args) const
  {
     string CurrentURI = "<UNKNOWN>";
     if (Queue != 0)
        CurrentURI = Queue->Uri;
 -   
 +   if (UsedMirror.empty() == true)
 +      fprintf(stdout, "%s\nURI: %s\nMessage: ",
 +            header, CurrentURI.c_str());
 +   else
 +      fprintf(stdout, "%s\nURI: %s\nUsedMirror: %s\nMessage: ",
 +            header, CurrentURI.c_str(), UsedMirror.c_str());
 +   vfprintf(stdout,Format,args);
 +   std::cout << "\n\n" << std::flush;
 +}
 +                                                                      /*}}}*/
 +// AcqMethod::Log - Send a log message                                        /*{{{*/
 +// ---------------------------------------------------------------------
 +/* */
 +void pkgAcqMethod::Log(const char *Format,...)
 +{
     va_list args;
     va_start(args,Format);
 -
 -   // sprintf the description
 -   char S[1024];
 -   unsigned int Len = snprintf(S,sizeof(S)-4,"101 Log\nURI: %s\n"
 -                             "Message: ",CurrentURI.c_str());
 -
 -   vsnprintf(S+Len,sizeof(S)-4-Len,Format,args);
 -   strcat(S,"\n\n");
 -   
 -   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
 -      exit(100);
 +   PrintStatus("101 Log", Format, args);
 +   va_end(args);
  }
                                                                        /*}}}*/
  // AcqMethod::Status - Send a status message                          /*{{{*/
  /* */
  void pkgAcqMethod::Status(const char *Format,...)
  {
 -   string CurrentURI = "<UNKNOWN>";
 -   if (Queue != 0)
 -      CurrentURI = Queue->Uri;
 -   
     va_list args;
     va_start(args,Format);
 -
 -   // sprintf the description
 -   char S[1024];
 -   unsigned int Len = snprintf(S,sizeof(S)-4,"102 Status\nURI: %s\n"
 -                             "Message: ",CurrentURI.c_str());
 -
 -   vsnprintf(S+Len,sizeof(S)-4-Len,Format,args);
 -   strcat(S,"\n\n");
 -   
 -   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
 -      exit(100);
 +   PrintStatus("102 Status", Format, args);
 +   va_end(args);
  }
                                                                        /*}}}*/
  // AcqMethod::Redirect - Send a redirect message                       /*{{{*/
     to keep the pipeline synchronized. */
  void pkgAcqMethod::Redirect(const string &NewURI)
  {
 -   string CurrentURI = "<UNKNOWN>";
 +   std::cout << "103 Redirect\nURI: ";
     if (Queue != 0)
 -      CurrentURI = Queue->Uri;
 - 
 -   char S[1024];
 -   snprintf(S, sizeof(S)-50, "103 Redirect\nURI: %s\nNew-URI: %s\n\n",
 -         CurrentURI.c_str(), NewURI.c_str());
 -
 -   if (write(STDOUT_FILENO,S,strlen(S)) != (ssize_t)strlen(S))
 -      exit(100);
 +      std::cout << Queue->Uri << "\n";
 +   else
 +      std::cout << "<UNKNOWN>\n";
 +   std::cout << "New-URI: " << NewURI << "\n"
 +           << "\n" << std::flush;
  
     // Change the URI for the request.
     Queue->Uri = NewURI;
@@@ -460,5 -505,6 +464,6 @@@ void pkgAcqMethod::FetchResult::TakeHas
     MD5Sum = Hash.MD5.Result();
     SHA1Sum = Hash.SHA1.Result();
     SHA256Sum = Hash.SHA256.Result();
+    SHA512Sum = Hash.SHA512.Result();
  }
                                                                        /*}}}*/
diff --combined apt-pkg/acquire-method.h
index 72efa8065491e644370363a2fa7e97f1797c5f67,f6bf83842fe42414e0bae968de855935f51957ad..2d0fa4590d6fc14967139303e03a2821f9ad4fe1
@@@ -23,7 -23,6 +23,7 @@@
  #include <apt-pkg/configuration.h>
  #include <apt-pkg/strutl.h>
  
 +#include <stdarg.h>
  
  class Hashes;
  class pkgAcqMethod
@@@ -46,6 -45,7 +46,7 @@@
        string MD5Sum;
        string SHA1Sum;
        string SHA256Sum;
+       string SHA512Sum;
        vector<string> GPGVOutput;
        time_t LastModified;
        bool IMSHit;
@@@ -79,8 -79,6 +80,8 @@@
     bool MediaFail(string Required,string Drive);
     virtual void Exit() {};
  
 +   void PrintStatus(char const * const header, const char* Format, va_list &args) const;
 +
     public:
     enum CnfFlags {SingleInstance = (1<<0),
                    Pipeline = (1<<1), SendConfig = (1<<2),
diff --combined apt-pkg/makefile
index e6bcf852470dc158f2b21d72136a382c2e92c899,b94b882578b9b5fc64be23f338b58c099fdc070d..b11e35250a55dd22a598dd824df034f88e94e684
@@@ -3,7 -3,7 +3,7 @@@ BASE=.
  SUBDIR=apt-pkg
  
  # Header location
 -SUBDIRS = deb contrib
 +SUBDIRS = deb edsp contrib
  HEADER_TARGETDIRS = apt-pkg
  
  # Bring in the default rules
@@@ -20,11 -20,15 +20,15 @@@ APT_DOMAIN:=libapt-pkg$(LIBAPTPKG_MAJOR
  # Source code for the contributed non-core things
  SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \
           contrib/configuration.cc contrib/progress.cc contrib/cmndline.cc \
-        contrib/md5.cc contrib/sha1.cc contrib/sha256.cc contrib/hashes.cc \
+        contrib/md5.cc contrib/sha1.cc contrib/sha2.cc  \
+        contrib/sha2_internal.cc\
+          contrib/hashes.cc \
         contrib/cdromutl.cc contrib/crc-16.cc contrib/netrc.cc \
         contrib/fileutl.cc 
  HEADERS = mmap.h error.h configuration.h fileutl.h  cmndline.h netrc.h\
-         md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha256.h hashes.h \
+         md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha2.h \
+         sha2_internal.h \
+           hashes.h hashsum_template.h\
          macros.h weakptr.h
  
  # Source code for the core main library
@@@ -35,7 -39,7 +39,7 @@@ SOURCE+= pkgcache.cc version.cc depcach
         srcrecords.cc cachefile.cc versionmatch.cc policy.cc \
         pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \
         indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \
 -       aptconfiguration.cc cachefilter.cc cacheset.cc
 +       aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc
  HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \
          orderlist.h sourcelist.h packagemanager.h tagfile.h \
          init.h pkgcache.h version.h progress.h pkgrecords.h \
@@@ -43,7 -47,7 +47,7 @@@
          clean.h srcrecords.h cachefile.h versionmatch.h policy.h \
          pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \
          vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \
 -        cachefilter.h cacheset.h
 +        cachefilter.h cacheset.h edsp.h
  
  # Source code for the debian specific components
  # In theory the deb headers do not need to be exported..
@@@ -53,10 -57,6 +57,10 @@@ SOURCE+= deb/deblistparser.cc deb/debre
  HEADERS+= debversion.h debsrcrecords.h dpkgpm.h debrecords.h \
          deblistparser.h debsystem.h debindexfile.h debmetaindex.h
  
 +# Source code for the APT resolver interface specific components
 +SOURCE+= edsp/edsplistparser.cc edsp/edspindexfile.cc edsp/edspsystem.cc
 +HEADERS+= edsplistparser.h edspindexfile.h edspsystem.h
 +
  HEADERS := $(addprefix apt-pkg/,$(HEADERS))
  
  include $(LIBRARY_H)
diff --combined cmdline/apt-get.cc
index 65eaef0d84d298bb492f80ac2dbebb0cfb71704b,61efa5601e42c0adab34710853749b2ec303b2c9..66ebd30b817ee0e9cd8e8c8ee9cdd79f460e716c
@@@ -382,6 -382,8 +382,6 @@@ void ShowNew(ostream &out,CacheFile &Ca
     {
        pkgCache::PkgIterator I(Cache,Cache.List[J]);
        if (Cache[I].NewInstall() == true) {
 -       if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
 -          continue;
           List += I.FullName(true) + " ";
           VersionsList += string(Cache[I].CandVersion) + "\n";
        }
@@@ -404,6 -406,8 +404,6 @@@ void ShowDel(ostream &out,CacheFile &Ca
        pkgCache::PkgIterator I(Cache,Cache.List[J]);
        if (Cache[I].Delete() == true)
        {
 -       if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
 -          continue;
         if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
            List += I.FullName(true) + "* ";
         else
@@@ -452,6 -456,8 +452,6 @@@ void ShowUpgraded(ostream &out,CacheFil
        // Not interesting
        if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
         continue;
 -      if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
 -       continue;
  
        List += I.FullName(true) + " ";
        VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
@@@ -473,6 -479,8 +473,6 @@@ bool ShowDowngraded(ostream &out,CacheF
        // Not interesting
        if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true)
         continue;
 -      if (Cache[I].CandidateVerIter(Cache).Pseudo() == true)
 -       continue;
  
        List += I.FullName(true) + " ";
        VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
@@@ -576,6 -584,9 +576,6 @@@ void Stats(ostream &out,pkgDepCache &De
     unsigned long ReInstall = 0;
     for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++)
     {
 -      if (pkgCache::VerIterator(Dep, Dep[I].CandidateVer).Pseudo() == true)
 -       continue;
 -
        if (Dep[I].NewInstall() == true)
         Install++;
        else
@@@ -764,7 -775,7 +764,7 @@@ struct TryToInstall 
     unsigned long AutoMarkChanged;
     APT::PackageSet doAutoInstallLater;
  
 -   TryToInstall(pkgCacheFile &Cache, pkgProblemResolver &PM, bool const &FixBroken) : Cache(&Cache), Fix(&PM),
 +   TryToInstall(pkgCacheFile &Cache, pkgProblemResolver *PM, bool const &FixBroken) : Cache(&Cache), Fix(PM),
                        FixBroken(FixBroken), AutoMarkChanged(0) {};
  
     void operator() (pkgCache::VerIterator const &Ver) {
         ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
                  Pkg.FullName(true).c_str());
        else {
 -       Fix->Clear(Pkg);
 -       Fix->Protect(Pkg);
 +       if (Fix != NULL) {
 +          Fix->Clear(Pkg);
 +          Fix->Protect(Pkg);
 +       }
         Cache->GetDepCache()->MarkInstall(Pkg,false);
  
         if (State.Install() == false) {
@@@ -873,27 -882,20 +873,27 @@@ struct TryToRemove 
     bool PurgePkgs;
     unsigned long AutoMarkChanged;
  
 -   TryToRemove(pkgCacheFile &Cache, pkgProblemResolver &PM) : Cache(&Cache), Fix(&PM),
 +   TryToRemove(pkgCacheFile &Cache, pkgProblemResolver *PM) : Cache(&Cache), Fix(PM),
                                PurgePkgs(_config->FindB("APT::Get::Purge", false)) {};
  
     void operator() (pkgCache::VerIterator const &Ver)
     {
        pkgCache::PkgIterator Pkg = Ver.ParentPkg();
  
 -      Fix->Clear(Pkg);
 -      Fix->Protect(Pkg);
 -      Fix->Remove(Pkg);
 +      if (Fix != NULL)
 +      {
 +       Fix->Clear(Pkg);
 +       Fix->Protect(Pkg);
 +       Fix->Remove(Pkg);
 +      }
  
        if ((Pkg->CurrentVer == 0 && PurgePkgs == false) ||
          (PurgePkgs == true && Pkg->CurrentState == pkgCache::State::NotInstalled))
 +      {
         ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.FullName(true).c_str());
 +       // MarkInstall refuses to install packages on hold
 +       Pkg->SelectedState = pkgCache::State::Hold;
 +      }
        else
         Cache->GetDepCache()->MarkDelete(Pkg, PurgePkgs);
     }
@@@ -1390,10 -1392,10 +1390,10 @@@ bool TryToInstallBuildDep(pkgCache::Pkg
  
     if (Remove == true)
     {
 -      TryToRemove RemoveAction(Cache, Fix);
 +      TryToRemove RemoveAction(Cache, &Fix);
        RemoveAction(Pkg.VersionList());
     } else if (Cache[Pkg].CandidateVer != 0) {
 -      TryToInstall InstallAction(Cache, Fix, BrokenFix);
 +      TryToInstall InstallAction(Cache, &Fix, BrokenFix);
        InstallAction(Cache[Pkg].CandidateVerIter(Cache));
        InstallAction.doAutoInstall();
     } else
@@@ -1653,7 -1655,6 +1653,7 @@@ bool DoAutomaticRemove(CacheFile &Cache
  
     string autoremovelist, autoremoveversions;
     unsigned long autoRemoveCount = 0;
 +   APT::PackageSet tooMuch;
     // look over the cache to see what can be removed
     for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg)
     {
            // if the package is a new install and already garbage we don't need to
            // install it in the first place, so nuke it instead of show it
            if (Cache[Pkg].Install() == true && Pkg.CurrentVer() == 0)
 +          {
               Cache->MarkDelete(Pkg, false);
 +             tooMuch.insert(Pkg);
 +          }
            // only show stuff in the list that is not yet marked for removal
            else if(hideAutoRemove == false && Cache[Pkg].Delete() == false) 
            {
        }
     }
  
 +   // we could have removed a new dependency of a garbage package,
 +   // so check if a reverse depends is broken and if so install it again.
 +   if (tooMuch.empty() == false && Cache->BrokenCount() != 0)
 +   {
 +      bool Changed;
 +      do {
 +       Changed = false;
 +       for (APT::PackageSet::const_iterator P = tooMuch.begin();
 +            P != tooMuch.end() && Changed == false; ++P)
 +       {
 +          for (pkgCache::DepIterator R = P.RevDependsList();
 +               R.end() == false; ++R)
 +          {
 +             if (R->Type != pkgCache::Dep::Depends &&
 +                 R->Type != pkgCache::Dep::PreDepends)
 +                continue;
 +             pkgCache::PkgIterator N = R.ParentPkg();
 +             if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
 +                continue;
 +             if (Debug == true)
 +                std::clog << "Save " << P << " as another installed garbage package depends on it" << std::endl;
 +             Cache->MarkInstall(P, false);
 +             if(hideAutoRemove == false)
 +             {
 +                ++autoRemoveCount;
 +                if (smallList == false)
 +                {
 +                   autoremovelist += P.FullName(true) + " ";
 +                   autoremoveversions += string(Cache[P].CandVersion) + "\n";
 +                }
 +             }
 +             tooMuch.erase(P);
 +             Changed = true;
 +             break;
 +          }
 +       }
 +      } while (Changed == true);
 +   }
 +
     // Now see if we had destroyed anything (if we had done anything)
     if (Cache->BrokenCount() != 0)
     {
@@@ -1796,10 -1755,8 +1796,10 @@@ bool DoInstall(CommandLine &CmdL
     bool BrokenFix = false;
     if (Cache->BrokenCount() != 0)
        BrokenFix = true;
 -   
 -   pkgProblemResolver Fix(Cache);
 +
 +   pkgProblemResolver* Fix = NULL;
 +   if (_config->FindB("APT::Get::CallResolver", true) == true)
 +      Fix = new pkgProblemResolver(Cache);
  
     static const unsigned short MOD_REMOVE = 1;
     static const unsigned short MOD_INSTALL = 2;
     if (_error->PendingError() == true)
     {
        helper.showVirtualPackageErrors(Cache);
 +      if (Fix != NULL)
 +       delete Fix;
        return false;
     }
  
 -   unsigned short order[] = { 0, 0, 0 };
 -   if (fallback == MOD_INSTALL) {
 -      order[0] = MOD_INSTALL;
 -      order[1] = MOD_REMOVE;
 -   } else {
 -      order[0] = MOD_REMOVE;
 -      order[1] = MOD_INSTALL;
 -   }
 +   unsigned short const order[] = { MOD_REMOVE, MOD_INSTALL, 0 };
  
    TryToInstall InstallAction(Cache, Fix, BrokenFix);
    TryToRemove RemoveAction(Cache, Fix);
  
        for (unsigned short i = 0; order[i] != 0; ++i)
        {
 -       if (order[i] == MOD_INSTALL) {
 +       if (order[i] == MOD_INSTALL)
            InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction);
 +       else if (order[i] == MOD_REMOVE)
 +          RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction);
 +      }
 +
 +      if (Fix != NULL && _config->FindB("APT::Get::AutoSolving", true) == true)
 +      {
 +         for (unsigned short i = 0; order[i] != 0; ++i)
 +         {
 +          if (order[i] != MOD_INSTALL)
 +             continue;
            InstallAction.propergateReleaseCandiateSwitching(helper.selectedByRelease, c0out);
            InstallAction.doAutoInstall();
         }
 -       else if (order[i] == MOD_REMOVE)
 -          RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction);
        }
  
        if (_error->PendingError() == true)
 +      {
 +       if (Fix != NULL)
 +          delete Fix;
         return false;
 +      }
  
        /* If we are in the Broken fixing mode we do not attempt to fix the
         problems. This is if the user invoked install without -f and gave
        {
         c1out << _("You might want to run 'apt-get -f install' to correct these:") << endl;
         ShowBroken(c1out,Cache,false);
 -
 +       if (Fix != NULL)
 +          delete Fix;
         return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
        }
 -   
 -      // Call the scored problem resolver
 -      Fix.InstallProtect();
 -      if (Fix.Resolve(true) == false)
 -       _error->Discard();
 +
 +      if (Fix != NULL)
 +      {
 +       // Call the scored problem resolver
 +       Fix->InstallProtect();
 +       Fix->Resolve(true);
 +       delete Fix;
 +      }
  
        // Now we check the state of the packages,
        if (Cache->BrokenCount() != 0)
         c1out << _("The following information may help to resolve the situation:") << endl;
         c1out << endl;
         ShowBroken(c1out,Cache,false);
 -       return _error->Error(_("Broken packages"));
 -      }   
 +       if (_error->PendingError() == true)
 +          return false;
 +       else
 +          return _error->Error(_("Broken packages"));
 +      }
     }
     if (!DoAutomaticRemove(Cache)) 
        return false;
         if ((*Cache)[I].Install() == false)
            continue;
         pkgCache::VerIterator Cand = Cache[I].CandidateVerIter(Cache);
 -       if (Cand.Pseudo() == true)
 -          continue;
  
         if (verset[MOD_INSTALL].find(Cand) != verset[MOD_INSTALL].end())
            continue;
  
     return InstallPackages(Cache,false);   
  }
 -
 -/* mark packages as automatically/manually installed. */
 +                                                                      /*}}}*/
 +/* mark packages as automatically/manually installed.                 {{{*/
  bool DoMarkAuto(CommandLine &CmdL)
  {
     bool Action = true;
           AutoMarkChanged++;
        }
     }
 +
 +   _error->Notice(_("This command is deprecated. Please use 'apt-mark auto' and 'apt-mark manual' instead."));
 +
     if (AutoMarkChanged && ! _config->FindB("APT::Get::Simulate",false))
        return Cache->writeStateFile(NULL);
     return false;
@@@ -2269,15 -2211,13 +2269,15 @@@ bool DoDownload(CommandLine &CmdL
     APT::CacheSetHelper helper(c0out);
     APT::VersionSet verset = APT::VersionSet::FromCommandLine(Cache,
                CmdL.FileList + 1, APT::VersionSet::CANDIDATE, helper);
 -   pkgAcquire Fetcher;
 -   AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0));
 -   Fetcher.Setup(&Stat);
  
     if (verset.empty() == true)
        return false;
  
 +   pkgAcquire Fetcher;
 +   AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0));
 +   if (_config->FindB("APT::Get::Print-URIs") == true)
 +      Fetcher.Setup(&Stat);
 +
     pkgRecords Recs(Cache);
     pkgSourceList *SrcList = Cache.GetSourceList();
     for (APT::VersionSet::const_iterator Ver = verset.begin(); 
        strprintf(descr, _("Downloading %s %s"), Pkg.Name(), Ver.VerStr());
        // get the most appropriate hash
        HashString hash;
+       if (rec.SHA512Hash() != "")
+          hash = HashString("sha512", rec.SHA512Hash());
        if (rec.SHA256Hash() != "")
           hash = HashString("sha256", rec.SHA256Hash());
        else if (rec.SHA1Hash() != "")
        // get the file
        new pkgAcqFile(&Fetcher, uri, hash.toStr(), (*Ver)->Size, descr, Pkg.Name(), ".");
     }
 -   bool result = (Fetcher.Run() == pkgAcquire::Continue);
  
 -   return result;
 +   // Just print out the uris and exit if the --print-uris flag was used
 +   if (_config->FindB("APT::Get::Print-URIs") == true)
 +   {
 +      pkgAcquire::UriIterator I = Fetcher.UriBegin();
 +      for (; I != Fetcher.UriEnd(); I++)
 +       cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
 +             I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
 +      return true;
 +   }
 +
 +   return (Fetcher.Run() == pkgAcquire::Continue);
  }
                                                                        /*}}}*/
  // DoCheck - Perform the check operation                              /*{{{*/
@@@ -2391,10 -2324,8 +2393,10 @@@ bool DoSource(CommandLine &CmdL
        string Src;
        pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
        
 -      if (Last == 0)
 +      if (Last == 0) {
 +       delete[] Dsc;
         return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
 +      }
        
        string srec = Last->AsStr();
        string::size_type pos = srec.find("\nVcs-");
  
        // Back track
        vector<pkgSrcRecords::File> Lst;
 -      if (Last->Files(Lst) == false)
 +      if (Last->Files(Lst) == false) {
 +       delete[] Dsc;
         return false;
 +      }
  
        // Load them into the fetcher
        for (vector<pkgSrcRecords::File>::const_iterator I = Lst.begin();
     struct statvfs Buf;
     string OutputDir = ".";
     if (statvfs(OutputDir.c_str(),&Buf) != 0) {
 +      delete[] Dsc;
        if (errno == EOVERFLOW)
         return _error->WarningE("statvfs",_("Couldn't determine free space in %s"),
                                OutputDir.c_str());
  #if HAVE_STRUCT_STATFS_F_TYPE
             || unsigned(Stat.f_type) != RAMFS_MAGIC
  #endif
 -           ) 
 +           )  {
 +       delete[] Dsc;
            return _error->Error(_("You don't have enough free space in %s"),
                OutputDir.c_str());
 -      }
 +       }
 +     }
     
     // Number of bytes
     if (DebBytes != FetchBytes)
     
     // Run it
     if (Fetcher.Run() == pkgAcquire::Failed)
 +   {
 +      delete[] Dsc;
        return false;
 +   }
  
     // Print error messages
     bool Failed = false;
        Failed = true;
     }
     if (Failed == true)
 +   {
 +      delete[] Dsc;
        return _error->Error(_("Failed to fetch some archives."));
 -   
 +   }
 +
     if (_config->FindB("APT::Get::Download-only",false) == true)
     {
        c1out << _("Download complete and in download only mode") << endl;
  bool DoBuildDep(CommandLine &CmdL)
  {
     CacheFile Cache;
 +
 +   _config->Set("APT::Install-Recommends", false);
 +   
     if (Cache.Open(true) == false)
        return false;
  
@@@ -2964,7 -2881,6 +2966,7 @@@ bool GuessThirdPartyChangelogUri(CacheF
     // now strip away the filename and add srcpkg_srcver.changelog
     return true;
  }
 +                                                                      /*}}}*/
  // DownloadChangelog - Download the changelog                                 /*{{{*/
  // ---------------------------------------------------------------------
  bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, 
                            "http://packages.debian.org/changelogs");
     path = GetChangelogPath(CacheFile, Pkg, Ver);
     strprintf(changelog_uri, "%s/%s/changelog", server.c_str(), path.c_str());
 +   if (_config->FindB("APT::Get::Print-URIs", false) == true)
 +   {
 +      std::cout << '\'' << changelog_uri << '\'' << std::endl;
 +      return true;
 +   }
 +
     strprintf(descr, _("Changelog for %s (%s)"), Pkg.Name(), changelog_uri.c_str());
     // queue it
     new pkgAcqFile(&Fetcher, changelog_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile);
  
 -   // try downloading it, if that fails, they third-party-changelogs location
 -   // FIXME: res is "Continue" even if I get a 404?!?
 -   int res = Fetcher.Run();
 +   // try downloading it, if that fails, try third-party-changelogs location
 +   // FIXME: Fetcher.Run() is "Continue" even if I get a 404?!?
 +   Fetcher.Run();
     if (!FileExists(targetfile))
     {
        string third_party_uri;
        {
           strprintf(descr, _("Changelog for %s (%s)"), Pkg.Name(), third_party_uri.c_str());
           new pkgAcqFile(&Fetcher, third_party_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile);
 -         res = Fetcher.Run();
 +         Fetcher.Run();
        }
     }
  
@@@ -3049,53 -2959,30 +3051,53 @@@ bool DoChangelog(CommandLine &CmdL
     APT::CacheSetHelper helper(c0out);
     APT::VersionSet verset = APT::VersionSet::FromCommandLine(Cache,
                CmdL.FileList + 1, APT::VersionSet::CANDIDATE, helper);
 +   if (verset.empty() == true)
 +      return false;
     pkgAcquire Fetcher;
 +
 +   if (_config->FindB("APT::Get::Print-URIs", false) == true)
 +      for (APT::VersionSet::const_iterator Ver = verset.begin();
 +         Ver != verset.end(); ++Ver)
 +       return DownloadChangelog(Cache, Fetcher, Ver, "");
 +
     AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0));
     Fetcher.Setup(&Stat);
  
 -   if (verset.empty() == true)
 -      return false;
 -   char *tmpdir = mkdtemp(strdup("/tmp/apt-changelog-XXXXXX"));
 -   if (tmpdir == NULL) {
 -      return _error->Errno("mkdtemp", "mkdtemp failed");
 +   bool const downOnly = _config->FindB("APT::Get::Download-Only", false);
 +
 +   char tmpname[100];
 +   char* tmpdir = NULL;
 +   if (downOnly == false)
 +   {
 +      const char* const tmpDir = getenv("TMPDIR");
 +      if (tmpDir != NULL && *tmpDir != '\0')
 +       snprintf(tmpname, sizeof(tmpname), "%s/apt-changelog-XXXXXX", tmpDir);
 +      else
 +       strncpy(tmpname, "/tmp/apt-changelog-XXXXXX", sizeof(tmpname));
 +      tmpdir = mkdtemp(tmpname);
 +      if (tmpdir == NULL)
 +       return _error->Errno("mkdtemp", "mkdtemp failed");
     }
 -   
 +
     for (APT::VersionSet::const_iterator Ver = verset.begin(); 
          Ver != verset.end(); 
          ++Ver) 
     {
 -      string changelogfile = string(tmpdir) + "changelog";
 -      if (DownloadChangelog(Cache, Fetcher, Ver, changelogfile))
 +      string changelogfile;
 +      if (downOnly == false)
 +       changelogfile.append(tmpname).append("changelog");
 +      else
 +       changelogfile.append(Ver.ParentPkg().Name()).append(".changelog");
 +      if (DownloadChangelog(Cache, Fetcher, Ver, changelogfile) && downOnly == false)
 +      {
           DisplayFileInPager(changelogfile);
 -      // cleanup temp file
 -      unlink(changelogfile.c_str());
 +         // cleanup temp file
 +         unlink(changelogfile.c_str());
 +      }
     }
     // clenaup tmp dir
 -   rmdir(tmpdir);
 -   free(tmpdir);
 +   if (tmpdir != NULL)
 +      rmdir(tmpdir);
     return true;
  }
                                                                        /*}}}*/
@@@ -3189,6 -3076,8 +3191,6 @@@ bool ShowHelp(CommandLine &CmdL
        "   clean - Erase downloaded archive files\n"
        "   autoclean - Erase old downloaded archive files\n"
        "   check - Verify that there are no broken dependencies\n"
 -      "   markauto - Mark the given packages as automatically installed\n"
 -      "   unmarkauto - Mark the given packages as manually installed\n"
        "   changelog - Download and display the changelog for the given package\n"
        "   download - Download the binary package into the current directory\n"
        "\n"
@@@ -3270,9 -3159,7 +3272,9 @@@ int main(int argc,const char *argv[]
        {0,"auto-remove","APT::Get::AutomaticRemove",0},
        {0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0},
        {0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean},
 +      {0,"install-suggests","APT::Install-Suggests",CommandLine::Boolean},
        {0,"fix-policy","APT::Get::Fix-Policy-Broken",0},
 +      {0,"solver","APT::Solver",CommandLine::HasArg},
        {'c',"config-file",0,CommandLine::ConfigFile},
        {'o',"option",0,CommandLine::ArbItem},
        {0,0,0,0}};
     }
  
     // simulate user-friendly if apt-get has no root privileges
 -   if (getuid() != 0 && _config->FindB("APT::Get::Simulate") == true)
 +   if (getuid() != 0 && _config->FindB("APT::Get::Simulate") == true &&
 +      (CmdL.FileSize() == 0 ||
 +       (strcmp(CmdL.FileList[0], "source") != 0 && strcmp(CmdL.FileList[0], "download") != 0 &&
 +        strcmp(CmdL.FileList[0], "changelog") != 0)))
     {
        if (_config->FindB("APT::Get::Show-User-Simulation-Note",true) == true)
         cout << _("NOTE: This is only a simulation!\n"
diff --combined debian/changelog
index 71f64dc2347dcbf5f2f78b54082616605245a1c4,986b6f87615a5f3f36cf7f5b4cb9e01107429b79..b144d35ad05e8a03b29d6bcd9e50132ad61b202e
 -apt (0.8.12) UNRELEASED; urgency=low
 +apt (0.8.15) UNRELEASED; urgency=low
 +
 +  [ David Kalnischkies ]
 +  * Implement EDSP in libapt-pkg so that all front-ends which
 +    use the internal resolver can now be used also with external
 +    ones as the usage is hidden in between the old API
 +  * provide two edsp solvers in apt-utils:
 +    - 'dump' to quickly output a complete scenario and
 +    - 'apt' to use the internal as an external resolver
 +  * apt-pkg/pkgcache.h:
 +    - clean up mess with the "all" handling in MultiArch to
 +      fix LP: #733741 cleanly for everyone now
 +  * apt-pkg/depcache.cc:
 +    - use a boolean instead of an int for Add/Remove in AddStates
 +      similar to how it works with AddSizes
 +    - let the Mark methods return if their marking was successful
 +    - if a Breaks can't be upgraded, remove it. If it or a Conflict
 +      can't be removed the installation of the breaker fails.
 +  * cmdline/apt-get.cc:
 +    - do not discard the error messages from the resolver and instead
 +      only show the general 'Broken packages' message if nothing else
 +
 +  [ Stefano Zacchiroli ]
 +  * doc/external-dependency-solver-protocol.txt:
 +    - describe EDSP and the configuration interface around it
++  
++  [ Michael Vogt ]
++  * merge lp:~mvo/apt/sha512-template to add support for sha512
 +
 + -- David Kalnischkies <kalnischkies@gmail.com>  Tue, 17 May 2011 18:43:21 +0200
 +
 +apt (0.8.14.2) UNRELEASED; urgency=low
 +
 +  [ Julian Andres Klode ]
 +  * apt-pkg/depcache.cc:
 +    - Really release action groups only once (Closes: #622744)
 +    - Make purge work again for config-files (LP: #244598) (Closes: #150831)
 +  * debian/apt.cron.daily:
 +    - Check power after wait, patch by manuel-soto (LP: #705269)
 +  * debian/control:
 +    - Move ${shlibs:Depends} to Pre-Depends, as we do not want APT
 +      unpacked if a library is too old and thus break upgrades
 +  * doc/apt-key.8.xml:
 +    - Document apt-key net-update (LP: #192810)
 +
 +  [ Christian Perrier ]
 +  * Galician translation update (Miguel Anxo Bouzada). Closes: #626505
 +
 +  [ David Kalnischkies ]
 +  * fix a bunch of cppcheck warnings/errors based on a patch by
 +    Niels Thykier, thanks! (Closes: #622805)
 +  * apt-pkg/depcache.cc:
 +    - really include 'rc' packages in the delete count by fixing a
 +      typo which exists since 1999 in the source… (LP: #761175)
 +    - if critical or-group can't be satisfied, exit directly.
 +  * apt-pkg/acquire-method.cc:
 +    - write directly to stdout instead of creating the message in
 +      memory first before writing to avoid hitting limits
 +    - fix order of CurrentURI and UsedMirror in Status() and Log()
 +  * apt-pkg/orderlist.cc:
 +    - let VisitRProvides report if the calls were successful
 +  * apt-pkg/deb/dpkgpm.cc:
 +    - replace obsolete usleep with nanosleep
 +  * debian/apt{,-utils}.symbols:
 +    - update both experimental symbol-files to reflect 0.8.14 state
 +  * debian/rules:
 +    - remove unused embedded jquery by doxygen from libapt-pkg-doc
 +  * cmdline/apt-mark.cc:
 +    - reimplement apt-mark in c++
 +    - provide a 'showmanual' command (Closes: #582791)
 +    - provide a 'dpkg --set-selections' wrapper to set/release holds
 +  * cmdline/apt-get.cc:
 +    - deprecate mostly undocumented 'markauto' in favor of 'apt-mark'
 +  * cmdline/apt-cache.cc:
 +    - deprecate mostly undocumented 'showauto' in favor of 'apt-mark'
 +  * apt-pkg/pkgcache.cc:
 +    - really ignore :arch in FindPkg() in non-multiarch environment
 +  * doc/po/de.po:
 +    - undo the translation of the command 'dump' in manpage of apt-config
 +      as report by Burghard Grossmann on debian-l10n-german, thanks!
 +  * apt-pkg/deb/debmetaindex.cc:
 +    - do not download TranslationIndex if no Translation-* will be
 +      downloaded later on anyway (Closes: #624218)
 +  * test/versions.lst:
 +    - disable obscure version number tests with versions dpkg doesn't
 +      allow any more as they don't start with a number
 +  * apt-pkg/acquire-worker.cc:
 +    - print filename in the unmatching size warning (Closes: #623137)
 +  * apt-pkg/acquire-item.cc:
 +    - apply fix for poorly worded 'locate file' error message from
 +      Ben Finney, thanks! (Closes: #623171)
 +  * methods/http.cc:
 +    - add config option to ignore a closed stdin to be able to easily
 +      use the method as a simple standalone downloader
 +    - Location header in redirects should be absolute URI, but some
 +      servers just send an absolute path so still deal with it properly
 +    - dequote URL taken from Location in redirects as we will otherwise
 +      quote an already quoted string in the request later (Closes: #602412)
 +  * apt-pkg/contrib/netrc.cc:
 +    - replace non-posix gnu-extension strdupa with strdup
 +  * apt-pkg/packagemanager.cc:
 +    - ensure for Multi-Arch:same packages that they are unpacked in
 +      lock step even in immediate configuration (Closes: #618288)
 +
 + -- Michael Vogt <mvo@debian.org>  Mon, 16 May 2011 14:57:52 +0200
 +
 +apt (0.8.14.1) unstable; urgency=low
 +
 +  * apt-pkg/acquire-item.cc:
 +    - Only try to rename existing Release files (Closes: #622912)
 +
 + -- Julian Andres Klode <jak@debian.org>  Sat, 16 Apr 2011 14:36:10 +0200
 +
 +apt (0.8.14) unstable; urgency=low
 +
 +  [ Julian Andres Klode ]
 +  * apt-pkg/indexcopy.cc:
 +    - Use RealFileExists() instead of FileExists(), allows amongst other
 +      things a directory named Sources to exist on a CD-ROM (LP: #750694).
 +  * apt-pkg/acquire-item.cc:
 +    - Use Release files even if they cannot be verified (LP: #704595)
 +  * cmdline/apt-get.cc:
 +    - Do not install recommends for build-dep (Closes: #454479) (LP: #245273)
 +  * apt-pkg/deb/deblistparser.cc:
 +    - Handle no space before "[" in build-dependencies (LP: #72344)
 +  * apt-pkg/policy.cc:
 +    - Allow pinning by glob() expressions, and regular expressions
 +      surrounded by slashes (the "/" character) (LP: #399474)
 +      (Closes: #121132)
 +  * debian/control:
 +    - Set Standards-Version to 3.9.2
 +  
 +  [ Michael Vogt ]
 +  * mirror method:
 +    - do not crash if the mirror file fails to download
 +  * apt-pkg/aptconfiguration.cc:
 +    - fix comparing for a empty string
 +  * debian/apt.cron.daily:
 +    - run unattended-upgrades even if there was a error during
 +      the apt-get update (LP: #676295)
 +
 +  [ David Kalnischkies ]
 +  * apt-pkg/pkgcache.cc:
 +    - use the native Architecture stored in the cache header instead of
 +      loading it from configuration as suggested by Julian Andres Klode
 +
 + -- Julian Andres Klode <jak@debian.org>  Fri, 15 Apr 2011 14:28:15 +0200
 +
 +apt (0.8.13.2) unstable; urgency=low
 +
 +  [ David Kalnischkies ]
 +  * apt-pkg/deb/dpkgpm.cc:
 +    - skip --configure if all packages disappeared
 +  * apt-pkg/vendor.cc, apt-pkg/vendorlist.cc:
 +    - mark them as deprecated as they are unused
 +  * apt-pkg/deb/deblistparser.h:
 +    - enable StripMultiArch by default for ParseDepends
 +  * debian/apt.conf.autoremove:
 +    - adapt to new gnumach kernel package naming (Closes: #619337)
 +  * doc/apt_preferences.5.xml:
 +    - correct typo spotted by Charles Plessy (Closes: #619088)
 +    - document ButAutomaticUpgrades together with NotAutomatic
 +      as suggested by Charles Plessy (Closes: #619083)
 +  * apt-pkg/depcache.cc:
 +    - remove pseudo handling leftover from SetReInstall
 +    - do not change protected packages in autoinstall (Closes: #618848)
 +  * apt-pkg/pkgcachegen.cc:
 +    - make "all"->"native" an implementation detail of NewPackage
 +      rather than rewrite it in higher methods
 +  * apt-pkg/cacheiterator.h:
 +    - return "all" instead of native architecture without breaking the abi
 +      (too much) by extending enum instead of using bitflags (LP: #733741)
 +  * apt-pkg/aptconfiguration.cc:
 +    - use dpkg --print-foreign-architectures to get multiarch configuration
 +      if non is specified with APT::Architectures (Closes: #612958)
 +  * cmdline/apt-get.cc:
 +    - do not show simulation notice for non-root commands (Closes: #619072)
 +    - be able to disable resolver with APT::Get::CallResolver and disable
 +      auto installation with APT::Get::AutoSolving
 +  * apt-pkg/deb/deblistparser.cc:
 +    - create foo:any provides for all architectures for an allowed package
 +
 + -- Michael Vogt <mvo@debian.org>  Tue, 05 Apr 2011 09:40:28 +0200
 +
 +apt (0.8.13.1) unstable; urgency=low
 +
 +  * apt-pkg/acquire-item.cc: Use stat buffer if stat was
 +    successful, not if it failed (Closes: #620546)
 +
 + -- Julian Andres Klode <jak@debian.org>  Sat, 02 Apr 2011 20:55:35 +0200
 +
 +apt (0.8.13) unstable; urgency=low
 +
 +  [ Thorsten Spindler ]
 +  * methods/rsh.cc
 +    - fix rsh/ssh option parsing (LP: #678080), thanks to
 +      Ville Mattila 
 +  
 +  [ Michael Vogt ]
 +  * apt-pkg/acquire-item.cc:
 +    - mark pkgAcqIndexTrans as Index-File to avoid asking the
 +      user to insert the CD on each apt-get update
 +  * po/sl.po:
 +    - updated, thanks to Andrej Znidarsic
 +  * mirror method:
 +    - when downloading data, show the mirror being used
 +    - randomize mirror list after download in a host specific way
 +      to ensure that the load is evenly spreaded accross the mirrors
 +    - fix some missing "Fail-Ignore"
 +
 + -- Michael Vogt <mvo@debian.org>  Wed, 16 Mar 2011 08:04:42 +0100
 +
 +apt (0.8.12) unstable; urgency=low
 +
 +  [ Michael Vogt ]
 +  * apt-pkg/deb/debindexfile.cc:
 +    - ignore missing deb-src files in /var/lib/apt/lists, thanks
 +      to Thorsten Spindler (LP: #85590)
 +  * apt-pkg/contrib/fileutl.cc, apt-pkg/deb/dpkgpm.cc:
 +    - honor Dpkg::Chroot-Directory in the RunScripts*() methods
 +  * apt-pkg/contrib/cdromutl.{cc,h}, apt-pkg/cdrom.{cc,h}:
 +    - deal with missing FSTAB_DIR when using libudev to discover cdrom
 +    - add experimental APT::cdrom::CdromOnly option (on by default). 
 +      When this is set to false apt-cdrom will handle any removable
 +      deivce (like a usb-stick) as a "cdrom/dvd" source
 +
 +  [ Christian Perrier ]
 +  * Fix error in French translation of manpages (apt_preferences(5)).
 +    Merci, Rémi Vanicat. Closes: #613689
 +  * Complete French manpage translation
 +  * Italian translation update (Milo Casagrande). Closes: #614395
 +
 +  [ David Kalnischkies ]
 +  * ftparchive/multicompress.cc, apt-inst/deb/debfile.cc:
 +    - support xz compressor to create xz-compressed Indexes and be able
 +      to open data.tar.xz files
 +    - load the supported compressors from configuration
 +  * ftparchive/writer.cc:
 +    - ensure that Date and Valid-Until time strings are not localised
 +    - add options to disable specific checksums for Indexes
 +    - include xz-compressed Packages and Sources files in Release file
 +  * apt-pkg/aptconfiguration.cc:
 +    - support download of xz-compressed indexes files
 +    - support adding new compressors by configuration
 +  * apt-pkg/deb/debsrcrecords.cc:
 +    - support xz-compressed source v3 debian.tar files
 +    - support every compression we have a compressor configured
 +  * ftparchive/contents.cc:
 +    - remove ExtractArchive codecopy from apt-inst/deb/debfile.cc
 +  * apt-inst/deb/debfile.cc:
 +    - support data.tar's compressed with any configured compressor
 +  * cmdline/apt-get.cc:
 +    - reinstall dependencies of reinstalled "garbage" (Closes: #617257)
 +
 +  [ Steve Langasek ]
 +  * apt-pkg/deb/dpkgpm.cc:
 +    - make sure that for multiarch packages, we are passing the full
 +      qualified package name to dpkg for removals. (Closes: #614298)
 +  * Remove the "pseudopackage" handling of Architecture: all packages for
 +    Multi-Arch; instead, Arch: all packages only satisfy dependencies for
 +    the native arch, except where the Arch: all package is declared
 +    Multi-Arch: foreign.  (Closes: #613584)
 +
 + -- Michael Vogt <mvo@debian.org>  Thu, 10 Mar 2011 14:46:48 +0100
 +
 +apt (0.8.11.5) unstable; urgency=low
 +
 +  [ Christian Perrier ]
 +  * Add missing dot in French translation of manpages. Merci, Olivier
 +    Humbert.
 +  * French translation update
 +  * French manpages translation update
 +
 +  [ David Kalnischkies ]
 +  * apt-pkg/depcache.cc:
 +    - party revert fix in 0.8.11.2 which marked all packages as manual
 +      installed if the FromUser bit is set in the MarkInstall call.
 +      The default for this bit is true and aptitude depends on the old
 +      behavior so the package is only marked as manual if its not marked
 +      ("old" behavior) or if automatic installation is enabled - which
 +      aptitude disables always (see also #613775)
 +
 + -- David Kalnischkies <kalnischkies@gmail.com>  Thu, 17 Feb 2011 15:16:31 +0100
 +
 +apt (0.8.11.4) unstable; urgency=low
 +
 +  [ David Kalnischkies ]
 +  * apt-pkg/contrib/error.cc:
 +    - ensure that va_list is not invalid in second try
 +  * cmdline/apt-get.cc:
 +    - don't remove new dependencies of garbage packages (Closes: #613420)
 +  
 +  [ Michael Vogt ]
 +  * test/integration/*
 +    - fix dashish in the integration tests
 +
 + -- Michael Vogt <mvo@debian.org>  Wed, 16 Feb 2011 14:36:03 +0100
 +
 +apt (0.8.11.3) unstable; urgency=low
 +
 +  * apt-pkg/contrib/fileutl.cc:
 +    - really detect bigendian machines by including config.h,
 +      so we can really (Closes: #612986)
 +  * apt-pkg/contrib/mmap.cc:
 +    - Base has as 'valid' failure states 0 and -1 so add a simple
 +      validData method to check for failure states
 +
 + -- David Kalnischkies <kalnischkies@gmail.com>  Mon, 14 Feb 2011 16:58:03 +0100
 +
 +apt (0.8.11.2) unstable; urgency=low
  
    [ Michael Vogt ]
    * merged lp:~evfool/apt/fix641673:
        mistake reported in bug LP: #641673, thanks to Robert Roth
    * merged lp:~evfool/apt/fix418552:
      - Grammar fix for bug LP: #418552, thanks to Robert Roth
 +  
 +  [ David Kalnischkies ]
 +  * cmdline/apt-get.cc:
 +    - add --install-suggests option (Closes: #473089)
 +  * apt-pkg/depcache.cc:
 +    - mark a package which was requested to be installed on commandline
 +      always as manual regardless if it is already marked or not as the
 +      marker could be lost later by the removal of rdepends (Closes: #612557)
 +  * methods/rred.cc:
 +    - read patch into MMap only if we work on uncompressed patches
 +    - update size of dynamic MMap as we write in from the outside
 +  * apt-pkg/contrib/mmap.cc:
 +    - do not try to free the mapping if its is unset
 +  * apt-pkg/contrib/fileutl.cc:
 +    - reorder the loaded filesize bytes for big endian (Closes: #612986)
 +      Thanks to Jörg Sommer for the detailed analyse!
 +
 + -- Michael Vogt <mvo@debian.org>  Mon, 14 Feb 2011 12:07:18 +0100
  
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Thu, 10 Feb 2011 17:37:56 +0100
 +apt (0.8.11.1) unstable; urgency=low
  
 -apt (0.8.11) UNRELEASED; urgency=low
 +  [ Stefan Lippers-Hollmann ]
 +  * cmdline/apt-key:
 +    - fix root test which prevented setting of trustdb-name
 +      which lets gpg fail if it adds/remove keys from trusted.gpg
 +      as it tries to open the (maybe) not existent /root/.gnupg
 +
 +  [ David Kalnischkies ]
 +  * debian/apt.symbols:
 +    - add more arch dependent symbols
 +
 + -- Michael Vogt <mvo@debian.org>  Wed, 09 Feb 2011 17:49:59 +0100
 +
 +apt (0.8.11) unstable; urgency=low
  
    [ David Kalnischkies ]
    * apt-pkg/depcache.cc:
      - add SetCandidateRelease() to set a candidate version and
        the candidates of dependencies if needed to a specified
        release (Closes: #572709)
 +    - allow conflicts in the same group again (Closes: #612099)
    * cmdline/apt-get.cc:
      - if --print-uris is used don't setup downloader as we don't need
        progress, lock nor the directories it would create otherwise
        so installing packages from experimental or backports is easier
      - really do not show packages in the extra section if they were
        requested on the commandline, e.g. with a modifier (Closes: #184730)
 +    - always do removes first and set not installed remove packages
 +      on hold to prevent temporary installation later (Closes: #549968)
    * debian/control:
      - add Vcs-Browser now that loggerhead works again (Closes: #511168)
      - depend on debhelper 7 to raise compat level
      - remove duplicated mentioning of --install-recommends
    * doc/sources.list.5.xml:
      - remove obsolete references to non-us (Closes: #594495)
 +    - a notice is printed for ignored files (Closes: #597615)
    * debian/rules:
      - use -- instead of deprecated -u for dh_gencontrol
      - remove shlibs.local creation and usage
      - print a good error message if FileSize() is zero
    * apt-pkg/aptconfiguration.cc:
      - remove the inbuilt Translation files whitelist
 +  * cmdline/apt-cache.cc:
 +    - remove not implemented 'apt-cache add' command
 +  * doc/apt-cache.8.xml:
 +    - describe reality as apt-cache just queries and doesn't manipulate
 +      the caches. Thanks to Enrico Zini for spotting it! (Closes: #612009)
 +  * apt-pkg/algorithms.cc:
 +    - mark pseudo packages of installed all packages as configured
 +      in the simulation as we don't call configure for these packages
 +  * apt-pkg/pkgcachegen.cc:
 +    - in multiarch, let :all packages conflict with :any packages
 +      with a different version to be sure
 +  * apt-pkg/contrib/error.cc:
 +    - remove 400 char size limit of error messages (LP: #365611)
  
    [ Michael Vogt ]
    * methods/http.cc:
        to Guillem Jover
    * apt-pkg/cdrom.cc, apt-pkg/init.cc, methods/cdrom.cc:
      - use /media/cdrom as default mountoint (closes: #611569)
 +  * cmdline/apt-get.cc:
 +    - add apt-get changelog (closes: #526990)
 +    - add apt-get download (closes: #82738)
  
    [ Martin Pitt ]
    * test/integration/test-compressed-indexes, test/test-indexes.sh:
        will actually test uncompressed indexes regardless of the internal
        default value of Acquire::GzipIndexes.
  
 - -- David Kalnischkies <kalnischkies@gmail.com>  Fri, 28 Jan 2011 12:22:25 +0100
 + -- Michael Vogt <mvo@debian.org>  Tue, 08 Feb 2011 12:58:12 +0100
  
  apt (0.8.10.3) unstable; urgency=low
  
diff --combined ftparchive/writer.cc
index 9f12cbf3d0e749204a1782485b06b76a558baf19,98ab852ea97604829dc132182b89fd1b7855b974..eb8938b9594708bc69335fc3216a5b5740c55dba
  #include <apt-pkg/strutl.h>
  #include <apt-pkg/error.h>
  #include <apt-pkg/configuration.h>
 +#include <apt-pkg/aptconfiguration.h>
  #include <apt-pkg/md5.h>
  #include <apt-pkg/sha1.h>
- #include <apt-pkg/sha256.h>
+ #include <apt-pkg/sha2.h>
  #include <apt-pkg/deblistparser.h>
  
  #include <sys/types.h>
@@@ -60,10 -59,6 +60,10 @@@ FTWScanner::FTWScanner(string const &Ar
  {
     ErrorPrinted = false;
     NoLinkAct = !_config->FindB("APT::FTPArchive::DeLinkAct",true);
 +
 +   DoMD5 = _config->FindB("APT::FTPArchive::MD5",true);
 +   DoSHA1 = _config->FindB("APT::FTPArchive::SHA1",true);
 +   DoSHA256 = _config->FindB("APT::FTPArchive::SHA256",true);
  }
                                                                        /*}}}*/
  // FTWScanner::Scanner - FTW Scanner                                  /*{{{*/
@@@ -313,9 -308,10 +313,10 @@@ PackagesWriter::PackagesWriter(string c
     DeLinkLimit = 0;
  
     // Process the command line options
 -   DoMD5 = _config->FindB("APT::FTPArchive::MD5",true);
 -   DoSHA1 = _config->FindB("APT::FTPArchive::SHA1",true);
 -   DoSHA256 = _config->FindB("APT::FTPArchive::SHA256",true);
 -   DoSHA256 = _config->FindB("APT::FTPArchive::SHA512",true);
 +   DoMD5 = _config->FindB("APT::FTPArchive::Packages::MD5",DoMD5);
 +   DoSHA1 = _config->FindB("APT::FTPArchive::Packages::SHA1",DoSHA1);
 +   DoSHA256 = _config->FindB("APT::FTPArchive::Packages::SHA256",DoSHA256);
++   DoSHA256 = _config->FindB("APT::FTPArchive::Packages::SHA512",true);
     DoAlwaysStat = _config->FindB("APT::FTPArchive::AlwaysStat", false);
     DoContents = _config->FindB("APT::FTPArchive::Contents",true);
     NoOverride = _config->FindB("APT::FTPArchive::NoOverrideMsg",false);
@@@ -370,7 -366,7 +371,7 @@@ bool FTWScanner::SetExts(string const &
  bool PackagesWriter::DoPackage(string FileName)
  {      
     // Pull all the data we need form the DB
-    if (Db.GetFileInfo(FileName, true, DoContents, true, DoMD5, DoSHA1, DoSHA256, DoAlwaysStat)
+    if (Db.GetFileInfo(FileName, true, DoContents, true, DoMD5, DoSHA1, DoSHA256, DoSHA512, DoAlwaysStat)
                  == false)
     {
        return false;
  
     unsigned int End = 0;
     SetTFRewriteData(Changes[End++], "Size", Size);
 -   SetTFRewriteData(Changes[End++], "MD5sum", Db.MD5Res.c_str());
 -   SetTFRewriteData(Changes[End++], "SHA1", Db.SHA1Res.c_str());
 -   SetTFRewriteData(Changes[End++], "SHA256", Db.SHA256Res.c_str());
 -   SetTFRewriteData(Changes[End++], "SHA512", Db.SHA512Res.c_str());
 +   if (DoMD5 == true)
 +      SetTFRewriteData(Changes[End++], "MD5sum", Db.MD5Res.c_str());
 +   if (DoSHA1 == true)
 +      SetTFRewriteData(Changes[End++], "SHA1", Db.SHA1Res.c_str());
 +   if (DoSHA256 == true)
 +      SetTFRewriteData(Changes[End++], "SHA256", Db.SHA256Res.c_str());
++   if (DoSHA512 == true)
++      SetTFRewriteData(Changes[End++], "SHA512", Db.SHA512Res.c_str());
     SetTFRewriteData(Changes[End++], "Filename", NewFileName.c_str());
     SetTFRewriteData(Changes[End++], "Priority", OverItem->Priority.c_str());
     SetTFRewriteData(Changes[End++], "Status", 0);
@@@ -567,9 -561,6 +570,9 @@@ SourcesWriter::SourcesWriter(string con
     BufSize = 0;
     
     // Process the command line options
 +   DoMD5 = _config->FindB("APT::FTPArchive::Sources::MD5",DoMD5);
 +   DoSHA1 = _config->FindB("APT::FTPArchive::Sources::SHA1",DoSHA1);
 +   DoSHA256 = _config->FindB("APT::FTPArchive::Sources::SHA256",DoSHA256);
     NoOverride = _config->FindB("APT::FTPArchive::NoOverrideMsg",false);
  
     // Read the override file
@@@ -619,17 -610,15 +622,20 @@@ bool SourcesWriter::DoPackage(string Fi
     // Hash the file
     char *Start = Buffer;
     char *BlkEnd = Buffer + St.st_size;
 -   MD5Summation MD5;
 -   MD5.Add((unsigned char *)Start,BlkEnd - Start);
  
 +   MD5Summation MD5;
     SHA1Summation SHA1;
     SHA256Summation SHA256;
 -   SHA512Summation SHA512;
 -   SHA1.Add((unsigned char *)Start,BlkEnd - Start);
 -   SHA256.Add((unsigned char *)Start,BlkEnd - Start);
 -   SHA512.Add((unsigned char *)Start,BlkEnd - Start);
++   SHA256Summation SHA512;
 +
 +   if (DoMD5 == true)
 +      MD5.Add((unsigned char *)Start,BlkEnd - Start);
 +   if (DoSHA1 == true)
 +      SHA1.Add((unsigned char *)Start,BlkEnd - Start);
 +   if (DoSHA256 == true)
 +      SHA256.Add((unsigned char *)Start,BlkEnd - Start);
++   if (DoSHA512 == true)
++      SHA512.Add((unsigned char *)Start,BlkEnd - Start);
  
     // Add an extra \n to the end, just in case
     *BlkEnd++ = '\n';
     // Add the dsc to the files hash list
     string const strippedName = flNotDir(FileName);
     std::ostringstream ostreamFiles;
 -   if (Tags.Exists("Files"))
 +   if (DoMD5 == true && Tags.Exists("Files"))
        ostreamFiles << "\n " << string(MD5.Result()) << " " << St.st_size << " "
                   << strippedName << "\n " << Tags.FindS("Files");
     string const Files = ostreamFiles.str();
  
     std::ostringstream ostreamSha1;
 -   if (Tags.Exists("Checksums-Sha1"))
 +   if (DoSHA1 == true && Tags.Exists("Checksums-Sha1"))
        ostreamSha1 << "\n " << string(SHA1.Result()) << " " << St.st_size << " "
                   << strippedName << "\n " << Tags.FindS("Checksums-Sha1");
     string const ChecksumsSha1 = ostreamSha1.str();
  
     std::ostringstream ostreamSha256;
 -   if (Tags.Exists("Checksums-Sha256"))
 +   if (DoSHA256 == true && Tags.Exists("Checksums-Sha256"))
        ostreamSha256 << "\n " << string(SHA256.Result()) << " " << St.st_size << " "
                   << strippedName << "\n " << Tags.FindS("Checksums-Sha256");
     string const ChecksumsSha256 = ostreamSha256.str();
  
+    std::ostringstream ostreamSha512;
+    if (Tags.Exists("Checksums-Sha512"))
+       ostreamSha512 << "\n " << string(SHA512.Result()) << " " << St.st_size << " "
+                  << strippedName << "\n " << Tags.FindS("Checksums-Sha512");
+    string const ChecksumsSha512 = ostreamSha512.str();
     // Strip the DirStrip prefix from the FileName and add the PathPrefix
     string NewFileName;
     if (DirStrip.empty() == false &&
  
     unsigned int End = 0;
     SetTFRewriteData(Changes[End++],"Source",Package.c_str(),"Package");
 -   SetTFRewriteData(Changes[End++],"Files",Files.c_str());
 -   SetTFRewriteData(Changes[End++],"Checksums-Sha1",ChecksumsSha1.c_str());
 -   SetTFRewriteData(Changes[End++],"Checksums-Sha256",ChecksumsSha256.c_str());
 -   SetTFRewriteData(Changes[End++],"Checksums-Sha512",ChecksumsSha512.c_str());
 +   if (Files.empty() == false)
 +      SetTFRewriteData(Changes[End++],"Files",Files.c_str());
 +   if (ChecksumsSha1.empty() == false)
 +      SetTFRewriteData(Changes[End++],"Checksums-Sha1",ChecksumsSha1.c_str());
 +   if (ChecksumsSha256.empty() == false)
 +      SetTFRewriteData(Changes[End++],"Checksums-Sha256",ChecksumsSha256.c_str());
++   if (ChecksumsSha512.empty() == false)
++      SetTFRewriteData(Changes[End++],"Checksums-Sha512",ChecksumsSha512.c_str());
     if (Directory != "./")
        SetTFRewriteData(Changes[End++],"Directory",Directory.c_str());
     SetTFRewriteData(Changes[End++],"Priority",BestPrio.c_str());
@@@ -931,12 -924,10 +945,12 @@@ ReleaseWriter::ReleaseWriter(string con
        AddPattern("Packages.gz");
        AddPattern("Packages.bz2");
        AddPattern("Packages.lzma");
 +      AddPattern("Packages.xz");
        AddPattern("Sources");
        AddPattern("Sources.gz");
        AddPattern("Sources.bz2");
        AddPattern("Sources.lzma");
 +      AddPattern("Sources.xz");
        AddPattern("Release");
        AddPattern("Index");
        AddPattern("md5sum.txt");
  
     Output = stdout;
     time_t const now = time(NULL);
 +
 +   setlocale(LC_TIME, "C");
 +
     char datestr[128];
     if (strftime(datestr, sizeof(datestr), "%a, %d %b %Y %H:%M:%S UTC",
                  gmtime(&now)) == 0)
        validstr[0] = '\0';
     }
  
 +   setlocale(LC_TIME, "");
 +
     map<string,string> Fields;
     Fields["Origin"] = "";
     Fields["Label"] = "";
  
        fprintf(Output, "%s: %s\n", (*I).first.c_str(), Value.c_str());
     }
 +
 +   DoMD5 = _config->FindB("APT::FTPArchive::Release::MD5",DoMD5);
 +   DoSHA1 = _config->FindB("APT::FTPArchive::Release::SHA1",DoSHA1);
 +   DoSHA256 = _config->FindB("APT::FTPArchive::Release::SHA256",DoSHA256);
  }
                                                                        /*}}}*/
  // ReleaseWriter::DoPackage - Process a single package                        /*{{{*/
@@@ -1025,27 -1007,24 +1039,31 @@@ bool ReleaseWriter::DoPackage(string Fi
  
     CheckSums[NewFileName].size = fd.Size();
  
 -   MD5Summation MD5;
 -   MD5.AddFD(fd.Fd(), fd.Size());
 -   CheckSums[NewFileName].MD5 = MD5.Result();
 -
 -   fd.Seek(0);
 -   SHA1Summation SHA1;
 -   SHA1.AddFD(fd.Fd(), fd.Size());
 -   CheckSums[NewFileName].SHA1 = SHA1.Result();
 -
 -   fd.Seek(0);
 -   SHA256Summation SHA256;
 -   SHA256.AddFD(fd.Fd(), fd.Size());
 -   CheckSums[NewFileName].SHA256 = SHA256.Result();
 +   if (DoMD5 == true)
 +   {
 +      MD5Summation MD5;
 +      MD5.AddFD(fd.Fd(), fd.Size());
 +      CheckSums[NewFileName].MD5 = MD5.Result();
 +      fd.Seek(0);
 +   }
 +   if (DoSHA1 == true)
 +   {
 +      SHA1Summation SHA1;
 +      SHA1.AddFD(fd.Fd(), fd.Size());
 +      CheckSums[NewFileName].SHA1 = SHA1.Result();
 +      fd.Seek(0);
 +   }
 +   if (DoSHA256 == true)
 +   {
 +      SHA256Summation SHA256;
 +      SHA256.AddFD(fd.Fd(), fd.Size());
 +      CheckSums[NewFileName].SHA256 = SHA256.Result();
 +   }
  
+    SHA256Summation SHA512;
+    SHA256.AddFD(fd.Fd(), fd.Size());
+    CheckSums[NewFileName].SHA512 = SHA512.Result();
     fd.Close();
     
     return true;
  // ---------------------------------------------------------------------
  void ReleaseWriter::Finish()
  {
 -   fprintf(Output, "MD5Sum:\n");
 -   for(map<string,struct CheckSum>::const_iterator I = CheckSums.begin();
 -       I != CheckSums.end();
 -       ++I)
 +   if (DoMD5 == true)
     {
 -      fprintf(Output, " %s %16ld %s\n",
 -              (*I).second.MD5.c_str(),
 -              (*I).second.size,
 -              (*I).first.c_str());
 +      fprintf(Output, "MD5Sum:\n");
 +      for(map<string,struct CheckSum>::const_iterator I = CheckSums.begin();
 +        I != CheckSums.end(); ++I)
 +      {
 +       fprintf(Output, " %s %16ld %s\n",
 +               (*I).second.MD5.c_str(),
 +               (*I).second.size,
 +               (*I).first.c_str());
 +      }
     }
 -
 -   fprintf(Output, "SHA1:\n");
 -   for(map<string,struct CheckSum>::const_iterator I = CheckSums.begin();
 -       I != CheckSums.end();
 -       ++I)
 +   if (DoSHA1 == true)
     {
 -      fprintf(Output, " %s %16ld %s\n",
 -              (*I).second.SHA1.c_str(),
 -              (*I).second.size,
 -              (*I).first.c_str());
 +      fprintf(Output, "SHA1:\n");
 +      for(map<string,struct CheckSum>::const_iterator I = CheckSums.begin();
 +        I != CheckSums.end(); ++I)
 +      {
 +       fprintf(Output, " %s %16ld %s\n",
 +               (*I).second.SHA1.c_str(),
 +               (*I).second.size,
 +               (*I).first.c_str());
 +      }
     }
 -
 -   fprintf(Output, "SHA256:\n");
 -   for(map<string,struct CheckSum>::const_iterator I = CheckSums.begin();
 -       I != CheckSums.end();
 -       ++I)
 +   if (DoSHA256 == true)
     {
 -      fprintf(Output, " %s %16ld %s\n",
 -              (*I).second.SHA256.c_str(),
 -              (*I).second.size,
 -              (*I).first.c_str());
 +      fprintf(Output, "SHA256:\n");
 +      for(map<string,struct CheckSum>::const_iterator I = CheckSums.begin();
 +        I != CheckSums.end(); ++I)
 +      {
 +       fprintf(Output, " %s %16ld %s\n",
 +               (*I).second.SHA256.c_str(),
 +               (*I).second.size,
 +               (*I).first.c_str());
 +      }
     }
+    fprintf(Output, "SHA512:\n");
+    for(map<string,struct CheckSum>::const_iterator I = CheckSums.begin();
+        I != CheckSums.end();
+        ++I)
+    {
+       fprintf(Output, " %s %32ld %s\n",
+               (*I).second.SHA512.c_str(),
+               (*I).second.size,
+               (*I).first.c_str());
+    }
  }
 -
diff --combined ftparchive/writer.h
index ce0eab7af9642b6469b236bd417f9082af84e990,e1810821a801a0c6c1b97d49dc4b756e6e12d96a..b8747decddd90cfbdaab3b6f68f0e590fe6fe16e
@@@ -60,9 -60,6 +60,9 @@@ class FTWScanne
     }
     
     public:
 +   bool DoMD5;
 +   bool DoSHA1;
 +   bool DoSHA256;
  
     unsigned long DeLinkLimit;
     string InternalPrefix;
@@@ -106,6 -103,10 +106,6 @@@ class PackagesWriter : public FTWScanne
     public:
  
     // Some flags
 -   bool DoMD5;
 -   bool DoSHA1;
 -   bool DoSHA256;
 -   bool DoSHA512;
     bool DoAlwaysStat;
     bool NoOverride;
     bool DoContents;
@@@ -195,6 -196,7 +195,7 @@@ protected
        string MD5;
        string SHA1;
        string SHA256;
+       string SHA512;
        // Limited by FileFd::Size()
        unsigned long size;
        ~CheckSum() {};