--- /dev/null
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: hashes.cc,v 1.1 2001/03/06 07:15:29 jgg Exp $
+/* ######################################################################
+
+   Hashes - Simple wrapper around the hash functions
+   
+   This is just used to make building the methods simpler, this is the
+   only interface required..
+   
+   ##################################################################### */
+                                                                       /*}}}*/
+// Include Files                                                       /*{{{*/
+#ifdef __GNUG__
+#pragma implementation "apt-pkg/hashes.h"
+#endif
+
+#include <apt-pkg/hashes.h>
+    
+#include <unistd.h>    
+#include <system.h>    
+                                                                       /*}}}*/
+
+// Hashes::AddFD - Add the contents of the FD                          /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool Hashes::AddFD(int Fd,unsigned long Size)
+{
+   unsigned char Buf[64*64];
+   int Res = 0;
+   while (Size != 0)
+   {
+      Res = read(Fd,Buf,MIN(Size,sizeof(Buf)));
+      if (Res < 0 || (unsigned)Res != MIN(Size,sizeof(Buf)))
+        return false;
+      Size -= Res;
+      MD5.Add(Buf,Res);
+      SHA1.Add(Buf,Res);
+   }
+   return true;
+}
+                                                                       /*}}}*/
+
 
--- /dev/null
+// -*- mode: cpp; mode: fold -*-
+// Description                                                         /*{{{*/
+// $Id: hashes.h,v 1.1 2001/03/06 07:15:29 jgg Exp $
+/* ######################################################################
+
+   Hashes - Simple wrapper around the hash functions
+   
+   This is just used to make building the methods simpler, this is the
+   only interface required..
+   
+   ##################################################################### */
+                                                                       /*}}}*/
+#ifndef APTPKG_HASHES_H
+#define APTPKG_HASHES_H
+
+#ifdef __GNUG__
+#pragma interface "apt-pkg/hashesh.h"
+#endif 
+
+#include <apt-pkg/md5.h>
+#include <apt-pkg/sha1.h>
+
+class Hashes
+{
+   public:
+
+   MD5Summation MD5;
+   SHA1Summation SHA1;
+   
+   inline bool Add(const unsigned char *Data,unsigned long Size)
+   {
+      MD5.Add(Data,Size);
+      SHA1.Add(Data,Size);
+   };
+   inline bool Add(const char *Data) {return Add((unsigned char *)Data,strlen(Data));};
+   bool AddFD(int Fd,unsigned long Size);
+   inline bool Add(const unsigned char *Beg,const unsigned char *End) 
+                  {return Add(Beg,End-Beg);};
+};
+
+#endif
 
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: init.h,v 1.6 2001/03/03 23:02:39 tausq Exp $
+// $Id: init.h,v 1.7 2001/03/06 07:15:29 jgg Exp $
 /* ######################################################################
 
    Init - Initialize the package library
 // See the makefile
 #define APT_PKG_MAJOR 3
 #define APT_PKG_MINOR 1
-#define APT_PKG_RELEASE 2
-
+#define APT_PKG_RELEASE 3
+    
 extern const char *pkgVersion;
 extern const char *pkgLibVersion;
 extern const char *pkgOS;
 
 LIBRARY=apt-pkg
 LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER)
 MAJOR=3.1
-MINOR=2
+MINOR=3
 SLIBS=$(PTHREADLIB)
 
 # Source code for the contributed non-core things
 SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \
          contrib/configuration.cc contrib/progress.cc contrib/cmndline.cc \
-        contrib/md5.cc contrib/cdromutl.cc contrib/crc-16.cc \
-        contrib/fileutl.cc contrib/sha1.cc
+        contrib/md5.cc contrib/sha1.cc contrib/hashes.cc \
+        contrib/cdromutl.cc contrib/crc-16.cc \
+        contrib/fileutl.cc 
 HEADERS = mmap.h error.h configuration.h fileutl.h  cmndline.h \
-         md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h
+         md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h hashes.h
 
 # Source code for the core main library
 SOURCE+= pkgcache.cc version.cc depcache.cc \
 
 
   * JoeyH's dpkg::preconfig not working. Closes: #88675
   * Fixed apt override disparity
+  * Alfredo's SHA-1 and related patches
   
  -- Jason Gunthorpe <jgg@debian.org>  Sun,  4 Mar 2001 15:39:43 -0700
 
 
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: ftp.cc,v 1.23 2001/02/23 07:19:49 jgg Exp $
+// $Id: ftp.cc,v 1.24 2001/03/06 07:15:29 jgg Exp $
 /* ######################################################################
 
-   HTTP Aquire Method - This is the FTP aquire method for APT.
+   FTP Aquire Method - This is the FTP aquire method for APT.
 
    This is a very simple implementation that does not try to optimize
    at all. Commands are sent syncronously with the FTP server (as the
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/acquire-method.h>
 #include <apt-pkg/error.h>
-#include <apt-pkg/md5.h>
+#include <apt-pkg/hashes.h>
 
 #include <sys/stat.h>
 #include <sys/time.h>
 /* This opens a data connection, sends REST and RETR and then
    transfers the file over. */
 bool FTPConn::Get(const char *Path,FileFd &To,unsigned long Resume,
-                 MD5Summation &MD5,bool &Missing)
+                 Hashes &Hash,bool &Missing)
 {
    Missing = false;
    if (CreateDataFd() == false)
    
    if (Resume != 0)
    {
-      if (MD5.AddFD(To.Fd(),Resume) == false)
+      if (Hash.AddFD(To.Fd(),Resume) == false)
       {
         _error->Errno("read","Problem hashing file");
         return false;
         break;
       }
    
-      MD5.Add(Buffer,Res);
+      Hash.Add(Buffer,Res);
       if (To.Write(Buffer,Res) == false)
       {
         Close();
    }
    
    // Open the file
-   MD5Summation MD5;
+   Hashes Hash;
    {
       FileFd Fd(Itm->DestFile,FileFd::WriteAny);
       if (_error->PendingError() == true)
       FailFd = Fd.Fd();
       
       bool Missing;
-      if (Server->Get(File,Fd,Res.ResumePoint,MD5,Missing) == false)
+      if (Server->Get(File,Fd,Res.ResumePoint,Hash,Missing) == false)
       {
         Fd.Close();
         
    }
    
    Res.LastModified = FailTime;
-   Res.MD5Sum = MD5.Result();
+   Res.MD5Sum = Hash.MD5.Result();
    
    // Timestamp
    struct utimbuf UBuf;
 
 // -*- mode: cpp; mode: fold -*-
-// Description                                                         /*{{{*/// $Id: ftp.h,v 1.3 2001/02/20 07:03:18 jgg Exp $
-// $Id: ftp.h,v 1.3 2001/02/20 07:03:18 jgg Exp $
+// Description                                                         /*{{{*/// $Id: ftp.h,v 1.4 2001/03/06 07:15:29 jgg Exp $
+// $Id: ftp.h,v 1.4 2001/03/06 07:15:29 jgg Exp $
 /* ######################################################################
 
    FTP Aquire Method - This is the FTP aquire method for APT.
    bool Size(const char *Path,unsigned long &Size);
    bool ModTime(const char *Path, time_t &Time);
    bool Get(const char *Path,FileFd &To,unsigned long Resume,
-           MD5Summation &MD5,bool &Missing);
+           Hashes &MD5,bool &Missing);
    
    FTPConn(URI Srv);
    ~FTPConn();
 
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: gzip.cc,v 1.11 2001/03/06 03:11:22 jgg Exp $
+// $Id: gzip.cc,v 1.12 2001/03/06 07:15:29 jgg Exp $
 /* ######################################################################
 
    GZip method - Take a file URI in and decompress it into the target 
 #include <apt-pkg/error.h>
 #include <apt-pkg/acquire-method.h>
 #include <apt-pkg/strutl.h>
+#include <apt-pkg/hashes.h>
 
 #include <sys/stat.h>
 #include <unistd.h>
 #include <utime.h>
 #include <stdio.h>
+#include <errno.h>
                                                                        /*}}}*/
 
 class GzipMethod : public pkgAcqMethod
    GzipMethod() : pkgAcqMethod("1.1",SingleInstance | SendConfig) {};
 };
 
+
 // GzipMethod::Fetch - Decompress the passed URI                       /*{{{*/
 // ---------------------------------------------------------------------
 /* */
 {
    URI Get = Itm->Uri;
    string Path = Get.Host + Get.Path; // To account for relative paths
-   string GzipPath = _config->Find("Dir::bin::gzip","gzip");
    
    FetchResult Res;
    Res.Filename = Itm->DestFile;
    URIStart(Res);
    
-   // Open the source and destintation files
+   // Open the source and destination files
    FileFd From(Path,FileFd::ReadOnly);
-   FileFd To(Itm->DestFile,FileFd::WriteEmpty);   
-   To.EraseOnFailure();
-   if (_error->PendingError() == true)
-      return false;
-   
+
+   int GzOut[2];   
+   if (pipe(GzOut) < 0)
+      return _error->Errno("pipe","Couldn't open pipe for gzip");
+
    // Fork gzip
-   int Process = fork();
-   if (Process < 0)
-      return _error->Errno("fork",string("Couldn't fork "+GzipPath).c_str());
-   
-   // The child
+   int Process = ExecFork();
    if (Process == 0)
    {
+      close(GzOut[0]);
       dup2(From.Fd(),STDIN_FILENO);
-      dup2(To.Fd(),STDOUT_FILENO);
+      dup2(GzOut[1],STDOUT_FILENO);
       From.Close();
-      To.Close();
+      close(GzOut[1]);
       SetCloseExec(STDIN_FILENO,false);
       SetCloseExec(STDOUT_FILENO,false);
       
       const char *Args[3];
-      Args[0] = GzipPath.c_str();
+      Args[0] = _config->Find("Dir::bin::gzip","gzip").c_str();
       Args[1] = "-d";
       Args[2] = 0;
       execvp(Args[0],(char **)Args);
-      exit(100);
+      _exit(100);
    }
    From.Close();
+   close(GzOut[1]);
+   
+   FileFd FromGz(GzOut[0]);  // For autoclose   
+   FileFd To(Itm->DestFile,FileFd::WriteEmpty);   
+   To.EraseOnFailure();
+   if (_error->PendingError() == true)
+      return false;
+   
+   // Read data from gzip, generate checksums and write
+   Hashes Hash;
+   bool Failed = false;
+   while (1) 
+   {
+      unsigned char Buffer[4*1024];
+      unsigned long Count;
+      
+      Count = read(GzOut[0],Buffer,sizeof(Buffer));
+      if (Count < 0 && errno == EINTR)
+        continue;
+      
+      if (Count < 0)
+      {
+        _error->Errno("read", "Read error from gzip process");
+        Failed = true;
+        break;
+      }
+      
+      if (Count == 0)
+        break;
+      
+      Hash.Add(Buffer,Count);
+      To.Write(Buffer,Count);
+   }
    
    // Wait for gzip to finish
-   if (ExecWait(Process,GzipPath.c_str(),false) == false)
+   if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false)
    {
       To.OpFail();
       return false;
        
    To.Close();
    
+   if (Failed == true)
+      return false;
+   
    // Transfer the modification times
    struct stat Buf;
    if (stat(Path.c_str(),&Buf) != 0)
    // Return a Done response
    Res.LastModified = Buf.st_mtime;
    Res.Size = Buf.st_size;
+   Res.MD5Sum = Hash.MD5.Result();
+
    URIDone(Res);
    
    return true;
 
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: http.cc,v 1.49 2001/02/23 07:19:49 jgg Exp $
+// $Id: http.cc,v 1.50 2001/03/06 07:15:29 jgg Exp $
 /* ######################################################################
 
    HTTP Aquire Method - This is the HTTP aquire method for APT.
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/acquire-method.h>
 #include <apt-pkg/error.h>
-#include <apt-pkg/md5.h>
+#include <apt-pkg/hashes.h>
 
 #include <sys/stat.h>
 #include <sys/time.h>
 // CircleBuf::CircleBuf - Circular input buffer                                /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-CircleBuf::CircleBuf(unsigned long Size) : Size(Size), MD5(0)
+CircleBuf::CircleBuf(unsigned long Size) : Size(Size), Hash(0)
 {
    Buf = new unsigned char[Size];
    Reset();
    StrPos = 0;
    MaxGet = (unsigned int)-1;
    OutQueue = string();
-   if (MD5 != 0)
+   if (Hash != 0)
    {
-      delete MD5;
-      MD5 = new MD5Summation;
+      delete Hash;
+      Hash = new Hashes;
    }   
 };
                                                                        /*}}}*/
         return false;
       }
       
-      if (MD5 != 0)
-        MD5->Add(Buf + (OutP%Size),Res);
+      if (Hash != 0)
+        Hash->Add(Buf + (OutP%Size),Res);
       
       OutP += Res;
    }
    // Set the start point
    lseek(File->Fd(),0,SEEK_END);
 
-   delete Srv->In.MD5;
-   Srv->In.MD5 = new MD5Summation;
+   delete Srv->In.Hash;
+   Srv->In.Hash = new Hashes;
    
-   // Fill the MD5 Hash if the file is non-empty (resume)
+   // Fill the Hash if the file is non-empty (resume)
    if (Srv->StartPos > 0)
    {
       lseek(File->Fd(),0,SEEK_SET);
-      if (Srv->In.MD5->AddFD(File->Fd(),Srv->StartPos) == false)
+      if (Srv->In.Hash->AddFD(File->Fd(),Srv->StartPos) == false)
       {
         _error->Errno("read","Problem hashing file");
         return 5;
            // Send status to APT
            if (Result == true)
            {
-              Res.MD5Sum = Server->In.MD5->Result();          
+              Res.MD5Sum = Server->In.Hash->MD5.Result();             
               URIDone(Res);
            }
            else
 
 // -*- mode: cpp; mode: fold -*-
-// Description                                                         /*{{{*/// $Id: http.h,v 1.9 2001/02/20 07:03:18 jgg Exp $
-// $Id: http.h,v 1.9 2001/02/20 07:03:18 jgg Exp $
+// Description                                                         /*{{{*/// $Id: http.h,v 1.10 2001/03/06 07:15:29 jgg Exp $
+// $Id: http.h,v 1.10 2001/03/06 07:15:29 jgg Exp $
 /* ######################################################################
 
    HTTP Aquire Method - This is the HTTP aquire method for APT.
    
    public:
    
-   MD5Summation *MD5;
+   Hashes *Hash;
    
    // Read data in
    bool Read(int Fd);
 
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: rsh.cc,v 1.2 2001/02/20 07:03:18 jgg Exp $
+// $Id: rsh.cc,v 1.3 2001/03/06 07:15:29 jgg Exp $
 /* ######################################################################
 
    RSH method - Transfer files via rsh compatible program
 // ---------------------------------------------------------------------
 /* */
 bool RSHConn::Get(const char *Path,FileFd &To,unsigned long Resume,
-                  MD5Summation &MD5,bool &Missing, unsigned long Size)
+                  Hashes &Hash,bool &Missing, unsigned long Size)
 {
    Missing = false;
 
       return false;
 
    if (Resume != 0) {
-      if (MD5.AddFD(To.Fd(),Resume) == false) {
+      if (Hash.AddFD(To.Fd(),Resume) == false) {
         _error->Errno("read","Problem hashing file");
         return false;
       }
       }
       MyLen += Res;
 
-      MD5.Add(Buffer,Res);
+      Hash.Add(Buffer,Res);
       if (To.Write(Buffer,Res) == false)
       {
          Close();
    }
 
    // Open the file
-   MD5Summation MD5;
+   Hashes Hash;
    {
       FileFd Fd(Itm->DestFile,FileFd::WriteAny);
       if (_error->PendingError() == true)
       FailFd = Fd.Fd();
 
       bool Missing;
-      if (Server->Get(File,Fd,Res.ResumePoint,MD5,Missing,Res.Size) == false)
+      if (Server->Get(File,Fd,Res.ResumePoint,Hash,Missing,Res.Size) == false)
       {
         Fd.Close();
 
    }
 
    Res.LastModified = FailTime;
-   Res.MD5Sum = MD5.Result();
+   Res.MD5Sum = Hash.MD5.Result();
 
    // Timestamp
    struct utimbuf UBuf;
 
 // -*- mode: cpp; mode: fold -*-
-// Description                                                         /*{{{*/// $Id: rsh.h,v 1.2 2001/02/20 07:03:18 jgg Exp $
-// $Id: rsh.h,v 1.2 2001/02/20 07:03:18 jgg Exp $
+// Description                                                         /*{{{*/// $Id: rsh.h,v 1.3 2001/03/06 07:15:29 jgg Exp $
+// $Id: rsh.h,v 1.3 2001/03/06 07:15:29 jgg Exp $
 /* ######################################################################
 
    RSH method - Transfer files via rsh compatible program
 
 #include <string>
 #include <apt-pkg/strutl.h>
-#include <apt-pkg/md5.h>
+#include <apt-pkg/hashes.h>
 #include <apt-pkg/acquire-method.h>
 #include <apt-pkg/fileutl.h>
 
    bool Size(const char *Path,unsigned long &Size);
    bool ModTime(const char *Path, time_t &Time);
    bool Get(const char *Path,FileFd &To,unsigned long Resume,
-            MD5Summation &MD5,bool &Missing, unsigned long Size);
+            Hashes &Hash,bool &Missing, unsigned long Size);
 
    RSHConn(URI Srv);
    ~RSHConn();