Kaynağa Gözat

* apt-inst/contrib/extracttar.cc:
- fix fd leak for zero size files (thanks to Bill Broadley for
reporting this bug)
* apt-pkg/acquire-item.cc:
- remove zero size files on I-M-S hit
* methods/https.cc:
- only send LastModified if we actually have one
- send range request with if-range
- delete failed downloads
* apt-pkg/deb/dpkgpm.{cc,h}:
- merged dpkg-log branch, this lets you specify a
Dir::Log::Terminal file to log dpkg output to
(ABI break)
* merged apt--sha256 branch to fully support the new
sha256 checksums in the Packages and Release files
(ABI break)
* Applied patch from Aurelien Jarno <aurel32@debian.org> to fix wrong
directory downloading on non-linux architectures (closes: #435597)
* Applied patch from Guillem Jover <guillem@debian.org> to use
* Applied patch from Guillem Jover <guillem@debian.org> to add
support to add lzma support (closes: #408201)
* methods/makefile:
- install lzma symlink method (for full lzma support)
* debian/control:
- suggest "lzma"
* Simplified HttpMethod::Fetch on http.cc removing Tail variable;
* Fix pipeline handling on http.cc (closes: #413324)
* Fix building to properly support binNMUs. Thanks to Daniel Schepler
<schepler@math.unipd.it> by the patch (closes: #359634)
* Fix example for Install-{Recommends,Suggests} options on
configure-index example file. Thanks to Peter Eisentraut
<peter_e@gmx.net> by the patch (closes: #432223)
* fixed compile errors with g++ 4.3 (thanks to
Daniel Burrows, closes: #429378)
* fixes in the auto-mark code (thanks to Daniel
Burrows)
* fix FTFBFS by changing build-depends to
libcurl4-gnutls-dev (closes: #428363)
* cmdline/apt-get.cc:
- fix InstallTask code when a pkgRecord ends
with a single '\n' (thanks to Soren Hansen for reporting)
* merged from Christian Perrier:
* vi.po: completed to 532t, again. Closes: #429899
* gl.po: completed to 532t. Closes: #429506
* vi.po: completed to 532t. Closes: #428672
* Update all PO and the POT. Gives 514t14f4u for formerly
complete translations
* fr.po: completed to 532t
* ku.po, uk.po, LINGUAS: reintegrate those translations
which disappeared from the BZR repositories

Michael Vogt 19 yıl önce
ebeveyn
işleme
f060e833f5

+ 1 - 1
apt-inst/contrib/extracttar.cc

@@ -332,7 +332,7 @@ bool ExtractTar::Go(pkgDirStream &Stream)
       }
       }
       
       
       // And finish up
       // And finish up
-      if (Itm.Size != 0 && BadRecord == false)
+      if (Itm.Size >= 0 && BadRecord == false)
 	 if (Stream.FinishedFile(Itm,Fd) == false)
 	 if (Stream.FinishedFile(Itm,Fd) == false)
 	    return false;
 	    return false;
       
       

+ 8 - 2
apt-inst/deb/debfile.cc

@@ -44,8 +44,10 @@ debDebFile::debDebFile(FileFd &File) : File(File), AR(File)
       return;
       return;
    }
    }
 
 
-   if (!CheckMember("data.tar.gz") && !CheckMember("data.tar.bz2")) {
-      _error->Error(_("This is not a valid DEB archive, it has no '%s' or '%s' member"), "data.tar.gz", "data.tar.bz2");
+   if (!CheckMember("data.tar.gz") &&
+       !CheckMember("data.tar.bz2") &&
+       !CheckMember("data.tar.lzma")) {
+      _error->Error(_("This is not a valid DEB archive, it has no '%s', '%s' or '%s' member"), "data.tar.gz", "data.tar.bz2", "data.tar.lzma");
       return;
       return;
    }
    }
 }
 }
@@ -130,6 +132,10 @@ bool debDebFile::ExtractArchive(pkgDirStream &Stream)
       Member = AR.FindMember("data.tar.bz2");
       Member = AR.FindMember("data.tar.bz2");
       Compressor = "bzip2";
       Compressor = "bzip2";
    }
    }
+   if (Member == 0) {
+      Member = AR.FindMember("data.tar.lzma");
+      Compressor = "lzma";
+   }
    if (Member == 0)
    if (Member == 0)
       return _error->Error(_("Internal error, could not locate member"));   
       return _error->Error(_("Internal error, could not locate member"));   
    if (File.Seek(Member->Start) == false)
    if (File.Seek(Member->Start) == false)

+ 71 - 81
apt-pkg/acquire-item.cc

@@ -103,7 +103,7 @@ void pkgAcquire::Item::Start(string /*Message*/,unsigned long Size)
 // Acquire::Item::Done - Item downloaded OK				/*{{{*/
 // Acquire::Item::Done - Item downloaded OK				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void pkgAcquire::Item::Done(string Message,unsigned long Size,string,
+void pkgAcquire::Item::Done(string Message,unsigned long Size,string Hash,
 			    pkgAcquire::MethodConfig *Cnf)
 			    pkgAcquire::MethodConfig *Cnf)
 {
 {
    // We just downloaded something..
    // We just downloaded something..
@@ -192,8 +192,9 @@ void pkgAcquire::Item::ReportMirrorFailure(string FailCode)
  */
  */
 pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
 pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
 				 string URI,string URIDesc,string ShortDesc,
 				 string URI,string URIDesc,string ShortDesc,
-				 string ExpectedMD5)
-   : Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5), Description(URIDesc)
+				 HashString ExpectedHash)
+   : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash),
+     Description(URIDesc)
 {
 {
    
    
    Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
    Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
@@ -321,11 +322,11 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)
       if(found) 
       if(found) 
       {
       {
 	 // queue the diffs
 	 // queue the diffs
-	 unsigned int last_space = Description.rfind(" ");
+	 string::size_type last_space = Description.rfind(" ");
 	 if(last_space != string::npos)
 	 if(last_space != string::npos)
 	    Description.erase(last_space, Description.size()-last_space);
 	    Description.erase(last_space, Description.size()-last_space);
 	 new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
 	 new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
-			      ExpectedMD5, available_patches);
+			      ExpectedHash, available_patches);
 	 Complete = false;
 	 Complete = false;
 	 Status = StatDone;
 	 Status = StatDone;
 	 Dequeue();
 	 Dequeue();
@@ -348,7 +349,7 @@ void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 		<< "Falling back to normal index file aquire" << std::endl;
 		<< "Falling back to normal index file aquire" << std::endl;
 
 
    new pkgAcqIndex(Owner, RealURI, Description, Desc.ShortDesc, 
    new pkgAcqIndex(Owner, RealURI, Description, Desc.ShortDesc, 
-		   ExpectedMD5);
+		   ExpectedHash);
 
 
    Complete = false;
    Complete = false;
    Status = StatDone;
    Status = StatDone;
@@ -394,8 +395,9 @@ void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,
  */
  */
 pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
 pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
 				   string URI,string URIDesc,string ShortDesc,
 				   string URI,string URIDesc,string ShortDesc,
-				   string ExpectedMD5, vector<DiffInfo> diffs)
-   : Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5), 
+				   HashString ExpectedMD5, 
+				   vector<DiffInfo> diffs)
+   : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash), 
      available_patches(diffs)
      available_patches(diffs)
 {
 {
    
    
@@ -428,7 +430,7 @@ void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
       std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << std::endl
       std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << std::endl
 		<< "Falling back to normal index file aquire" << std::endl;
 		<< "Falling back to normal index file aquire" << std::endl;
    new pkgAcqIndex(Owner, RealURI, Description,Desc.ShortDesc, 
    new pkgAcqIndex(Owner, RealURI, Description,Desc.ShortDesc, 
-		   ExpectedMD5);
+		   ExpectedHash);
    Finish();
    Finish();
 }
 }
 
 
@@ -443,14 +445,7 @@ void pkgAcqIndexDiffs::Finish(bool allDone)
       DestFile = _config->FindDir("Dir::State::lists");
       DestFile = _config->FindDir("Dir::State::lists");
       DestFile += URItoFileName(RealURI);
       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)
+      if(!ExpectedHash.empty() && !ExpectedHash.VerifyFile(DestFile))
       {
       {
 	 Status = StatAuthError;
 	 Status = StatAuthError;
 	 ErrorText = _("MD5Sum mismatch");
 	 ErrorText = _("MD5Sum mismatch");
@@ -592,7 +587,7 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,
       // see if there is more to download
       // see if there is more to download
       if(available_patches.size() > 0) {
       if(available_patches.size() > 0) {
 	 new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
 	 new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
-			      ExpectedMD5, available_patches);
+			      ExpectedHash, available_patches);
 	 return Finish();
 	 return Finish();
       } else 
       } else 
 	 return Finish(true);
 	 return Finish(true);
@@ -606,8 +601,8 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,
    instantiated to fetch the revision file */   
    instantiated to fetch the revision file */   
 pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
 pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
 			 string URI,string URIDesc,string ShortDesc,
 			 string URI,string URIDesc,string ShortDesc,
-			 string ExpectedMD5, string comprExt)
-   : Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5)
+			 HashString ExpectedHash, string comprExt)
+   : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash)
 {
 {
    Decompression = false;
    Decompression = false;
    Erase = false;
    Erase = false;
@@ -657,7 +652,7 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 
 
       // retry with a gzip one 
       // retry with a gzip one 
       new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc, 
       new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc, 
-		      ExpectedMD5, string(".gz"));
+		      ExpectedHash, string(".gz"));
       Status = StatDone;
       Status = StatDone;
       Complete = false;
       Complete = false;
       Dequeue();
       Dequeue();
@@ -682,32 +677,23 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
    to the uncompressed version of the file. If this is so the file
    to the uncompressed version of the file. If this is so the file
    is copied into the partial directory. In all other cases the file
    is copied into the partial directory. In all other cases the file
    is decompressed with a gzip uri. */
    is decompressed with a gzip uri. */
-void pkgAcqIndex::Done(string Message,unsigned long Size,string MD5,
+void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
 		       pkgAcquire::MethodConfig *Cfg)
 		       pkgAcquire::MethodConfig *Cfg)
 {
 {
-   Item::Done(Message,Size,MD5,Cfg);
+   Item::Done(Message,Size,Hash,Cfg);
 
 
    if (Decompression == true)
    if (Decompression == true)
    {
    {
       if (_config->FindB("Debug::pkgAcquire::Auth", false))
       if (_config->FindB("Debug::pkgAcquire::Auth", false))
       {
       {
-         std::cerr << std::endl << RealURI << ": Computed MD5: " << MD5;
-         std::cerr << "  Expected MD5: " << ExpectedMD5 << std::endl;
-      }
-
-      if (MD5.empty())
-      {
-         MD5Summation sum;
-         FileFd Fd(DestFile, FileFd::ReadOnly);
-         sum.AddFD(Fd.Fd(), Fd.Size());
-         Fd.Close();
-         MD5 = (string)sum.Result();
+         std::cerr << std::endl << RealURI << ": Computed Hash: " << Hash;
+         std::cerr << "  Expected Hash: " << ExpectedHash.toStr() << std::endl;
       }
       }
 
 
-      if (!ExpectedMD5.empty() && MD5 != ExpectedMD5)
+      if (!ExpectedHash.empty() && ExpectedHash.toStr() != Hash)
       {
       {
          Status = StatAuthError;
          Status = StatAuthError;
-         ErrorText = _("MD5Sum mismatch");
+         ErrorText = _("Hash Sum mismatch");
          Rename(DestFile,DestFile + ".FAILED");
          Rename(DestFile,DestFile + ".FAILED");
 	 ReportMirrorFailure("HashChecksumFailure");
 	 ReportMirrorFailure("HashChecksumFailure");
          return;
          return;
@@ -738,8 +724,10 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string MD5,
    {
    {
       // The files timestamp matches
       // The files timestamp matches
       if (StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false) == true)
       if (StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false) == true)
+      {
+	 unlink(FileName.c_str());
 	 return;
 	 return;
-
+      }
       Decompression = true;
       Decompression = true;
       Local = true;
       Local = true;
       DestFile += ".decomp";
       DestFile += ".decomp";
@@ -758,7 +746,10 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string MD5,
    
    
    // The files timestamp matches
    // The files timestamp matches
    if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
    if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
+   {
+      unlink(FileName.c_str());
       return;
       return;
+   }
 
 
    if (FileName == DestFile)
    if (FileName == DestFile)
       Erase = true;
       Erase = true;
@@ -787,8 +778,8 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string MD5,
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The Translation file is added to the queue */
 /* The Translation file is added to the queue */
 pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
 pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
-			    string URI,string URIDesc,string ShortDesc) :
-                      pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, "", "")
+			    string URI,string URIDesc,string ShortDesc) 
+  : pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashString(), "")
 {
 {
 }
 }
 
 
@@ -965,10 +956,10 @@ string pkgAcqMetaIndex::Custom600Headers()
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 }
 }
 
 
-void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string MD5,
+void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash,
 			   pkgAcquire::MethodConfig *Cfg)
 			   pkgAcquire::MethodConfig *Cfg)
 {
 {
-   Item::Done(Message,Size,MD5,Cfg);
+   Item::Done(Message,Size,Hash,Cfg);
 
 
    // MetaIndexes are done in two passes: one to download the
    // MetaIndexes are done in two passes: one to download the
    // metaindex with an appropriate method, and a second to verify it
    // metaindex with an appropriate method, and a second to verify it
@@ -1030,18 +1021,18 @@ void pkgAcqMetaIndex::RetrievalDone(string Message)
 
 
    // see if the download was a IMSHit
    // see if the download was a IMSHit
    IMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false);
    IMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false);
-
    Complete = true;
    Complete = true;
 
 
    string FinalFile = _config->FindDir("Dir::State::lists");
    string FinalFile = _config->FindDir("Dir::State::lists");
    FinalFile += URItoFileName(RealURI);
    FinalFile += URItoFileName(RealURI);
 
 
-   // The files timestamp matches
-   if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == false)
-   {
-      // Move it into position
+   // If we get a IMS hit we can remove the empty file in partial
+   // othersie we move the file in place
+   if (IMSHit)
+      unlink(DestFile.c_str());
+   else
       Rename(DestFile,FinalFile);
       Rename(DestFile,FinalFile);
-   }
+
    chmod(FinalFile.c_str(),0644);
    chmod(FinalFile.c_str(),0644);
    DestFile = FinalFile;
    DestFile = FinalFile;
 }
 }
@@ -1086,7 +1077,7 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)
         Target != IndexTargets->end();
         Target != IndexTargets->end();
         Target++)
         Target++)
    {
    {
-      string ExpectedIndexMD5;
+      HashString ExpectedIndexHash;
       if (verify)
       if (verify)
       {
       {
          const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey);
          const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey);
@@ -1097,16 +1088,16 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)
                + (*Target)->MetaKey + " in Meta-index file (malformed Release file?)";
                + (*Target)->MetaKey + " in Meta-index file (malformed Release file?)";
             return;
             return;
          }
          }
-         ExpectedIndexMD5 = Record->MD5Hash;
+         ExpectedIndexHash = Record->Hash;
          if (_config->FindB("Debug::pkgAcquire::Auth", false))
          if (_config->FindB("Debug::pkgAcquire::Auth", false))
          {
          {
             std::cerr << "Queueing: " << (*Target)->URI << std::endl;
             std::cerr << "Queueing: " << (*Target)->URI << std::endl;
-            std::cerr << "Expected MD5: " << ExpectedIndexMD5 << std::endl;
+            std::cerr << "Expected Hash: " << ExpectedIndexHash.toStr() << std::endl;
          }
          }
-         if (ExpectedIndexMD5.empty())
+         if (ExpectedIndexHash.empty())
          {
          {
             Status = StatAuthError;
             Status = StatAuthError;
-            ErrorText = "Unable to find MD5 sum for "
+            ErrorText = "Unable to find hash sum for "
                + (*Target)->MetaKey + " in Meta-index file";
                + (*Target)->MetaKey + " in Meta-index file";
             return;
             return;
          }
          }
@@ -1116,10 +1107,10 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)
       // on the users option)
       // on the users option)
       if(_config->FindB("Acquire::PDiffs",false) == true) 
       if(_config->FindB("Acquire::PDiffs",false) == true) 
 	 new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description,
 	 new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description,
-			     (*Target)->ShortDesc, ExpectedIndexMD5);
+			     (*Target)->ShortDesc, ExpectedIndexHash);
       else 
       else 
 	 new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
 	 new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
-			    (*Target)->ShortDesc, ExpectedIndexMD5);
+			    (*Target)->ShortDesc, ExpectedIndexHash);
    }
    }
 }
 }
 
 
@@ -1360,7 +1351,12 @@ bool pkgAcqArchive::QueueNext()
 	 return false;
 	 return false;
       
       
       string PkgFile = Parse.FileName();
       string PkgFile = Parse.FileName();
-      MD5 = Parse.MD5Hash();
+      if(Parse.SHA256Hash() != "")
+	 ExpectedHash = HashString("SHA256", Parse.SHA256Hash());
+      else if (Parse.SHA1Hash() != "")
+	 ExpectedHash = HashString("SHA1", Parse.SHA1Hash());
+      else 
+	 ExpectedHash = HashString("MD5Sum", Parse.MD5Hash());
       if (PkgFile.empty() == true)
       if (PkgFile.empty() == true)
 	 return _error->Error(_("The package index files are corrupted. No Filename: "
 	 return _error->Error(_("The package index files are corrupted. No Filename: "
 			      "field for package %s."),
 			      "field for package %s."),
@@ -1440,10 +1436,10 @@ bool pkgAcqArchive::QueueNext()
 // AcqArchive::Done - Finished fetching					/*{{{*/
 // AcqArchive::Done - Finished fetching					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void pkgAcqArchive::Done(string Message,unsigned long Size,string Md5Hash,
+void pkgAcqArchive::Done(string Message,unsigned long Size,string CalcHash,
 			 pkgAcquire::MethodConfig *Cfg)
 			 pkgAcquire::MethodConfig *Cfg)
 {
 {
-   Item::Done(Message,Size,Md5Hash,Cfg);
+   Item::Done(Message,Size,CalcHash,Cfg);
    
    
    // Check the size
    // Check the size
    if (Size != Version->Size)
    if (Size != Version->Size)
@@ -1453,17 +1449,14 @@ void pkgAcqArchive::Done(string Message,unsigned long Size,string Md5Hash,
       return;
       return;
    }
    }
    
    
-   // Check the md5
-   if (Md5Hash.empty() == false && MD5.empty() == false)
+   // Check the hash
+   if(ExpectedHash.toStr() != CalcHash)
    {
    {
-      if (Md5Hash != MD5)
-      {
-	 Status = StatError;
-	 ErrorText = _("MD5Sum mismatch");
-	 if(FileExists(DestFile))
-	    Rename(DestFile,DestFile + ".FAILED");
-	 return;
-      }
+      Status = StatError;
+      ErrorText = _("Hash Sum mismatch");
+      if(FileExists(DestFile))
+	 Rename(DestFile,DestFile + ".FAILED");
+      return;
    }
    }
 
 
    // Grab the output filename
    // Grab the output filename
@@ -1555,10 +1548,10 @@ void pkgAcqArchive::Finished()
 // AcqFile::pkgAcqFile - Constructor					/*{{{*/
 // AcqFile::pkgAcqFile - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The file is added to the queue */
 /* The file is added to the queue */
-pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string MD5,
+pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string Hash,
 		       unsigned long Size,string Dsc,string ShortDesc,
 		       unsigned long Size,string Dsc,string ShortDesc,
 		       const string &DestDir, const string &DestFilename) :
 		       const string &DestDir, const string &DestFilename) :
-                       Item(Owner), Md5Hash(MD5)
+                       Item(Owner), ExpectedHash(Hash)
 {
 {
    Retries = _config->FindI("Acquire::Retries",0);
    Retries = _config->FindI("Acquire::Retries",0);
    
    
@@ -1595,23 +1588,20 @@ pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string MD5,
 // AcqFile::Done - Item downloaded OK					/*{{{*/
 // AcqFile::Done - Item downloaded OK					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void pkgAcqFile::Done(string Message,unsigned long Size,string MD5,
+void pkgAcqFile::Done(string Message,unsigned long Size,string CalcHash,
 		      pkgAcquire::MethodConfig *Cnf)
 		      pkgAcquire::MethodConfig *Cnf)
 {
 {
-   // Check the md5
-   if (Md5Hash.empty() == false && MD5.empty() == false)
+   Item::Done(Message,Size,CalcHash,Cnf);
+
+   // Check the hash
+   if(!ExpectedHash.empty() && ExpectedHash.toStr() != CalcHash)
    {
    {
-      if (Md5Hash != MD5)
-      {
-	 Status = StatError;
-	 ErrorText = "MD5Sum mismatch";
-	 Rename(DestFile,DestFile + ".FAILED");
-	 return;
-      }
+      Status = StatError;
+      ErrorText = "Hash Sum mismatch";
+      Rename(DestFile,DestFile + ".FAILED");
+      return;
    }
    }
    
    
-   Item::Done(Message,Size,MD5,Cnf);
-
    string FileName = LookupTag(Message,"Filename");
    string FileName = LookupTag(Message,"Filename");
    if (FileName.empty() == true)
    if (FileName.empty() == true)
    {
    {

+ 39 - 38
apt-pkg/acquire-item.h

@@ -12,7 +12,7 @@
    Three item classes are provided to provide functionality for
    Three item classes are provided to provide functionality for
    downloading of Index, Translation and Packages files.
    downloading of Index, Translation and Packages files.
    
    
-   A Archive class is provided for downloading .deb files. It does Md5
+   A Archive class is provided for downloading .deb files. It does Hash
    checking and source location as well as a retry algorithm.
    checking and source location as well as a retry algorithm.
    
    
    ##################################################################### */
    ##################################################################### */
@@ -26,7 +26,7 @@
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/pkgrecords.h>
 #include <apt-pkg/pkgrecords.h>
 #include <apt-pkg/indexrecords.h>
 #include <apt-pkg/indexrecords.h>
-
+#include <apt-pkg/hashes.h>
 
 
 /** \addtogroup acquire
 /** \addtogroup acquire
  *  @{
  *  @{
@@ -188,12 +188,12 @@ class pkgAcquire::Item
     *  \param Message Data from the acquire method.  Use LookupTag()
     *  \param Message Data from the acquire method.  Use LookupTag()
     *  to parse it.
     *  to parse it.
     *  \param Size The size of the object that was fetched.
     *  \param Size The size of the object that was fetched.
-    *  \param Md5Hash The MD5Sum of the object that was fetched.
+    *  \param Hash The HashSum of the object that was fetched.
     *  \param Cnf The method via which the object was fetched.
     *  \param Cnf The method via which the object was fetched.
     *
     *
     *  \sa pkgAcqMethod
     *  \sa pkgAcqMethod
     */
     */
-   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+   virtual void Done(string Message,unsigned long Size,string Hash,
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
 
 
    /** \brief Invoked when the worker starts to fetch this object.
    /** \brief Invoked when the worker starts to fetch this object.
@@ -231,12 +231,12 @@ class pkgAcquire::Item
    /** \brief Invoked by the worker when the download is completely done. */
    /** \brief Invoked by the worker when the download is completely done. */
    virtual void Finished() {};
    virtual void Finished() {};
    
    
-   /** \brief MD5Sum.
+   /** \brief HashSum 
     *
     *
-    *  \return the MD5Sum of this object, if applicable; otherwise, an
+    *  \return the HashSum of this object, if applicable; otherwise, an
     *  empty string.
     *  empty string.
     */
     */
-   virtual string MD5Sum() {return string();};
+   virtual string HashSum() {return string();};
 
 
    /** \return the acquire process with which this item is associated. */
    /** \return the acquire process with which this item is associated. */
    pkgAcquire *GetOwner() {return Owner;};
    pkgAcquire *GetOwner() {return Owner;};
@@ -309,10 +309,10 @@ class pkgAcqDiffIndex : public pkgAcquire::Item
     */
     */
    string RealURI;
    string RealURI;
 
 
-   /** \brief The MD5Sum that the real index file should have after
+   /** \brief The Hash that the real index file should have after
     *  all patches have been applied.
     *  all patches have been applied.
     */
     */
-   string ExpectedMD5;
+   HashString ExpectedHash;
 
 
    /** \brief The index file which will be patched to generate the new
    /** \brief The index file which will be patched to generate the new
     *  file.
     *  file.
@@ -355,10 +355,10 @@ class pkgAcqDiffIndex : public pkgAcquire::Item
     *
     *
     *  \param ShortDesc A short 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.
+    *  \param ExpectedHash The list file's MD5 signature.
     */
     */
    pkgAcqDiffIndex(pkgAcquire *Owner,string URI,string URIDesc,
    pkgAcqDiffIndex(pkgAcquire *Owner,string URI,string URIDesc,
-		   string ShortDesc, string ExpectedMD5);
+		   string ShortDesc, HashString ExpectedHash);
 };
 };
 
 
 /** \brief An item that is responsible for fetching all the patches
 /** \brief An item that is responsible for fetching all the patches
@@ -391,7 +391,7 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
     *  finishes downloading.
     *  finishes downloading.
     *
     *
     *  Dequeues the item and checks the resulting file's md5sum
     *  Dequeues the item and checks the resulting file's md5sum
-    *  against ExpectedMD5 after the last patch was applied.
+    *  against ExpectedHash after the last patch was applied.
     *  There is no need to check the md5/sha1 after a "normal" 
     *  There is no need to check the md5/sha1 after a "normal" 
     *  patch because QueueNextDiff() will check the sha1 later.
     *  patch because QueueNextDiff() will check the sha1 later.
     *
     *
@@ -417,10 +417,10 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
     */
     */
    string RealURI;
    string RealURI;
 
 
-   /** \brief The MD5Sum of the package index file that is being
+   /** \brief The HashSum of the package index file that is being
     *  reconstructed.
     *  reconstructed.
     */
     */
-   string ExpectedMD5;
+   HashString ExpectedHash;
 
 
    /** A description of the file being downloaded. */
    /** A description of the file being downloaded. */
    string Description;
    string Description;
@@ -477,7 +477,7 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
     *
     *
     *  \param ShortDesc A brief description of this item.
     *  \param ShortDesc A brief description of this item.
     *
     *
-    *  \param ExpectedMD5 The expected md5sum of the completely
+    *  \param ExpectedHash The expected md5sum of the completely
     *  reconstructed package index file; the index file will be tested
     *  reconstructed package index file; the index file will be tested
     *  against this value when it is entirely reconstructed.
     *  against this value when it is entirely reconstructed.
     *
     *
@@ -486,7 +486,7 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
     *  that depends on it.
     *  that depends on it.
     */
     */
    pkgAcqIndexDiffs(pkgAcquire *Owner,string URI,string URIDesc,
    pkgAcqIndexDiffs(pkgAcquire *Owner,string URI,string URIDesc,
-		    string ShortDesc, string ExpectedMD5,
+		    string ShortDesc, HashString ExpectedHash,
 		    vector<DiffInfo> diffs=vector<DiffInfo>());
 		    vector<DiffInfo> diffs=vector<DiffInfo>());
 };
 };
 
 
@@ -519,8 +519,8 @@ class pkgAcqIndex : public pkgAcquire::Item
     */
     */
    string RealURI;
    string RealURI;
 
 
-   /** \brief The expected md5sum of the decompressed index file. */
-   string ExpectedMD5;
+   /** \brief The expected hashsum of the decompressed index file. */
+   HashString ExpectedHash;
 
 
    /** \brief The compression-related file extension that is being
    /** \brief The compression-related file extension that is being
     *  added to the downloaded file (e.g., ".gz" or ".bz2").
     *  added to the downloaded file (e.g., ".gz" or ".bz2").
@@ -535,6 +535,7 @@ class pkgAcqIndex : public pkgAcquire::Item
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
    virtual string Custom600Headers();
    virtual string Custom600Headers();
    virtual string DescURI() {return RealURI + CompressionExtension;};
    virtual string DescURI() {return RealURI + CompressionExtension;};
+   virtual string HashSum() {return ExpectedHash.toStr(); };
 
 
    /** \brief Create a pkgAcqIndex.
    /** \brief Create a pkgAcqIndex.
     *
     *
@@ -547,14 +548,15 @@ class pkgAcqIndex : public pkgAcquire::Item
     *
     *
     *  \param ShortDesc A brief description of this index file.
     *  \param ShortDesc A brief description of this index file.
     *
     *
-    *  \param ExpectedMD5 The expected md5sum of this index file.
+    *  \param ExpectedHash The expected hashsum of this index file.
     *
     *
     *  \param compressExt The compression-related extension with which
     *  \param compressExt The compression-related extension with which
     *  this index file should be downloaded, or "" to autodetect
     *  this index file should be downloaded, or "" to autodetect
     *  (".bz2" is used if bzip2 is installed, ".gz" otherwise).
     *  (".bz2" is used if bzip2 is installed, ".gz" otherwise).
     */
     */
    pkgAcqIndex(pkgAcquire *Owner,string URI,string URIDesc,
    pkgAcqIndex(pkgAcquire *Owner,string URI,string URIDesc,
-	       string ShortDesct, string ExpectedMD5, string compressExt="");
+	       string ShortDesc, HashString ExpectedHash, 
+	       string compressExt="");
 };
 };
 
 
 /** \brief An acquire item that is responsible for fetching a
 /** \brief An acquire item that is responsible for fetching a
@@ -581,7 +583,7 @@ class pkgAcqIndexTrans : public pkgAcqIndex
     *
     *
     *  \param ShortDesc A brief description of this index file.
     *  \param ShortDesc A brief description of this index file.
     *
     *
-    *  \param ExpectedMD5 The expected md5sum of this index file.
+    *  \param ExpectedHash The expected hashsum of this index file.
     *
     *
     *  \param compressExt The compression-related extension with which
     *  \param compressExt The compression-related extension with which
     *  this index file should be downloaded, or "" to autodetect
     *  this index file should be downloaded, or "" to autodetect
@@ -673,9 +675,9 @@ class pkgAcqMetaSig : public pkgAcquire::Item
  *
  *
  *  Once the download and verification are complete, the downloads of
  *  Once the download and verification are complete, the downloads of
  *  the individual index files are queued up using pkgAcqDiffIndex.
  *  the individual index files are queued up using pkgAcqDiffIndex.
- *  If the meta-index file had a valid signature, the expected md5sums
+ *  If the meta-index file had a valid signature, the expected hashsums
  *  of the index files will be the md5sums listed in the meta-index;
  *  of the index files will be the md5sums listed in the meta-index;
- *  otherwise, the expected md5sums will be "" (causing the
+ *  otherwise, the expected hashsums will be "" (causing the
  *  authentication of the index files to be bypassed).
  *  authentication of the index files to be bypassed).
  */
  */
 class pkgAcqMetaIndex : public pkgAcquire::Item
 class pkgAcqMetaIndex : public pkgAcquire::Item
@@ -739,11 +741,11 @@ class pkgAcqMetaIndex : public pkgAcquire::Item
 
 
    /** \brief Starts downloading the individual index files.
    /** \brief Starts downloading the individual index files.
     *
     *
-    *  \param verify If \b true, only indices whose expected md5sum
+    *  \param verify If \b true, only indices whose expected hashsum
     *  can be determined from the meta-index will be downloaded, and
     *  can be determined from the meta-index will be downloaded, and
-    *  the md5sums of indices will be checked (reporting
+    *  the hashsums of indices will be checked (reporting
     *  #StatAuthError if there is a mismatch).  If verify is \b false,
     *  #StatAuthError if there is a mismatch).  If verify is \b false,
-    *  no md5sum checking will be performed.
+    *  no hashsum checking will be performed.
     */
     */
    void QueueIndexes(bool verify);
    void QueueIndexes(bool verify);
    
    
@@ -751,7 +753,7 @@ class pkgAcqMetaIndex : public pkgAcquire::Item
    
    
    // Specialized action members
    // Specialized action members
    virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
    virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+   virtual void Done(string Message,unsigned long Size, string Hash,
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
    virtual string Custom600Headers();
    virtual string Custom600Headers();
    virtual string DescURI() {return RealURI; };
    virtual string DescURI() {return RealURI; };
@@ -788,8 +790,8 @@ class pkgAcqArchive : public pkgAcquire::Item
     */
     */
    pkgRecords *Recs;
    pkgRecords *Recs;
 
 
-   /** \brief The md5sum of this package. */
-   string MD5;
+   /** \brief The hashsum of this package. */
+   HashString ExpectedHash;
 
 
    /** \brief A location in which the actual filename of the package
    /** \brief A location in which the actual filename of the package
     *  should be stored.
     *  should be stored.
@@ -817,13 +819,12 @@ class pkgAcqArchive : public pkgAcquire::Item
    public:
    public:
    
    
    virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
    virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+   virtual void Done(string Message,unsigned long Size,string Hash,
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
-   virtual string MD5Sum() {return MD5;};
    virtual string DescURI() {return Desc.URI;};
    virtual string DescURI() {return Desc.URI;};
    virtual string ShortDesc() {return Desc.ShortDesc;};
    virtual string ShortDesc() {return Desc.ShortDesc;};
    virtual void Finished();
    virtual void Finished();
-
+   virtual string HashSum() {return ExpectedHash.toStr(); };
    virtual bool IsTrusted();
    virtual bool IsTrusted();
    
    
    /** \brief Create a new pkgAcqArchive.
    /** \brief Create a new pkgAcqArchive.
@@ -860,8 +861,8 @@ class pkgAcqFile : public pkgAcquire::Item
    /** \brief The currently active download process. */
    /** \brief The currently active download process. */
    pkgAcquire::ItemDesc Desc;
    pkgAcquire::ItemDesc Desc;
 
 
-   /** \brief The md5sum of the file to download, if it is known. */
-   string Md5Hash;
+   /** \brief The hashsum of the file to download, if it is known. */
+   HashString ExpectedHash;
 
 
    /** \brief How many times to retry the download, set from
    /** \brief How many times to retry the download, set from
     *  Acquire::Retries.
     *  Acquire::Retries.
@@ -872,10 +873,10 @@ class pkgAcqFile : public pkgAcquire::Item
    
    
    // Specialized action members
    // Specialized action members
    virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
    virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+   virtual void Done(string Message,unsigned long Size,string CalcHash,
 		     pkgAcquire::MethodConfig *Cnf);
 		     pkgAcquire::MethodConfig *Cnf);
-   virtual string MD5Sum() {return Md5Hash;};
    virtual string DescURI() {return Desc.URI;};
    virtual string DescURI() {return Desc.URI;};
+   virtual string HashSum() {return ExpectedHash.toStr(); };
 
 
    /** \brief Create a new pkgAcqFile object.
    /** \brief Create a new pkgAcqFile object.
     *
     *
@@ -884,7 +885,7 @@ class pkgAcqFile : public pkgAcquire::Item
     *
     *
     *  \param URI The URI to download.
     *  \param URI The URI to download.
     *
     *
-    *  \param MD5 The md5sum of the file to download, if it is known;
+    *  \param Hash The hashsum of the file to download, if it is known;
     *  otherwise "".
     *  otherwise "".
     *
     *
     *  \param Size The size of the file to download, if it is known;
     *  \param Size The size of the file to download, if it is known;
@@ -906,7 +907,7 @@ class pkgAcqFile : public pkgAcquire::Item
     * is the absolute name to which the file should be downloaded.
     * is the absolute name to which the file should be downloaded.
     */
     */
 
 
-   pkgAcqFile(pkgAcquire *Owner, string URI, string MD5, unsigned long Size,
+   pkgAcqFile(pkgAcquire *Owner, string URI, string Hash, unsigned long Size,
 	      string Desc, string ShortDesc,
 	      string Desc, string ShortDesc,
 	      const string &DestDir="", const string &DestFilename="");
 	      const string &DestDir="", const string &DestFilename="");
 };
 };

+ 9 - 0
apt-pkg/acquire-method.cc

@@ -179,9 +179,14 @@ void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt)
 		      TimeRFC1123(Res.LastModified).c_str());
 		      TimeRFC1123(Res.LastModified).c_str());
 
 
    if (Res.MD5Sum.empty() == false)
    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),"MD5-Hash: %s\n",Res.MD5Sum.c_str());
+      End += snprintf(End,sizeof(S)-50 - (End - S),"MD5Sum-Hash: %s\n",Res.MD5Sum.c_str());
+   }
    if (Res.SHA1Sum.empty() == false)
    if (Res.SHA1Sum.empty() == false)
       End += snprintf(End,sizeof(S)-50 - (End - S),"SHA1-Hash: %s\n",Res.SHA1Sum.c_str());
       End += snprintf(End,sizeof(S)-50 - (End - S),"SHA1-Hash: %s\n",Res.SHA1Sum.c_str());
+   if (Res.SHA256Sum.empty() == false)
+      End += snprintf(End,sizeof(S)-50 - (End - S),"SHA256-Hash: %s\n",Res.SHA256Sum.c_str());
    if (UsedMirror.empty() == false)
    if (UsedMirror.empty() == false)
       End += snprintf(End,sizeof(S)-50 - (End - S),"UsedMirror: %s\n",UsedMirror.c_str());
       End += snprintf(End,sizeof(S)-50 - (End - S),"UsedMirror: %s\n",UsedMirror.c_str());
    if (Res.GPGVOutput.size() > 0)
    if (Res.GPGVOutput.size() > 0)
@@ -216,6 +221,9 @@ void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt)
       if (Alt->SHA1Sum.empty() == false)
       if (Alt->SHA1Sum.empty() == false)
 	 End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-SHA1-Hash: %s\n",
 	 End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-SHA1-Hash: %s\n",
 			 Alt->SHA1Sum.c_str());
 			 Alt->SHA1Sum.c_str());
+      if (Alt->SHA256Sum.empty() == false)
+	 End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-SHA256-Hash: %s\n",
+			 Alt->SHA256Sum.c_str());
       
       
       if (Alt->IMSHit == true)
       if (Alt->IMSHit == true)
 	 strcat(End,"Alt-IMS-Hit: true\n");
 	 strcat(End,"Alt-IMS-Hit: true\n");
@@ -460,5 +468,6 @@ void pkgAcqMethod::FetchResult::TakeHashes(Hashes &Hash)
 {
 {
    MD5Sum = Hash.MD5.Result();
    MD5Sum = Hash.MD5.Result();
    SHA1Sum = Hash.SHA1.Result();
    SHA1Sum = Hash.SHA1.Result();
+   SHA256Sum = Hash.SHA256.Result();
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 1 - 0
apt-pkg/acquire-method.h

@@ -43,6 +43,7 @@ class pkgAcqMethod
    {
    {
       string MD5Sum;
       string MD5Sum;
       string SHA1Sum;
       string SHA1Sum;
+      string SHA256Sum;
       vector<string> GPGVOutput;
       vector<string> GPGVOutput;
       time_t LastModified;
       time_t LastModified;
       bool IMSHit;
       bool IMSHit;

+ 16 - 1
apt-pkg/acquire-worker.cc

@@ -267,8 +267,23 @@ bool pkgAcquire::Worker::RunMessages()
 	       _error->Warning("Bizarre Error - File size is not what the server reported %s %lu",
 	       _error->Warning("Bizarre Error - File size is not what the server reported %s %lu",
 			       LookupTag(Message,"Size","0").c_str(),TotalSize);
 			       LookupTag(Message,"Size","0").c_str(),TotalSize);
 
 
+	    // see if there is a hash to verify
+	    string RecivedHash;
+	    HashString expectedHash(Owner->HashSum());
+	    if(!expectedHash.empty()) 
+	    {
+	       string hashTag = expectedHash.HashType()+"-Hash";
+	       RecivedHash = expectedHash.HashType() + ":" + LookupTag(Message, hashTag.c_str());
+	       if(_config->FindB("Debug::pkgAcquire::Auth", false) == true)
+	       {
+		  clog << "201 URI Done: " << Owner->DescURI() << endl
+		       << "RecivedHash: " << RecivedHash << endl
+		       << "ExpectedHash: " << expectedHash.toStr() 
+		       << endl << endl;
+	       }
+	    }
 	    Owner->Done(Message,atoi(LookupTag(Message,"Size","0").c_str()),
 	    Owner->Done(Message,atoi(LookupTag(Message,"Size","0").c_str()),
-			LookupTag(Message,"MD5-Hash"),Config);
+			RecivedHash.c_str(), Config);
 	    ItemDone();
 	    ItemDone();
 	    
 	    
 	    // Log that we are done
 	    // Log that we are done

+ 84 - 0
apt-pkg/contrib/hashes.cc

@@ -12,11 +12,95 @@
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
 #include <apt-pkg/hashes.h>
 #include <apt-pkg/hashes.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/configuration.h>
     
     
 #include <unistd.h>    
 #include <unistd.h>    
 #include <system.h>    
 #include <system.h>    
+#include <string>
+#include <iostream>
 									/*}}}*/
 									/*}}}*/
 
 
+const char* HashString::_SupportedHashes[] = 
+{
+   "SHA256", "SHA1", "MD5Sum", NULL
+};
+
+HashString::HashString()
+{
+}
+
+HashString::HashString(string Type, string Hash) : Type(Type), Hash(Hash)
+{
+}
+
+HashString::HashString(string StringedHash)
+{
+   // legacy: md5sum without "MD5Sum:" prefix
+   if (StringedHash.find(":") == string::npos && StringedHash.size() == 32)
+   {
+      Type = "MD5Sum";
+      Hash = StringedHash;
+      return;
+   }
+   string::size_type pos = StringedHash.find(":");
+   Type = StringedHash.substr(0,pos);
+   Hash = StringedHash.substr(pos+1, StringedHash.size() - pos);
+
+   if(_config->FindB("Debug::Hashes",false) == true)
+      std::clog << "HashString(string): " << Type << " : " << Hash << std::endl;
+}
+
+
+bool HashString::VerifyFile(string filename) const
+{
+   FileFd fd;
+   MD5Summation MD5;
+   SHA1Summation SHA1;
+   SHA256Summation SHA256;
+   string fileHash;
+
+   FileFd Fd(filename, FileFd::ReadOnly);
+   if(Type == "MD5Sum") 
+   {
+      MD5.AddFD(Fd.Fd(), Fd.Size());
+      fileHash = (string)MD5.Result();
+   } 
+   else if (Type == "SHA1")
+   {
+      SHA1.AddFD(Fd.Fd(), Fd.Size());
+      fileHash = (string)SHA1.Result();
+   } 
+   else if (Type == "SHA256") 
+   {
+      SHA256.AddFD(Fd.Fd(), Fd.Size());
+      fileHash = (string)SHA256.Result();
+   }
+   Fd.Close();
+
+   if(_config->FindB("Debug::Hashes",false) == true)
+      std::clog << "HashString::VerifyFile: got: " << fileHash << " expected: " << toStr() << std::endl;
+
+   return (fileHash == Hash);
+}
+
+const char** HashString::SupportedHashes()
+{
+   return _SupportedHashes;
+}
+
+bool HashString::empty() const
+{
+   return (Type.empty() || Hash.empty());
+}
+
+
+string HashString::toStr() const
+{
+   return Type+string(":")+Hash;
+}
+
+
 // Hashes::AddFD - Add the contents of the FD				/*{{{*/
 // Hashes::AddFD - Add the contents of the FD				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */

+ 30 - 0
apt-pkg/contrib/hashes.h

@@ -19,8 +19,38 @@
 #include <apt-pkg/sha256.h>
 #include <apt-pkg/sha256.h>
 
 
 #include <algorithm>
 #include <algorithm>
+#include <vector>
 
 
 using std::min;
 using std::min;
+using std::vector;
+
+// helper class that contains hash function name
+// and hash
+class HashString
+{
+ protected:
+   string Type;
+   string Hash;
+   static const char * _SupportedHashes[10];
+
+ public:
+   HashString(string Type, string Hash);
+   HashString(string StringedHashString);  // init from str as "type:hash"
+   HashString();
+
+   // get hash type used
+   string HashType() { return Type; };
+
+   // verify the given filename against the currently loaded hash
+   bool VerifyFile(string filename) const;
+
+   // helper
+   string toStr() const;                    // convert to str as "type:hash"
+   bool empty() const;
+
+   // return the list of hashes we support
+   static const char** SupportedHashes();
+};
 
 
 class Hashes
 class Hashes
 {
 {

+ 1 - 1
apt-pkg/deb/debmetaindex.cc

@@ -144,7 +144,7 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const
       vector <struct IndexTarget *> *targets = ComputeIndexTargets();
       vector <struct IndexTarget *> *targets = ComputeIndexTargets();
       for (vector <struct IndexTarget*>::const_iterator Target = targets->begin(); Target != targets->end(); Target++) {
       for (vector <struct IndexTarget*>::const_iterator Target = targets->begin(); Target != targets->end(); Target++) {
 	 new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
 	 new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
-			 (*Target)->ShortDesc, "");
+			 (*Target)->ShortDesc, HashString());
       }
       }
    }
    }
    new pkgAcqMetaSig(Owner, MetaIndexURI("Release.gpg"),
    new pkgAcqMetaSig(Owner, MetaIndexURI("Release.gpg"),

+ 8 - 0
apt-pkg/deb/debrecords.cc

@@ -67,6 +67,14 @@ string debRecordParser::SHA1Hash()
    return Section.FindS("SHA1");
    return Section.FindS("SHA1");
 }
 }
 									/*}}}*/
 									/*}}}*/
+// RecordParser::SHA1Hash - Return the archive hash			/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string debRecordParser::SHA256Hash()
+{
+   return Section.FindS("SHA256");
+}
+									/*}}}*/
 // RecordParser::Maintainer - Return the maintainer email		/*{{{*/
 // RecordParser::Maintainer - Return the maintainer email		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */

+ 1 - 0
apt-pkg/deb/debrecords.h

@@ -35,6 +35,7 @@ class debRecordParser : public pkgRecords::Parser
    virtual string FileName();
    virtual string FileName();
    virtual string MD5Hash();
    virtual string MD5Hash();
    virtual string SHA1Hash();
    virtual string SHA1Hash();
+   virtual string SHA256Hash();
    virtual string SourcePkg();
    virtual string SourcePkg();
    virtual string SourceVer();
    virtual string SourceVer();
    
    

+ 1 - 1
apt-pkg/deb/debsrcrecords.cc

@@ -137,7 +137,7 @@ bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List)
 	    break;
 	    break;
 	 F.Type = string(F.Path,Tmp+1,Pos-Tmp);
 	 F.Type = string(F.Path,Tmp+1,Pos-Tmp);
 	 
 	 
-	 if (F.Type == "gz" || F.Type == "bz2")
+	 if (F.Type == "gz" || F.Type == "bz2" || F.Type == "lzma")
 	 {
 	 {
 	    Pos = Tmp-1;
 	    Pos = Tmp-1;
 	    continue;
 	    continue;

+ 253 - 134
apt-pkg/deb/dpkgpm.cc

@@ -18,6 +18,7 @@
 #include <unistd.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <fcntl.h>
 #include <fcntl.h>
+#include <sys/select.h>
 #include <sys/types.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/wait.h>
 #include <signal.h>
 #include <signal.h>
@@ -26,17 +27,24 @@
 #include <sstream>
 #include <sstream>
 #include <map>
 #include <map>
 
 
+#include <termios.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <pty.h>
+
 #include <config.h>
 #include <config.h>
 #include <apti18n.h>
 #include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
 
 
 using namespace std;
 using namespace std;
 
 
+
+
 // DPkgPM::pkgDPkgPM - Constructor					/*{{{*/
 // DPkgPM::pkgDPkgPM - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
 pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) 
 pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) 
-   : pkgPackageManager(Cache), pkgFailures(0)
+   : pkgPackageManager(Cache), dpkgbuf_pos(0), PackagesTotal(0), PackagesDone(0)
 {
 {
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -325,7 +333,170 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
 
 
    return true;
    return true;
 }
 }
+
+									/*}}}*/
+// DPkgPM::DoStdin - Read stdin and pass to slave pty			/*{{{*/
+// ---------------------------------------------------------------------
+/*
+*/
+void pkgDPkgPM::DoStdin(int master)
+{
+   char input_buf[256] = {0,}; 
+   int len = read(0, input_buf, sizeof(input_buf));
+   write(master, input_buf, len);
+}
+									/*}}}*/
+// DPkgPM::DoTerminalPty - Read the terminal pty and write log		/*{{{*/
+// ---------------------------------------------------------------------
+/*
+ * read the terminal pty and write log
+ */
+void pkgDPkgPM::DoTerminalPty(int master, FILE *term_out)
+{
+   char term_buf[1024] = {0,};
+
+   int len=read(master, term_buf, sizeof(term_buf));
+   if(len <= 0)
+      return;
+   write(1, term_buf, len);
+   if(term_out)
+      fwrite(term_buf, len, sizeof(char), term_out);
+}
+									/*}}}*/
+// DPkgPM::ProcessDpkgStatusBuf                                        	/*{{{*/
+// ---------------------------------------------------------------------
+/*
+ */
+void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
+{
+   // the status we output
+   ostringstream status;
+
+   if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+      std::clog << "got from dpkg '" << line << "'" << std::endl;
+
+
+   /* dpkg sends strings like this:
+      'status:   <pkg>:  <pkg  qstate>'
+      errors look like this:
+      'status: /var/cache/apt/archives/krecipes_0.8.1-0ubuntu1_i386.deb : error : trying to overwrite `/usr/share/doc/kde/HTML/en/krecipes/krectip.png', which is also in package krecipes-data 
+      and conffile-prompt like this
+      'status: conffile-prompt: conffile : 'current-conffile' 'new-conffile' useredited distedited
+	    
+   */
+   char* list[5];
+   //        dpkg sends multiline error messages sometimes (see
+   //        #374195 for a example. we should support this by
+   //        either patching dpkg to not send multiline over the
+   //        statusfd or by rewriting the code here to deal with
+   //        it. for now we just ignore it and not crash
+   TokSplitString(':', line, list, sizeof(list)/sizeof(list[0]));
+   char *pkg = list[1];
+   char *action = _strstrip(list[2]);
+   if( pkg == NULL || action == NULL) 
+   {
+      if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+	 std::clog << "ignoring line: not enough ':'" << std::endl;
+      return;
+   }
+
+   if(strncmp(action,"error",strlen("error")) == 0)
+   {
+      status << "pmerror:" << list[1]
+	     << ":"  << (PackagesDone/float(PackagesTotal)*100.0) 
+	     << ":" << list[3]
+	     << endl;
+      if(OutStatusFd > 0)
+	 write(OutStatusFd, status.str().c_str(), status.str().size());
+      if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+	 std::clog << "send: '" << status.str() << "'" << endl;
+      pkgFailures++;
+      WriteApportReport(list[1], list[3]);
+      return;
+   }
+   if(strncmp(action,"conffile",strlen("conffile")) == 0)
+   {
+      status << "pmconffile:" << list[1]
+	     << ":"  << (PackagesDone/float(PackagesTotal)*100.0) 
+	     << ":" << list[3]
+	     << endl;
+      if(OutStatusFd > 0)
+	 write(OutStatusFd, status.str().c_str(), status.str().size());
+      if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+	 std::clog << "send: '" << status.str() << "'" << endl;
+      return;
+   }
+
+   vector<struct DpkgState> &states = PackageOps[pkg];
+   const char *next_action = NULL;
+   if(PackageOpsDone[pkg] < states.size())
+      next_action = states[PackageOpsDone[pkg]].state;
+   // check if the package moved to the next dpkg state
+   if(next_action && (strcmp(action, next_action) == 0)) 
+   {
+      // only read the translation if there is actually a next
+      // action
+      const char *translation = _(states[PackageOpsDone[pkg]].str);
+      char s[200];
+      snprintf(s, sizeof(s), translation, pkg);
+
+      // we moved from one dpkg state to a new one, report that
+      PackageOpsDone[pkg]++;
+      PackagesDone++;
+      // build the status str
+      status << "pmstatus:" << pkg 
+	     << ":"  << (PackagesDone/float(PackagesTotal)*100.0) 
+	     << ":" << s
+	     << endl;
+      if(OutStatusFd > 0)
+	 write(OutStatusFd, status.str().c_str(), status.str().size());
+      if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+	 std::clog << "send: '" << status.str() << "'" << endl;
+   }
+   if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) 
+      std::clog << "(parsed from dpkg) pkg: " << pkg 
+		<< " action: " << action << endl;
+}
+
+// DPkgPM::DoDpkgStatusFd                                           	/*{{{*/
+// ---------------------------------------------------------------------
+/*
+ */
+void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd)
+{
+   char *p, *q;
+   int len;
+
+   len=read(statusfd, &dpkgbuf[dpkgbuf_pos], sizeof(dpkgbuf)-dpkgbuf_pos);
+   dpkgbuf_pos += len;
+   if(len <= 0)
+      return;
+
+   // process line by line if we have a buffer
+   p = q = dpkgbuf;
+   while((q=(char*)memchr(p, '\n', dpkgbuf+dpkgbuf_pos-p)) != NULL)
+   {
+      *q = 0;
+      ProcessDpkgStatusLine(OutStatusFd, p);
+      p=q+1; // continue with next line
+   }
+
+   // now move the unprocessed bits (after the final \n that is now a 0x0) 
+   // to the start and update dpkgbuf_pos
+   p = (char*)memrchr(dpkgbuf, 0, dpkgbuf_pos);
+   if(p == NULL)
+      return;
+
+   // we are interessted in the first char *after* 0x0
+   p++;
+
+   // move the unprocessed tail to the start and update pos
+   memmove(dpkgbuf, p, p-dpkgbuf);
+   dpkgbuf_pos = dpkgbuf+dpkgbuf_pos-p;
+}
 									/*}}}*/
 									/*}}}*/
+
+
 // DPkgPM::Go - Run the sequence					/*{{{*/
 // DPkgPM::Go - Run the sequence					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This globs the operations and calls dpkg 
 /* This globs the operations and calls dpkg 
@@ -346,9 +517,6 @@ bool pkgDPkgPM::Go(int OutStatusFd)
    if (RunScriptsWithPkgs("DPkg::Pre-Install-Pkgs") == false)
    if (RunScriptsWithPkgs("DPkg::Pre-Install-Pkgs") == false)
       return false;
       return false;
    
    
-   // prepare the progress reporting 
-   int Done = 0;
-   int Total = 0;
    // map the dpkg states to the operations that are performed
    // map the dpkg states to the operations that are performed
    // (this is sorted in the same way as Item::Ops)
    // (this is sorted in the same way as Item::Ops)
    static const struct DpkgState DpkgStatesOpMap[][5] = {
    static const struct DpkgState DpkgStatesOpMap[][5] = {
@@ -380,15 +548,6 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       },
       },
    };
    };
 
 
-   // the dpkg states that the pkg will run through, the string is 
-   // the package, the vector contains the dpkg states that the package
-   // will go through
-   map<string,vector<struct DpkgState> > PackageOps;
-   // the dpkg states that are already done; the string is the package
-   // the int is the state that is already done (e.g. a package that is
-   // going to be install is already in state "half-installed")
-   map<string,unsigned int> PackageOpsDone;
-
    // init the PackageOps map, go over the list of packages that
    // init the PackageOps map, go over the list of packages that
    // that will be [installed|configured|removed|purged] and add
    // that will be [installed|configured|removed|purged] and add
    // them to the PackageOps map (the dpkg states it goes through)
    // them to the PackageOps map (the dpkg states it goes through)
@@ -400,10 +559,31 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       for(int i=0; (DpkgStatesOpMap[(*I).Op][i]).state != NULL;  i++) 
       for(int i=0; (DpkgStatesOpMap[(*I).Op][i]).state != NULL;  i++) 
       {
       {
 	 PackageOps[name].push_back(DpkgStatesOpMap[(*I).Op][i]);
 	 PackageOps[name].push_back(DpkgStatesOpMap[(*I).Op][i]);
-	 Total++;
+	 PackagesTotal++;
       }
       }
    }   
    }   
 
 
+   // create log
+   string logdir = _config->FindDir("Dir::Log");
+   if(not FileExists(logdir))
+      return _error->Error(_("Directory '%s' missing"), logdir.c_str());
+   string logfile_name = flCombine(logdir,
+				   _config->Find("Dir::Log::Terminal"));
+   FILE *term_out = NULL;
+   if (!logfile_name.empty())
+   {
+      term_out = fopen(logfile_name.c_str(),"a");
+      chmod(logfile_name.c_str(), 0600);
+      // output current time
+      char outstr[200];
+      time_t t = time(NULL);
+      struct tm *tmp = localtime(&t);
+      strftime(outstr, sizeof(outstr), "%F  %T", tmp);
+      fprintf(term_out, "\nLog started: ");
+      fprintf(term_out, outstr);
+      fprintf(term_out, "\n");
+   }
+
    // this loop is runs once per operation
    // this loop is runs once per operation
    for (vector<Item>::iterator I = List.begin(); I != List.end();)
    for (vector<Item>::iterator I = List.begin(); I != List.end();)
    {
    {
@@ -518,7 +698,26 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	 it doesn't die but we do! So we must also ignore it */
 	 it doesn't die but we do! So we must also ignore it */
       sighandler_t old_SIGQUIT = signal(SIGQUIT,SIG_IGN);
       sighandler_t old_SIGQUIT = signal(SIGQUIT,SIG_IGN);
       sighandler_t old_SIGINT = signal(SIGINT,SIG_IGN);
       sighandler_t old_SIGINT = signal(SIGINT,SIG_IGN);
-	
+
+      struct	termios tt;
+      struct	winsize win;
+      int	master;
+      int	slave;
+
+      // FIXME: setup sensible signal handling (*ick*)
+      tcgetattr(0, &tt);
+      ioctl(0, TIOCGWINSZ, (char *)&win);
+      if (openpty(&master, &slave, NULL, &tt, &win) < 0) 
+      {
+	 fprintf(stderr, _("openpty failed\n"));
+      }
+
+      struct termios rtt;
+      rtt = tt;
+      cfmakeraw(&rtt);
+      rtt.c_lflag &= ~ECHO;
+      tcsetattr(0, TCSAFLUSH, &rtt);
+
        // Fork dpkg
        // Fork dpkg
       pid_t Child;
       pid_t Child;
       _config->Set("APT::Keep-Fds::",fd[1]);
       _config->Set("APT::Keep-Fds::",fd[1]);
@@ -527,8 +726,15 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       // This is the child
       // This is the child
       if (Child == 0)
       if (Child == 0)
       {
       {
+	 setsid();
+	 ioctl(slave, TIOCSCTTY, 0);
+	 close(master);
+	 dup2(slave, 0);
+	 dup2(slave, 1);
+	 dup2(slave, 2);
+	 close(slave);
 	 close(fd[0]); // close the read end of the pipe
 	 close(fd[0]); // close the read end of the pipe
-	 
+
 	 if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0)
 	 if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0)
 	    _exit(100);
 	    _exit(100);
 	 
 	 
@@ -547,7 +753,8 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	    if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0)
 	    if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0)
 	       _exit(100);
 	       _exit(100);
 	 }
 	 }
-	 
+
+
 	 /* No Job Control Stop Env is a magic dpkg var that prevents it
 	 /* No Job Control Stop Env is a magic dpkg var that prevents it
 	    from using sigstop */
 	    from using sigstop */
 	 putenv("DPKG_NO_TSTP=yes");
 	 putenv("DPKG_NO_TSTP=yes");
@@ -564,16 +771,19 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 
 
       // we read from dpkg here
       // we read from dpkg here
       int _dpkgin = fd[0];
       int _dpkgin = fd[0];
-      fcntl(_dpkgin, F_SETFL, O_NONBLOCK);
       close(fd[1]);                        // close the write end of the pipe
       close(fd[1]);                        // close the write end of the pipe
 
 
       // the read buffers for the communication with dpkg
       // the read buffers for the communication with dpkg
-      char line[1024] = {0,};
       char buf[2] = {0,0};
       char buf[2] = {0,0};
       
       
       // the result of the waitpid call
       // the result of the waitpid call
       int res;
       int res;
+      close(slave);
 
 
+      // setups fds
+      fd_set rfds;
+      struct timeval tv;
+      int select_ret;
       while ((res=waitpid(Child,&Status, WNOHANG)) != Child) {
       while ((res=waitpid(Child,&Status, WNOHANG)) != Child) {
 	 if(res < 0) {
 	 if(res < 0) {
 	    // FIXME: move this to a function or something, looks ugly here
 	    // FIXME: move this to a function or something, looks ugly here
@@ -587,129 +797,34 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	    signal(SIGINT,old_SIGINT);
 	    signal(SIGINT,old_SIGINT);
 	    return _error->Errno("waitpid","Couldn't wait for subprocess");
 	    return _error->Errno("waitpid","Couldn't wait for subprocess");
 	 }
 	 }
-	 
-	 // read a single char, make sure that the read can't block 
-	 // (otherwise we may leave zombies)
-         int len = read(_dpkgin, buf, 1);
-
-	 // nothing to read, wait a bit for more
-	 if(len <= 0)
-	 {
-	    usleep(1000);
-	    continue;
-	 }
-	 
-	 // sanity check (should never happen)
-	 if(strlen(line) >= sizeof(line)-10)
-	 {
-	    _error->Error("got a overlong line from dpkg: '%s'",line);
-	    line[0]=0;
-	 }
-	 // append to line, check if we got a complete line
-	 strcat(line, buf);
-	 if(buf[0] != '\n')
-	    continue;
-
-	 if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
-	    std::clog << "got from dpkg '" << line << "'" << std::endl;
-
-	 // the status we output
-	 ostringstream status;
 
 
-	 /* dpkg sends strings like this:
-	    'status:   <pkg>:  <pkg  qstate>'
-	    errors look like this:
-	    'status: /var/cache/apt/archives/krecipes_0.8.1-0ubuntu1_i386.deb : error : trying to overwrite `/usr/share/doc/kde/HTML/en/krecipes/krectip.png', which is also in package krecipes-data 
-	    and conffile-prompt like this
-	    'status: conffile-prompt: conffile : 'current-conffile' 'new-conffile' useredited distedited
-	    
-	 */
-	 char* list[5];
-	 //        dpkg sends multiline error messages sometimes (see
-	 //        #374195 for a example. we should support this by
-	 //        either patching dpkg to not send multiline over the
-	 //        statusfd or by rewriting the code here to deal with
-	 //        it. for now we just ignore it and not crash
-	 TokSplitString(':', line, list, sizeof(list)/sizeof(list[0]));
-	 char *pkg = list[1];
-	 char *action = _strstrip(list[2]);
-	 if( pkg == NULL || action == NULL) 
-	 {
-	    if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
-	       std::clog << "ignoring line: not enough ':'" << std::endl;
-	    // reset the line buffer
-	    line[0]=0;
-	    continue;
-	 }
-
-	 if(strncmp(action,"error",strlen("error")) == 0)
-	 {
-	    status << "pmerror:" << list[1]
-		   << ":"  << (Done/float(Total)*100.0) 
-		   << ":" << list[3]
-		   << endl;
-	    if(OutStatusFd > 0)
-	       write(OutStatusFd, status.str().c_str(), status.str().size());
-	    line[0]=0;
-	    if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
-	       std::clog << "send: '" << status.str() << "'" << endl;
-	    pkgFailures++;
-	    WriteApportReport(list[1], list[3]);
+	 // wait for input or output here
+	 FD_ZERO(&rfds);
+	 FD_SET(0, &rfds); 
+	 FD_SET(_dpkgin, &rfds);
+	 FD_SET(master, &rfds);
+	 tv.tv_sec = 1;
+	 tv.tv_usec = 0;
+	 select_ret = select(max(master, _dpkgin)+1, &rfds, NULL, NULL, &tv);
+	 if (select_ret < 0)
+	    std::cerr << "Error in select()" << std::endl;
+	 else if (select_ret == 0)
 	    continue;
 	    continue;
-	 }
-	 if(strncmp(action,"conffile",strlen("conffile")) == 0)
-	 {
-	    status << "pmconffile:" << list[1]
-		   << ":"  << (Done/float(Total)*100.0) 
-		   << ":" << list[3]
-		   << endl;
-	    if(OutStatusFd > 0)
-	       write(OutStatusFd, status.str().c_str(), status.str().size());
-	    line[0]=0;
-	    if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
-	       std::clog << "send: '" << status.str() << "'" << endl;
-	    continue;
-	 }
-
-	 vector<struct DpkgState> &states = PackageOps[pkg];
-	 const char *next_action = NULL;
-	 if(PackageOpsDone[pkg] < states.size())
-	    next_action = states[PackageOpsDone[pkg]].state;
-	 // check if the package moved to the next dpkg state
-	 if(next_action && (strcmp(action, next_action) == 0)) 
-	 {
-	    // only read the translation if there is actually a next
-	    // action
-	    const char *translation = _(states[PackageOpsDone[pkg]].str);
-	    char s[200];
-	    snprintf(s, sizeof(s), translation, pkg);
-
-	    // we moved from one dpkg state to a new one, report that
-	    PackageOpsDone[pkg]++;
-	    Done++;
-	    // build the status str
-	    status << "pmstatus:" << pkg 
-		   << ":"  << (Done/float(Total)*100.0) 
-		   << ":" << s
-		   << endl;
-	    if(OutStatusFd > 0)
-	       write(OutStatusFd, status.str().c_str(), status.str().size());
-	    if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
-	       std::clog << "send: '" << status.str() << "'" << endl;
 
 
-	 }
-	 if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) 
-	    std::clog << "(parsed from dpkg) pkg: " << pkg 
-		      << " action: " << action << endl;
-
-	 // reset the line buffer
-	 line[0]=0;
+	 if(FD_ISSET(master, &rfds))
+	    DoTerminalPty(master, term_out);
+	 if(FD_ISSET(0, &rfds))
+	    DoStdin(master);
+	 if(FD_ISSET(_dpkgin, &rfds))
+	    DoDpkgStatusFd(_dpkgin, OutStatusFd);
       }
       }
       close(_dpkgin);
       close(_dpkgin);
 
 
       // Restore sig int/quit
       // Restore sig int/quit
       signal(SIGQUIT,old_SIGQUIT);
       signal(SIGQUIT,old_SIGQUIT);
       signal(SIGINT,old_SIGINT);
       signal(SIGINT,old_SIGINT);
+
+      tcsetattr(0, TCSAFLUSH, &tt);
        
        
       // Check for an error code.
       // Check for an error code.
       if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
       if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
@@ -729,10 +844,14 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	 else 
 	 else 
 	    _error->Error("Sub-process %s exited unexpectedly",Args[0]);
 	    _error->Error("Sub-process %s exited unexpectedly",Args[0]);
 
 
-	 if(stopOnError)
+	 if(stopOnError) 
+	 {
+	    fclose(term_out);
 	    return false;
 	    return false;
+	 }
       }      
       }      
    }
    }
+   fclose(term_out);
 
 
    if (RunScripts("DPkg::Post-Invoke") == false)
    if (RunScripts("DPkg::Post-Invoke") == false)
       return false;
       return false;

+ 29 - 2
apt-pkg/deb/dpkgpm.h

@@ -12,22 +12,43 @@
 
 
 #include <apt-pkg/packagemanager.h>
 #include <apt-pkg/packagemanager.h>
 #include <vector>
 #include <vector>
+#include <map>
 #include <stdio.h>
 #include <stdio.h>
 
 
 using std::vector;
 using std::vector;
+using std::map;
+
 
 
 class pkgDPkgPM : public pkgPackageManager
 class pkgDPkgPM : public pkgPackageManager
 {
 {
+   private:
+
+   // the buffer we use for the dpkg status-fd reading
+   char dpkgbuf[1024];
+   int dpkgbuf_pos;
+
    protected:
    protected:
    int pkgFailures;
    int pkgFailures;
 
 
-   // used for progress reporting
+   // progress reporting
    struct DpkgState 
    struct DpkgState 
    {
    {
       const char *state;     // the dpkg state (e.g. "unpack")
       const char *state;     // the dpkg state (e.g. "unpack")
       const char *str;       // the human readable translation of the state
       const char *str;       // the human readable translation of the state
    };
    };
-   
+
+   // the dpkg states that the pkg will run through, the string is 
+   // the package, the vector contains the dpkg states that the package
+   // will go through
+   map<string,vector<struct DpkgState> > PackageOps;
+   // the dpkg states that are already done; the string is the package
+   // the int is the state that is already done (e.g. a package that is
+   // going to be install is already in state "half-installed")
+   map<string,int> PackageOpsDone;
+   // progress reporting
+   int PackagesDone;
+   int PackagesTotal;
+  
    struct Item
    struct Item
    {
    {
       enum Ops {Install, Configure, Remove, Purge} Op;
       enum Ops {Install, Configure, Remove, Purge} Op;
@@ -48,6 +69,12 @@ class pkgDPkgPM : public pkgPackageManager
    // apport integration
    // apport integration
    void WriteApportReport(const char *pkgpath, const char *errormsg);
    void WriteApportReport(const char *pkgpath, const char *errormsg);
 
 
+   // input processing
+   void DoStdin(int master);
+   void DoTerminalPty(int master, FILE *out);
+   void DoDpkgStatusFd(int statusfd, int OutStatusFd);
+   void ProcessDpkgStatusLine(int OutStatusFd, char *line);
+
    // The Actuall installation implementation
    // The Actuall installation implementation
    virtual bool Install(PkgIterator Pkg,string File);
    virtual bool Install(PkgIterator Pkg,string File);
    virtual bool Configure(PkgIterator Pkg);
    virtual bool Configure(PkgIterator Pkg);

+ 3 - 10
apt-pkg/indexcopy.cc

@@ -528,23 +528,16 @@ bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex)
       return false;
       return false;
    }
    }
 
 
-   MD5Summation sum;
-   FileFd Fd(prefix+file, FileFd::ReadOnly);
-   sum.AddFD(Fd.Fd(), Fd.Size());
-   Fd.Close();
-   string MD5 = (string)sum.Result();
-   
-   if (Record->MD5Hash != MD5)
+   if (!Record->Hash.VerifyFile(prefix+file))
    {
    {
-      _error->Warning("MD5 mismatch for: %s",file.c_str());
+      _error->Warning("Hash mismatch for: %s",file.c_str());
       return false;
       return false;
    }
    }
 
 
    if(_config->FindB("Debug::aptcdrom",false)) 
    if(_config->FindB("Debug::aptcdrom",false)) 
    {
    {
       cout << "File: " << prefix+file << endl;
       cout << "File: " << prefix+file << endl;
-      cout << "Expected MD5sum: " << Record->MD5Hash << endl;
-      cout << "got: " << MD5 << endl << endl;
+      cout << "Expected Hash " << Record->Hash.toStr() << endl;
    }
    }
 
 
    return true;
    return true;

+ 27 - 21
apt-pkg/indexrecords.cc

@@ -50,32 +50,38 @@ bool indexRecords::Load(const string Filename)
 
 
    const char *Start, *End;
    const char *Start, *End;
    Section.Get (Start, End, 0);
    Section.Get (Start, End, 0);
+
    Suite = Section.FindS("Suite");
    Suite = Section.FindS("Suite");
    Dist = Section.FindS("Codename");
    Dist = Section.FindS("Codename");
-//    if (Dist.empty())
-//    {
-//       ErrorText = _(("No Codename entry in Release file " + Filename).c_str());
-//       return false;
-//    }
-   if (!Section.Find("MD5Sum", Start, End))
+
+   int i;
+   for (i=0;HashString::SupportedHashes()[i] != NULL; i++)
    {
    {
-      ErrorText = _(("No MD5Sum entry in Release file " + Filename).c_str());
-      return false;
+      if (!Section.Find(HashString::SupportedHashes()[i], Start, End))
+	 continue;
+
+      string Name;
+      string Hash;
+      size_t Size;
+      while (Start < End)
+      {
+	 if (!parseSumData(Start, End, Name, Hash, Size))
+	    return false;
+	 indexRecords::checkSum *Sum = new indexRecords::checkSum;
+	 Sum->MetaKeyFilename = Name;
+	 Sum->Hash = HashString(HashString::SupportedHashes()[i],Hash);
+	 Sum->Size = Size;
+	 Entries[Name] = Sum;
+      }
+      break;
    }
    }
-   string Name;
-   string MD5Hash;
-   size_t Size;
-   while (Start < End)
+
+   if(HashString::SupportedHashes()[i] == NULL)
    {
    {
-      if (!parseSumData(Start, End, Name, MD5Hash, Size))
-	 return false;
-      indexRecords::checkSum *Sum = new indexRecords::checkSum;
-      Sum->MetaKeyFilename = Name;
-      Sum->MD5Hash = MD5Hash;
-      Sum->Size = Size;
-      Entries[Name] = Sum;
-   }
-   
+      ErrorText = _(("No Hash entry in Release file " + Filename).c_str());
+      return false;
+   }  
+
    string Strdate = Section.FindS("Date"); // FIXME: verify this somehow?
    string Strdate = Section.FindS("Date"); // FIXME: verify this somehow?
    return true;
    return true;
 }
 }

+ 2 - 1
apt-pkg/indexrecords.h

@@ -8,6 +8,7 @@
 
 
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
+#include <apt-pkg/hashes.h>
 
 
 #include <map>
 #include <map>
 #include <vector>
 #include <vector>
@@ -45,7 +46,7 @@ class indexRecords
 struct indexRecords::checkSum
 struct indexRecords::checkSum
 {
 {
    string MetaKeyFilename;
    string MetaKeyFilename;
-   string MD5Hash;
+   HashString Hash;
    size_t Size;      
    size_t Size;      
 };
 };
 
 

+ 5 - 7
apt-pkg/init.cc

@@ -24,8 +24,6 @@ const char *pkgVersion = VERSION;
 const char *pkgLibVersion = Stringfy(APT_PKG_MAJOR) "."
 const char *pkgLibVersion = Stringfy(APT_PKG_MAJOR) "."
                             Stringfy(APT_PKG_MINOR) "." 
                             Stringfy(APT_PKG_MINOR) "." 
                             Stringfy(APT_PKG_RELEASE);
                             Stringfy(APT_PKG_RELEASE);
-const char *pkgCPU = COMMON_CPU;
-const char *pkgOS = COMMON_OS;
     
     
 // pkgInitConfig - Initialize the configuration class			/*{{{*/
 // pkgInitConfig - Initialize the configuration class			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
@@ -35,11 +33,7 @@ const char *pkgOS = COMMON_OS;
 bool pkgInitConfig(Configuration &Cnf)
 bool pkgInitConfig(Configuration &Cnf)
 {
 {
    // General APT things
    // General APT things
-   if (strcmp(COMMON_OS,"linux") == 0 ||
-       strcmp(COMMON_OS,"unknown") == 0)
-      Cnf.Set("APT::Architecture",COMMON_CPU);
-   else
-      Cnf.Set("APT::Architecture",COMMON_OS "-" COMMON_CPU);
+   Cnf.Set("APT::Architecture", COMMON_ARCH);
    Cnf.Set("APT::Build-Essential::", "build-essential");
    Cnf.Set("APT::Build-Essential::", "build-essential");
    Cnf.Set("APT::Install-Recommends", false);
    Cnf.Set("APT::Install-Recommends", false);
    Cnf.Set("APT::Install-Suggests", false);
    Cnf.Set("APT::Install-Suggests", false);
@@ -75,6 +69,10 @@ bool pkgInitConfig(Configuration &Cnf)
    Cnf.Set("Dir::Etc::parts","apt.conf.d");
    Cnf.Set("Dir::Etc::parts","apt.conf.d");
    Cnf.Set("Dir::Etc::preferences","preferences");
    Cnf.Set("Dir::Etc::preferences","preferences");
    Cnf.Set("Dir::Bin::methods","/usr/lib/apt/methods");
    Cnf.Set("Dir::Bin::methods","/usr/lib/apt/methods");
+
+   // State   
+   Cnf.Set("Dir::Log","var/log/apt");
+   Cnf.Set("Dir::Log::Name","term.log");
    
    
    bool Res = true;
    bool Res = true;
    
    

+ 1 - 3
apt-pkg/init.h

@@ -18,13 +18,11 @@
 
 
 // See the makefile
 // See the makefile
 #define APT_PKG_MAJOR 4
 #define APT_PKG_MAJOR 4
-#define APT_PKG_MINOR 4
+#define APT_PKG_MINOR 5
 #define APT_PKG_RELEASE 0
 #define APT_PKG_RELEASE 0
     
     
 extern const char *pkgVersion;
 extern const char *pkgVersion;
 extern const char *pkgLibVersion;
 extern const char *pkgLibVersion;
-extern const char *pkgOS;
-extern const char *pkgCPU;
 
 
 bool pkgInitConfig(Configuration &Cnf);
 bool pkgInitConfig(Configuration &Cnf);
 bool pkgInitSystem(Configuration &Cnf,pkgSystem *&Sys);
 bool pkgInitSystem(Configuration &Cnf,pkgSystem *&Sys);

+ 2 - 2
apt-pkg/makefile

@@ -13,9 +13,9 @@ include ../buildlib/defaults.mak
 # methods/makefile - FIXME
 # methods/makefile - FIXME
 LIBRARY=apt-pkg
 LIBRARY=apt-pkg
 LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER)
 LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER)
-MAJOR=4.4
+MAJOR=4.5
 MINOR=0
 MINOR=0
-SLIBS=$(PTHREADLIB) $(INTLLIBS)
+SLIBS=$(PTHREADLIB) $(INTLLIBS) -lutil
 APT_DOMAIN:=libapt-pkg$(MAJOR)
 APT_DOMAIN:=libapt-pkg$(MAJOR)
 
 
 # Source code for the contributed non-core things
 # Source code for the contributed non-core things

+ 1 - 0
apt-pkg/pkgrecords.h

@@ -57,6 +57,7 @@ class pkgRecords::Parser
    virtual string FileName() {return string();};
    virtual string FileName() {return string();};
    virtual string MD5Hash() {return string();};
    virtual string MD5Hash() {return string();};
    virtual string SHA1Hash() {return string();};
    virtual string SHA1Hash() {return string();};
+   virtual string SHA256Hash() {return string();};
    virtual string SourcePkg() {return string();};
    virtual string SourcePkg() {return string();};
    virtual string SourceVer() {return string();};
    virtual string SourceVer() {return string();};
 
 

+ 2 - 2
apt-pkg/tagfile.h

@@ -30,8 +30,8 @@ class pkgTagSection
    const char *Stop;
    const char *Stop;
    
    
    // We have a limit of 256 tags per section.
    // We have a limit of 256 tags per section.
-   unsigned short Indexes[256];
-   unsigned short AlphaIndexes[0x100];
+   unsigned int Indexes[256];
+   unsigned int AlphaIndexes[0x100];
    
    
    unsigned int TagCount;
    unsigned int TagCount;
      
      

+ 2 - 5
buildlib/config.h.in

@@ -32,11 +32,8 @@
 /* If there is no socklen_t, define this for the netdb shim */
 /* If there is no socklen_t, define this for the netdb shim */
 #undef NEED_SOCKLEN_T_DEFINE
 #undef NEED_SOCKLEN_T_DEFINE
 
 
-/* Define the cpu name string */
-#undef COMMON_CPU
-
-/* Define the on name string */
-#undef COMMON_OS
+/* Define the arch name string */
+#undef COMMON_ARCH
 
 
 /* The version number string */
 /* The version number string */
 #undef VERSION
 #undef VERSION

+ 2 - 2
cmdline/apt-cache.cc

@@ -1711,8 +1711,8 @@ bool GenCaches(CommandLine &Cmd)
 /* */
 /* */
 bool ShowHelp(CommandLine &Cmd)
 bool ShowHelp(CommandLine &Cmd)
 {
 {
-   ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
-	    COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+   ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION,
+	    COMMON_ARCH,__DATE__,__TIME__);
    
    
    if (_config->FindB("version") == true)
    if (_config->FindB("version") == true)
      return true;
      return true;

+ 2 - 2
cmdline/apt-cdrom.cc

@@ -135,8 +135,8 @@ bool DoIdent(CommandLine &)
 /* */
 /* */
 int ShowHelp()
 int ShowHelp()
 {
 {
-   ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
-	    COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+   ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION,
+	    COMMON_ARCH,__DATE__,__TIME__);
    if (_config->FindB("version") == true)
    if (_config->FindB("version") == true)
       return 0;
       return 0;
    
    

+ 2 - 2
cmdline/apt-config.cc

@@ -67,8 +67,8 @@ bool DoDump(CommandLine &CmdL)
 /* */
 /* */
 int ShowHelp()
 int ShowHelp()
 {
 {
-   ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
-	    COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+   ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION,
+	    COMMON_ARCH,__DATE__,__TIME__);
    if (_config->FindB("version") == true)
    if (_config->FindB("version") == true)
       return 0;
       return 0;
    
    

+ 2 - 2
cmdline/apt-extracttemplates.cc

@@ -222,8 +222,8 @@ bool DebFile::ParseInfo()
 /* */
 /* */
 int ShowHelp(void)
 int ShowHelp(void)
 {
 {
-   	ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
-	    COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+   	ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION,
+	    COMMON_ARCH,__DATE__,__TIME__);
 
 
 	if (_config->FindB("version") == true) 
 	if (_config->FindB("version") == true) 
 		return 0;
 		return 0;

+ 5 - 5
cmdline/apt-get.cc

@@ -918,7 +918,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
       pkgAcquire::UriIterator I = Fetcher.UriBegin();
       pkgAcquire::UriIterator I = Fetcher.UriBegin();
       for (; I != Fetcher.UriEnd(); I++)
       for (; I != Fetcher.UriEnd(); I++)
 	 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
 	 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
-	       I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+	       I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
       return true;
       return true;
    }
    }
 
 
@@ -1359,7 +1359,7 @@ bool DoUpdate(CommandLine &CmdL)
       pkgAcquire::UriIterator I = Fetcher.UriBegin();
       pkgAcquire::UriIterator I = Fetcher.UriBegin();
       for (; I != Fetcher.UriEnd(); I++)
       for (; I != Fetcher.UriEnd(); I++)
 	 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
 	 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
-	       I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+	       I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
       return true;
       return true;
    }
    }
 
 
@@ -2241,7 +2241,7 @@ bool DoSource(CommandLine &CmdL)
       pkgAcquire::UriIterator I = Fetcher.UriBegin();
       pkgAcquire::UriIterator I = Fetcher.UriBegin();
       for (; I != Fetcher.UriEnd(); I++)
       for (; I != Fetcher.UriEnd(); I++)
 	 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
 	 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
-	       I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+	       I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
       return true;
       return true;
    }
    }
    
    
@@ -2612,8 +2612,8 @@ bool DoMoo(CommandLine &CmdL)
 /* */
 /* */
 bool ShowHelp(CommandLine &CmdL)
 bool ShowHelp(CommandLine &CmdL)
 {
 {
-   ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
-	    COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+   ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION,
+	    COMMON_ARCH,__DATE__,__TIME__);
 	    
 	    
    if (_config->FindB("version") == true)
    if (_config->FindB("version") == true)
    {
    {

+ 2 - 2
cmdline/apt-sortpkgs.cc

@@ -141,8 +141,8 @@ bool DoIt(string InFile)
 /* */
 /* */
 int ShowHelp()
 int ShowHelp()
 {
 {
-   ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
-	    COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+   ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION,
+	    COMMON_ARCH,__DATE__,__TIME__);
    if (_config->FindB("version") == true)
    if (_config->FindB("version") == true)
       return 0;
       return 0;
    
    

+ 1 - 1
cmdline/makefile

@@ -14,7 +14,7 @@ include $(PROGRAM_H)
 
 
 # The apt-get program
 # The apt-get program
 PROGRAM=apt-get
 PROGRAM=apt-get
-SLIBS = -lapt-pkg
+SLIBS = -lapt-pkg -lutil
 LIB_MAKES = apt-pkg/makefile
 LIB_MAKES = apt-pkg/makefile
 SOURCE = apt-get.cc acqprogress.cc
 SOURCE = apt-get.cc acqprogress.cc
 include $(PROGRAM_H)
 include $(PROGRAM_H)

+ 3 - 10
configure.in

@@ -18,7 +18,7 @@ AC_CONFIG_AUX_DIR(buildlib)
 AC_CONFIG_HEADER(include/config.h:buildlib/config.h.in include/apti18n.h:buildlib/apti18n.h.in)
 AC_CONFIG_HEADER(include/config.h:buildlib/config.h.in include/apti18n.h:buildlib/apti18n.h.in)
 
 
 dnl -- SET THIS TO THE RELEASE VERSION --
 dnl -- SET THIS TO THE RELEASE VERSION --
-AC_DEFINE_UNQUOTED(VERSION,"0.7.4ubuntu1")
+AC_DEFINE_UNQUOTED(VERSION,"0.7.6ubuntu1")
 PACKAGE="apt"
 PACKAGE="apt"
 AC_DEFINE_UNQUOTED(PACKAGE,"$PACKAGE")
 AC_DEFINE_UNQUOTED(PACKAGE,"$PACKAGE")
 AC_SUBST(PACKAGE)
 AC_SUBST(PACKAGE)
@@ -80,20 +80,13 @@ dnl Converts the ARCH to be something singular for this general CPU family
 dnl This is often the dpkg architecture string.
 dnl This is often the dpkg architecture string.
 dnl First check against the full canonical canoncial-system-type in $target
 dnl First check against the full canonical canoncial-system-type in $target
 dnl and if that fails, just look for the cpu
 dnl and if that fails, just look for the cpu
-AC_MSG_CHECKING(system architecture)
+AC_MSG_CHECKING(debian architecture)
 archset="`dpkg-architecture -qDEB_HOST_ARCH`"
 archset="`dpkg-architecture -qDEB_HOST_ARCH`"
 if test "x$archset" = "x"; then
 if test "x$archset" = "x"; then
    AC_MSG_ERROR([failed: use --host= or output from dpkg-architecture])
    AC_MSG_ERROR([failed: use --host= or output from dpkg-architecture])
 fi
 fi
 AC_MSG_RESULT($archset)
 AC_MSG_RESULT($archset)
-AC_DEFINE_UNQUOTED(COMMON_CPU,"$archset")
-
-dnl Get a common name for the host OS - this is primarily only for HURD and is
-dnl non fatal if it fails
-AC_MSG_CHECKING(system OS)
-osset="`dpkg-architecture -qDEB_HOST_ARCH_OS`"
-AC_MSG_RESULT($osset)
-AC_DEFINE_UNQUOTED(COMMON_OS,"$osset")
+AC_DEFINE_UNQUOTED(COMMON_ARCH,"$archset")
 
 
 dnl We use C99 types if at all possible
 dnl We use C99 types if at all possible
 AC_CACHE_CHECK([for C99 integer types],c9x_ints,[
 AC_CACHE_CHECK([for C99 integer types],c9x_ints,[

+ 2 - 0
debian/apt.dirs

@@ -4,8 +4,10 @@ usr/lib/dpkg/methods/apt
 etc/apt
 etc/apt
 etc/apt/apt.conf.d
 etc/apt/apt.conf.d
 etc/apt/sources.list.d
 etc/apt/sources.list.d
+etc/logrotate.d
 var/cache/apt/archives/partial
 var/cache/apt/archives/partial
 var/lib/apt/lists/partial
 var/lib/apt/lists/partial
 var/lib/apt/mirrors/partial
 var/lib/apt/mirrors/partial
 var/lib/apt/periodic
 var/lib/apt/periodic
+var/log/apt
 usr/share/bug/apt
 usr/share/bug/apt

+ 8 - 0
debian/apt.logrotate

@@ -0,0 +1,8 @@
+/var/log/apt/term.log {
+  rotate 6
+  monthly
+  compress
+  missingok
+  notifempty
+}
+

+ 72 - 3
debian/changelog

@@ -1,14 +1,53 @@
-apt (0.7.4ubuntu1) gutsy; urgency=low
+apt (0.7.6ubuntu1) gutsy; urgency=low
+
+  * apt-inst/contrib/extracttar.cc:
+    - fix fd leak for zero size files (thanks to Bill Broadley for
+      reporting this bug)
+  * apt-pkg/acquire-item.cc:
+    - remove zero size files on I-M-S hit
+  * methods/https.cc:
+    - only send LastModified if we actually have one
+    - send range request with if-range 
+    - delete failed downloads
+  * apt-pkg/deb/dpkgpm.{cc,h}:
+    - merged dpkg-log branch, this lets you specify a 
+      Dir::Log::Terminal file to log dpkg output to
+      (ABI break)
+  * merged apt--sha256 branch to fully support the new
+    sha256 checksums in the Packages and Release files
+    (ABI break)
+
+ -- Michael Vogt <michael.vogt@ubuntu.com>  Thu, 02 Aug 2007 11:55:54 +0200
+
+apt (0.7.6) unstable; urgency=low
+
+  * Applied patch from Aurelien Jarno <aurel32@debian.org> to fix wrong
+    directory downloading on non-linux architectures (closes: #435597)
+
+ -- Otavio Salvador <otavio@debian.org>  Wed, 01 Aug 2007 19:49:51 -0300
+
+apt (0.7.5) unstable; urgency=low
 
 
   [ Otavio Salvador ]
   [ Otavio Salvador ]
-  * Applied patch from Guillem Jover <guillem.jover@nokia.com> to use
+  * Applied patch from Guillem Jover <guillem@debian.org> to use
     dpkg-architecture to get the host architecture (closes: #407187)
     dpkg-architecture to get the host architecture (closes: #407187)
+  * Applied patch from Guillem Jover <guillem@debian.org> to add
+    support to add lzma support (closes: #408201)
 
 
   [ Michael Vogt ]
   [ Michael Vogt ]
   * apt-pkg/depcache.cc:
   * apt-pkg/depcache.cc:
     - support a list of sections for:
     - support a list of sections for:
       APT::Install-Recommends-Sections
       APT::Install-Recommends-Sections
       APT::Never-MarkAuto-Sections
       APT::Never-MarkAuto-Sections
+  * methods/makefile:
+    - install lzma symlink method (for full lzma support)
+  * debian/control:
+    - suggest "lzma"
+
+ -- Otavio Salvador <otavio@ossystems.com.br>  Wed, 25 Jul 2007 20:16:46 -0300
+
+apt (0.7.4ubuntu1) gutsy; urgency=low
+
   * debian/apt.conf.ubuntu, apt.conf.autoremove:
   * debian/apt.conf.ubuntu, apt.conf.autoremove:
     - Change metapackages to {restricted,universe,multiverse}/metapackages 
     - Change metapackages to {restricted,universe,multiverse}/metapackages 
       in Install-Recommends-Sections and Never-MarkAuto-Sections
       in Install-Recommends-Sections and Never-MarkAuto-Sections
@@ -34,6 +73,13 @@ apt (0.7.4) unstable; urgency=low
       - type conversion;
       - type conversion;
       - unused variable;
       - unused variable;
       - changed SetupProxy() method to void;
       - changed SetupProxy() method to void;
+  * Simplified HttpMethod::Fetch on http.cc removing Tail variable;
+  * Fix pipeline handling on http.cc (closes: #413324)
+  * Fix building to properly support binNMUs. Thanks to Daniel Schepler
+    <schepler@math.unipd.it> by the patch (closes: #359634)
+  * Fix example for Install-{Recommends,Suggests} options on
+    configure-index example file. Thanks to Peter Eisentraut
+    <peter_e@gmx.net> by the patch (closes: #432223)
 
 
   [ Christian Perrier ]
   [ Christian Perrier ]
   * Basque translation update. Closes: ##423766
   * Basque translation update. Closes: ##423766
@@ -45,6 +91,29 @@ apt (0.7.4) unstable; urgency=low
 
 
  -- Otavio Salvador <otavio@debian.org>  Tue, 24 Jul 2007 09:55:50 -0300
  -- Otavio Salvador <otavio@debian.org>  Tue, 24 Jul 2007 09:55:50 -0300
 
 
+apt (0.7.3) unstable; urgency=low
+
+  * fixed compile errors with g++ 4.3 (thanks to 
+    Daniel Burrows, closes: #429378)
+  * fixes in the auto-mark code (thanks to Daniel
+    Burrows)
+  * fix FTFBFS by changing build-depends to
+    libcurl4-gnutls-dev (closes: #428363)
+  * cmdline/apt-get.cc:
+    - fix InstallTask code when a pkgRecord ends 
+      with a single '\n' (thanks to Soren Hansen for reporting)
+  * merged from Christian Perrier:
+        * vi.po: completed to 532t, again. Closes: #429899
+        * gl.po: completed to 532t. Closes: #429506
+        * vi.po: completed to 532t. Closes: #428672
+        * Update all PO and the POT. Gives 514t14f4u for formerly
+          complete translations
+        * fr.po: completed to 532t
+        * ku.po, uk.po, LINGUAS: reintegrate those translations
+          which disappeared from the BZR repositories
+
+ -- Michael Vogt <mvo@debian.org>  Sun, 01 Jul 2007 12:31:29 +0200
+  
 apt (0.7.2ubuntu7) gutsy; urgency=low
 apt (0.7.2ubuntu7) gutsy; urgency=low
 
 
   * fix build-dependencies 
   * fix build-dependencies 
@@ -226,7 +295,7 @@ apt (0.7.1) experimental; urgency=low
   * apt-pkg/policy.cc:
   * apt-pkg/policy.cc:
     - allow multiple packages (thanks to David Foerster)
     - allow multiple packages (thanks to David Foerster)
 
 
- -- Michael Vogt <michael.vogt@ubuntu.com>  Tue, 17 Apr 2007 15:53:37 +0200
+ -- Michael Vogt <mvo@debian.org>  Wed,  2 May 2007 13:43:44 +0200
 
 
 apt (0.6.46.4ubuntu10) feisty; urgency=low
 apt (0.6.46.4ubuntu10) feisty; urgency=low
 
 

+ 1 - 1
debian/control

@@ -16,7 +16,7 @@ Priority: important
 Replaces: libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7)
 Replaces: libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7)
 Provides: ${libapt-pkg:provides}
 Provides: ${libapt-pkg:provides}
 Recommends: ubuntu-keyring
 Recommends: ubuntu-keyring
-Suggests: aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2, gnupg
+Suggests: aptitude | synaptic | gnome-apt | wajig, dpkg-dev, apt-doc, bzip2, gnupg, lzma
 Section: admin
 Section: admin
 Description: Advanced front-end for dpkg
 Description: Advanced front-end for dpkg
  This is Debian's next generation front-end for the dpkg package manager.
  This is Debian's next generation front-end for the dpkg package manager.

+ 1 - 0
debian/rules

@@ -209,6 +209,7 @@ apt: build debian/shlibs.local
 	cp -r $(BLD)/locale debian/$@/usr/share/
 	cp -r $(BLD)/locale debian/$@/usr/share/
 
 
 	cp debian/bugscript debian/$@/usr/share/bug/apt/script
 	cp debian/bugscript debian/$@/usr/share/bug/apt/script
+	cp debian/apt.logrotate debian/$@/etc/logrotate.d/apt
 
 
 	cp share/ubuntu-archive.gpg debian/$@/usr/share/$@
 	cp share/ubuntu-archive.gpg debian/$@/usr/share/$@
 	cp debian/apt.conf.autoremove debian/$@/etc/apt/apt.conf.d/01autoremove
 	cp debian/apt.conf.autoremove debian/$@/etc/apt/apt.conf.d/01autoremove

+ 5 - 0
doc/examples/configure-index

@@ -245,6 +245,11 @@ Dir "/"
      apt-get "/usr/bin/apt-get";
      apt-get "/usr/bin/apt-get";
      apt-cache "/usr/bin/apt-cache";
      apt-cache "/usr/bin/apt-cache";
   };
   };
+
+  // Location of the logfile
+  Log "var/log/apt" {
+	Terminal "term.log";
+  };
 };
 };
 
 
 // Things that effect the APT dselect method
 // Things that effect the APT dselect method

+ 2 - 2
ftparchive/apt-ftparchive.cc

@@ -544,8 +544,8 @@ void LoadBinDir(vector<PackageMap> &PkgList,Configuration &Setup)
 /* */
 /* */
 bool ShowHelp(CommandLine &CmdL)
 bool ShowHelp(CommandLine &CmdL)
 {
 {
-   ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
-	    COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
+   ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION,
+	    COMMON_ARCH,__DATE__,__TIME__);
    if (_config->FindB("version") == true)
    if (_config->FindB("version") == true)
       return true;
       return true;
 
 

+ 20 - 8
methods/https.cc

@@ -107,6 +107,7 @@ bool HttpsMethod::Fetch(FetchItem *Itm)
    struct stat SBuf;
    struct stat SBuf;
    struct curl_slist *headers=NULL;  
    struct curl_slist *headers=NULL;  
    char curl_errorstr[CURL_ERROR_SIZE];
    char curl_errorstr[CURL_ERROR_SIZE];
+   long curl_responsecode;
 
 
    // TODO:
    // TODO:
    //       - http::Timeout
    //       - http::Timeout
@@ -159,8 +160,11 @@ bool HttpsMethod::Fetch(FetchItem *Itm)
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
 
 
    // set time values
    // set time values
-   curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
-   curl_easy_setopt(curl, CURLOPT_TIMEVALUE, Itm->LastModified);
+   if(Itm->LastModified > 0)
+   {
+      curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
+      curl_easy_setopt(curl, CURLOPT_TIMEVALUE, Itm->LastModified);
+   }
 
 
    // speed limit
    // speed limit
    int dlLimit = _config->FindI("Acquire::http::Dl-Limit",0)*1024;
    int dlLimit = _config->FindI("Acquire::http::Dl-Limit",0)*1024;
@@ -178,8 +182,14 @@ bool HttpsMethod::Fetch(FetchItem *Itm)
    curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errorstr);
    curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errorstr);
 
 
    // In this case we send an if-range query with a range header
    // In this case we send an if-range query with a range header
-  if (stat(Itm->DestFile.c_str(),&SBuf) >= 0 && SBuf.st_size > 0)
-     curl_easy_setopt(curl, CURLOPT_RESUME_FROM, (long)SBuf.st_size);
+   if (stat(Itm->DestFile.c_str(),&SBuf) >= 0 && SBuf.st_size > 0)
+   {
+      char Buf[1000];
+      sprintf(Buf,"Range: bytes=%li-\r\nIf-Range: %s\r\n",
+	      (long)SBuf.st_size - 1,
+	      TimeRFC1123(SBuf.st_mtime).c_str());
+      headers = curl_slist_append(headers, Buf);
+   }
 
 
    // go for it - if the file exists, append on it
    // go for it - if the file exists, append on it
    File = new FileFd(Itm->DestFile, FileFd::WriteAny);
    File = new FileFd(Itm->DestFile, FileFd::WriteAny);
@@ -190,14 +200,17 @@ bool HttpsMethod::Fetch(FetchItem *Itm)
 
 
    // get it!
    // get it!
    CURLcode success = curl_easy_perform(curl);
    CURLcode success = curl_easy_perform(curl);
-
+   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &curl_responsecode);
 
 
    // cleanup
    // cleanup
-   if(success != 0) {
+   if(success != 0) 
+   {
+      unlink(File->Name().c_str());
       _error->Error(curl_errorstr);
       _error->Error(curl_errorstr);
       Fail();
       Fail();
       return true;
       return true;
    }
    }
+   File->Close();
 
 
    if (Res.Size == 0)
    if (Res.Size == 0)
       Res.Size = File->Size();
       Res.Size = File->Size();
@@ -210,7 +223,7 @@ bool HttpsMethod::Fetch(FetchItem *Itm)
       Res.Filename = File->Name();
       Res.Filename = File->Name();
       Res.LastModified = Buf.st_mtime;
       Res.LastModified = Buf.st_mtime;
       Res.IMSHit = false;
       Res.IMSHit = false;
-      if (Itm->LastModified != 0 && Buf.st_mtime >= Itm->LastModified)
+      if (curl_responsecode == 304)
       {
       {
 	 Res.IMSHit = true;
 	 Res.IMSHit = true;
 	 Res.LastModified = Itm->LastModified;
 	 Res.LastModified = Itm->LastModified;
@@ -227,7 +240,6 @@ bool HttpsMethod::Fetch(FetchItem *Itm)
    URIDone(Res);
    URIDone(Res);
 
 
    // cleanup
    // cleanup
-   File->Close();
    Res.Size = 0;
    Res.Size = 0;
    delete File;
    delete File;
    curl_slist_free_all(headers);
    curl_slist_free_all(headers);

+ 9 - 4
methods/makefile

@@ -7,7 +7,7 @@ include ../buildlib/defaults.mak
 BIN := $(BIN)/methods
 BIN := $(BIN)/methods
 
 
 # FIXME..
 # FIXME..
-LIB_APT_PKG_MAJOR = 4.4
+LIB_APT_PKG_MAJOR = 4.5
 APT_DOMAIN := libapt-pkg$(LIB_APT_PKG_MAJOR)
 APT_DOMAIN := libapt-pkg$(LIB_APT_PKG_MAJOR)
 
 
 # The file method
 # The file method
@@ -94,9 +94,9 @@ LIB_MAKES = apt-pkg/makefile
 SOURCE = mirror.cc http.cc rfc2553emu.cc connect.cc
 SOURCE = mirror.cc http.cc rfc2553emu.cc connect.cc
 include $(PROGRAM_H)
 include $(PROGRAM_H)
 
 
-# SSH and vzip2 method symlink
-binary: $(BIN)/ssh $(BIN)/bzip2
-veryclean: clean-$(BIN)/ssh clean-$(BIN)/bzip2
+# SSH and bzip2,lzma method symlinks
+binary: $(BIN)/ssh $(BIN)/bzip2 $(BIN)/lzma
+veryclean: clean-$(BIN)/ssh clean-$(BIN)/bzip2 clean-$(BIN)/lzma
 $(BIN)/ssh:
 $(BIN)/ssh:
 	echo "Installing ssh method link"
 	echo "Installing ssh method link"
 	ln -fs rsh $(BIN)/ssh
 	ln -fs rsh $(BIN)/ssh
@@ -106,5 +106,10 @@ clean-$(BIN)/ssh:
 $(BIN)/bzip2:
 $(BIN)/bzip2:
 	echo "Installing bzip2 method link"
 	echo "Installing bzip2 method link"
 	ln -fs gzip $(BIN)/bzip2
 	ln -fs gzip $(BIN)/bzip2
+$(BIN)/lzma:
+	echo "Installing lzma method link"
+	ln -fs gzip $(BIN)/lzma
 clean-$(BIN)/bzip2:
 clean-$(BIN)/bzip2:
 	-rm $(BIN)/bzip2
 	-rm $(BIN)/bzip2
+clean-$(BIN)/lzma:
+	-rm $(BIN)/lzma