Sfoglia il codice sorgente

merged from lp:~donkult/apt/experimental

Michael Vogt 14 anni fa
parent
commit
27da8141d2
72 ha cambiato i file con 1117 aggiunte e 524 eliminazioni
  1. 3 0
      apt-inst/contrib/arfile.h
  2. 6 0
      apt-inst/contrib/extracttar.h
  3. 4 0
      apt-inst/database.h
  4. 4 0
      apt-inst/deb/debfile.h
  5. 8 0
      apt-pkg/acquire-item.h
  6. 5 0
      apt-pkg/acquire-method.h
  7. 5 0
      apt-pkg/acquire.h
  8. 5 0
      apt-pkg/algorithms.h
  9. 6 0
      apt-pkg/cachefile.h
  10. 4 0
      apt-pkg/cacheset.h
  11. 85 73
      apt-pkg/cdrom.cc
  12. 5 0
      apt-pkg/cdrom.h
  13. 4 0
      apt-pkg/contrib/cdromutl.h
  14. 4 0
      apt-pkg/contrib/cmndline.h
  15. 4 0
      apt-pkg/contrib/configuration.h
  16. 432 74
      apt-pkg/contrib/fileutl.cc
  17. 59 12
      apt-pkg/contrib/fileutl.h
  18. 6 0
      apt-pkg/contrib/hashes.h
  19. 5 0
      apt-pkg/contrib/hashsum_template.h
  20. 5 0
      apt-pkg/contrib/md5.h
  21. 20 2
      apt-pkg/contrib/mmap.cc
  22. 5 0
      apt-pkg/contrib/mmap.h
  23. 4 0
      apt-pkg/contrib/netrc.h
  24. 4 0
      apt-pkg/contrib/progress.h
  25. 5 0
      apt-pkg/contrib/sha1.h
  26. 6 0
      apt-pkg/contrib/strutl.h
  27. 14 18
      apt-pkg/deb/debindexfile.cc
  28. 1 0
      apt-pkg/deb/deblistparser.cc
  29. 4 0
      apt-pkg/deb/deblistparser.h
  30. 4 0
      apt-pkg/deb/debmetaindex.h
  31. 1 1
      apt-pkg/deb/debrecords.cc
  32. 4 0
      apt-pkg/deb/debrecords.h
  33. 1 1
      apt-pkg/deb/debsrcrecords.h
  34. 5 0
      apt-pkg/deb/dpkgpm.h
  35. 5 0
      apt-pkg/depcache.h
  36. 5 0
      apt-pkg/edsp.h
  37. 4 7
      apt-pkg/edsp/edspindexfile.cc
  38. 4 0
      apt-pkg/edsp/edspindexfile.h
  39. 6 0
      apt-pkg/edsp/edsplistparser.h
  40. 59 116
      apt-pkg/indexcopy.cc
  41. 5 0
      apt-pkg/indexcopy.h
  42. 4 0
      apt-pkg/indexfile.h
  43. 4 0
      apt-pkg/indexrecords.h
  44. 5 0
      apt-pkg/init.h
  45. 7 0
      apt-pkg/metaindex.h
  46. 5 0
      apt-pkg/packagemanager.h
  47. 4 1
      apt-pkg/pkgcache.h
  48. 9 7
      apt-pkg/pkgcachegen.cc
  49. 4 0
      apt-pkg/pkgsystem.h
  50. 4 0
      apt-pkg/policy.h
  51. 15 13
      apt-pkg/sourcelist.h
  52. 4 4
      apt-pkg/srcrecords.cc
  53. 5 0
      apt-pkg/srcrecords.h
  54. 4 0
      apt-pkg/tagfile.h
  55. 4 0
      apt-pkg/vendor.h
  56. 7 0
      apt-pkg/vendorlist.h
  57. 4 0
      apt-pkg/version.h
  58. 4 0
      apt-pkg/versionmatch.h
  59. 2 0
      buildlib/config.h.in
  60. 1 1
      cmdline/apt-cache.cc
  61. 16 0
      cmdline/apt-config.cc
  62. 6 4
      cmdline/apt-extracttemplates.h
  63. 14 12
      debian/changelog
  64. 13 127
      ftparchive/multicompress.cc
  65. 1 5
      ftparchive/multicompress.h
  66. 8 15
      ftparchive/writer.cc
  67. 1 1
      methods/gzip.cc
  68. 15 29
      methods/rred.cc
  69. 1 1
      test/integration/framework
  70. 86 0
      test/libapt/cdromfindpackages_test.cc
  71. 6 0
      test/libapt/makefile
  72. 29 0
      test/libapt/run-tests

+ 3 - 0
apt-inst/contrib/arfile.h

@@ -17,6 +17,9 @@
 
 
 
 
 #include <string>
 #include <string>
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/fileutl.h>
+#endif
 
 
 class FileFd;
 class FileFd;
 
 

+ 6 - 0
apt-inst/contrib/extracttar.h

@@ -18,6 +18,12 @@
 
 
 #include <string>
 #include <string>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/dirstream.h>
+#include <algorithm>
+using std::min;
+#endif
+
 class pkgDirStream;
 class pkgDirStream;
 
 
 class ExtractTar
 class ExtractTar

+ 4 - 0
apt-inst/database.h

@@ -25,6 +25,10 @@
 
 
 #include <string>
 #include <string>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/filelist.h>
+#endif
+
 class pkgFLCache;
 class pkgFLCache;
 class OpProgress;
 class OpProgress;
 
 

+ 4 - 0
apt-inst/deb/debfile.h

@@ -29,6 +29,10 @@
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/database.h>
+#endif
+
 class FileFd;
 class FileFd;
 class pkgDataBase;
 class pkgDataBase;
 
 

+ 8 - 0
apt-pkg/acquire-item.h

@@ -25,6 +25,14 @@
 #include <apt-pkg/weakptr.h>
 #include <apt-pkg/weakptr.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/indexfile.h>
+#include <apt-pkg/vendor.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/indexrecords.h>
+#endif
+
 /** \addtogroup acquire
 /** \addtogroup acquire
  *  @{
  *  @{
  *
  *

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

@@ -25,6 +25,11 @@
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/strutl.h>
+#endif
+
 class Hashes;
 class Hashes;
 class pkgAcqMethod
 class pkgAcqMethod
 {
 {

+ 5 - 0
apt-pkg/acquire.h

@@ -75,6 +75,11 @@
 #include <sys/time.h>
 #include <sys/time.h>
 #include <unistd.h>
 #include <unistd.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::vector;
+using std::string;
+#endif
+
 class pkgAcquireStatus;
 class pkgAcquireStatus;
 
 
 /** \brief The core download scheduler.					{{{
 /** \brief The core download scheduler.					{{{

+ 5 - 0
apt-pkg/algorithms.h

@@ -36,6 +36,11 @@
 
 
 #include <iostream>
 #include <iostream>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/acquire.h>
+using std::ostream;
+#endif
+
 class pkgAcquireStatus;
 class pkgAcquireStatus;
 
 
 class pkgSimulate : public pkgPackageManager				/*{{{*/
 class pkgSimulate : public pkgPackageManager				/*{{{*/

+ 6 - 0
apt-pkg/cachefile.h

@@ -20,6 +20,12 @@
 #include <apt-pkg/depcache.h>
 #include <apt-pkg/depcache.h>
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/acquire.h>
+#include <apt-pkg/policy.h>
+#include <apt-pkg/sourcelist.h>
+#endif
+
 class pkgPolicy;
 class pkgPolicy;
 class pkgSourceList;
 class pkgSourceList;
 class OpProgress;
 class OpProgress;

+ 4 - 0
apt-pkg/cacheset.h

@@ -20,6 +20,10 @@
 
 
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
+
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/cachefile.h>
+#endif
 									/*}}}*/
 									/*}}}*/
 
 
 class pkgCacheFile;
 class pkgCacheFile;

+ 85 - 73
apt-pkg/cdrom.cc

@@ -58,23 +58,21 @@ bool pkgCdrom::FindPackages(string CD,
       return _error->Errno("chdir","Unable to change to %s",CD.c_str());
       return _error->Errno("chdir","Unable to change to %s",CD.c_str());
 
 
    // Look for a .disk subdirectory
    // Look for a .disk subdirectory
-   struct stat Buf;
-   if (stat(".disk",&Buf) == 0)
+   if (DirectoryExists(".disk") == true)
    {
    {
       if (InfoDir.empty() == true)
       if (InfoDir.empty() == true)
 	 InfoDir = CD + ".disk/";
 	 InfoDir = CD + ".disk/";
    }
    }
 
 
    // Don't look into directories that have been marked to ingore.
    // Don't look into directories that have been marked to ingore.
-   if (stat(".aptignr",&Buf) == 0)
+   if (RealFileExists(".aptignr") == true)
       return true;
       return true;
 
 
-
    /* Check _first_ for a signature file as apt-cdrom assumes that all files
    /* Check _first_ for a signature file as apt-cdrom assumes that all files
       under a Packages/Source file are in control of that file and stops 
       under a Packages/Source file are in control of that file and stops 
       the scanning
       the scanning
    */
    */
-   if (stat("Release.gpg",&Buf) == 0)
+   if (RealFileExists("Release.gpg") == true || RealFileExists("InRelease") == true)
    {
    {
       SigList.push_back(CD);
       SigList.push_back(CD);
    }
    }
@@ -82,66 +80,69 @@ bool pkgCdrom::FindPackages(string CD,
    /* Aha! We found some package files. We assume that everything under 
    /* Aha! We found some package files. We assume that everything under 
       this dir is controlled by those package files so we don't look down
       this dir is controlled by those package files so we don't look down
       anymore */
       anymore */
-    std::vector<std::string> types = APT::Configuration::getCompressionTypes();
-    types.push_back("");
-    for (std::vector<std::string>::const_iterator t = types.begin();
-         t != types.end(); ++t)
-    {
-       std::string filename = std::string("Packages");
-       if ((*t).size() > 0)
-          filename.append("."+*t);
-       if (stat(filename.c_str(), &Buf) == 0)
-       {
-          List.push_back(CD);
-      
-          // Continue down if thorough is given
-          if (_config->FindB("APT::CDROM::Thorough",false) == false)
-             return true;
-          break;
-       }
-    }
-    for (std::vector<std::string>::const_iterator t = types.begin();
-         t != types.end(); ++t)
-    {
-       std::string filename = std::string("Sources");
-       if ((*t).size() > 0)
-          filename.append("."+*t);
-       {
-          SList.push_back(CD);
-      
-          // Continue down if thorough is given
-          if (_config->FindB("APT::CDROM::Thorough",false) == false)
-             return true;
-          break;
-       }
-    }
+   std::vector<APT::Configuration::Compressor> const compressor = APT::Configuration::getCompressors();
+   for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
+	c != compressor.end(); ++c)
+   {
+      if (RealFileExists(std::string("Packages").append(c->Extension).c_str()) == false)
+	 continue;
+
+      if (_config->FindB("Debug::aptcdrom",false) == true)
+	 std::clog << "Found Packages in " << CD << std::endl;
+      List.push_back(CD);
 
 
-   // see if we find translatin indexes
-   if (stat("i18n",&Buf) == 0)
+      // Continue down if thorough is given
+      if (_config->FindB("APT::CDROM::Thorough",false) == false)
+	 return true;
+      break;
+   }
+   for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
+	c != compressor.end(); ++c)
+   {
+      if (RealFileExists(std::string("Sources").append(c->Extension).c_str()) == false)
+	 continue;
+
+      if (_config->FindB("Debug::aptcdrom",false) == true)
+	 std::clog << "Found Sources in " << CD << std::endl;
+      SList.push_back(CD);
+
+      // Continue down if thorough is given
+      if (_config->FindB("APT::CDROM::Thorough",false) == false)
+	 return true;
+      break;
+   }
+
+   // see if we find translation indices
+   if (DirectoryExists("i18n") == true)
    {
    {
       D = opendir("i18n");
       D = opendir("i18n");
       for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
       for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
       {
       {
-	 if(strstr(Dir->d_name,"Translation") != NULL) 
+	 if(strncmp(Dir->d_name, "Translation-", strlen("Translation-")) != 0)
+	    continue;
+	 string file = Dir->d_name;
+	 for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
+	      c != compressor.end(); ++c)
 	 {
 	 {
-	    if (_config->FindB("Debug::aptcdrom",false) == true)
-	       std::clog << "found translations: " << Dir->d_name << "\n";
-	    string file = Dir->d_name;
-            for (std::vector<std::string>::const_iterator t = types.begin();
-                 t != types.end(); ++t)
-            {
-               std::string needle = "." + *t;
-               if(file.substr(file.size()-needle.size()) == needle)
-                  file = file.substr(0, file.size()-needle.size());
-               TransList.push_back(CD+"i18n/"+ file);
-               break;
-            }
+	    string fileext = flExtension(file);
+	    if (file == fileext)
+	       fileext.clear();
+	    else if (fileext.empty() == false)
+	       fileext = "." + fileext;
+
+	    if (c->Extension == fileext)
+	    {
+	       if (_config->FindB("Debug::aptcdrom",false) == true)
+		  std::clog << "Found translation " << Dir->d_name << " in " << CD << "i18n/" << std::endl;
+	       file.erase(file.size() - fileext.size());
+	       TransList.push_back(CD + "i18n/" + file);
+	       break;
+	    }
 	 }
 	 }
       }
       }
       closedir(D);
       closedir(D);
    }
    }
 
 
-   
    D = opendir(".");
    D = opendir(".");
    if (D == 0)
    if (D == 0)
       return _error->Errno("opendir","Unable to read %s",CD.c_str());
       return _error->Errno("opendir","Unable to read %s",CD.c_str());
@@ -276,38 +277,43 @@ bool pkgCdrom::DropBinaryArch(vector<string> &List)
 /* Here we go and stat every file that we found and strip dup inodes. */
 /* Here we go and stat every file that we found and strip dup inodes. */
 bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name)
 bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name)
 {
 {
+   bool couldFindAllFiles = true;
    // Get a list of all the inodes
    // Get a list of all the inodes
    ino_t *Inodes = new ino_t[List.size()];
    ino_t *Inodes = new ino_t[List.size()];
-   for (unsigned int I = 0; I != List.size(); I++)
+   for (unsigned int I = 0; I != List.size(); ++I)
    {
    {
       struct stat Buf;
       struct stat Buf;
-      std::vector<std::string> types = APT::Configuration::getCompressionTypes();
-      types.push_back("");
-      for (std::vector<std::string>::const_iterator t = types.begin();
-           t != types.end(); ++t)
+      bool found = false;
+
+      std::vector<APT::Configuration::Compressor> const compressor = APT::Configuration::getCompressors();
+      for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
+	   c != compressor.end(); ++c)
       {
       {
-         std::string filename = List[I] + Name;
-         if ((*t).size() > 0)
-            filename.append("." + *t);
+	 std::string filename = std::string(List[I]).append(Name).append(c->Extension);
          if (stat(filename.c_str(), &Buf) != 0)
          if (stat(filename.c_str(), &Buf) != 0)
-            _error->Errno("stat","Failed to stat %s%s",List[I].c_str(),
-                          Name);
-         Inodes[I] = Buf.st_ino;
+	    continue;
+	 Inodes[I] = Buf.st_ino;
+	 found = true;
+	 break;
+      }
+
+      if (found == false)
+      {
+	 _error->Errno("stat","Failed to stat %s%s",List[I].c_str(), Name);
+	 couldFindAllFiles = false;
+	 Inodes[I] = 0;
       }
       }
    }
    }
-   
-   if (_error->PendingError() == true) {
-      delete[] Inodes;
-      return false;
-   }
-   
+
    // Look for dups
    // Look for dups
    for (unsigned int I = 0; I != List.size(); I++)
    for (unsigned int I = 0; I != List.size(); I++)
    {
    {
+      if (Inodes[I] == 0)
+	 continue;
       for (unsigned int J = I+1; J < List.size(); J++)
       for (unsigned int J = I+1; J < List.size(); J++)
       {
       {
 	 // No match
 	 // No match
-	 if (Inodes[J] != Inodes[I])
+	 if (Inodes[J] == 0 || Inodes[J] != Inodes[I])
 	    continue;
 	    continue;
 	 
 	 
 	 // We score the two paths.. and erase one
 	 // We score the two paths.. and erase one
@@ -333,7 +339,7 @@ bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name)
 	 List.erase(List.begin()+I);
 	 List.erase(List.begin()+I);
    }
    }
    
    
-   return true;
+   return couldFindAllFiles;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // ReduceSourceList - Takes the path list and reduces it		/*{{{*/
 // ReduceSourceList - Takes the path list and reduces it		/*{{{*/
@@ -712,7 +718,13 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
    DropBinaryArch(List);
    DropBinaryArch(List);
    DropRepeats(List,"Packages");
    DropRepeats(List,"Packages");
    DropRepeats(SourceList,"Sources");
    DropRepeats(SourceList,"Sources");
+   // FIXME: We ignore stat() errors here as we usually have only one of those in use
+   // This has little potencial to drop 'valid' stat() errors as we know that one of these
+   // files need to exist, but it would be better if we would check it here
+   _error->PushToStack();
    DropRepeats(SigList,"Release.gpg");
    DropRepeats(SigList,"Release.gpg");
+   DropRepeats(SigList,"InRelease");
+   _error->RevertToStack();
    DropRepeats(TransList,"");
    DropRepeats(TransList,"");
    if(log != NULL) {
    if(log != NULL) {
       msg.str("");
       msg.str("");

+ 5 - 0
apt-pkg/cdrom.h

@@ -4,6 +4,11 @@
 #include<string>
 #include<string>
 #include<vector>
 #include<vector>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/init.h>
+using namespace std;
+#endif
+
 class Configuration;
 class Configuration;
 class OpProgress;
 class OpProgress;
 
 

+ 4 - 0
apt-pkg/contrib/cdromutl.h

@@ -12,6 +12,10 @@
 
 
 #include <string>
 #include <string>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+#endif
+
 // mount cdrom, DeviceName (e.g. /dev/sr0) is optional
 // mount cdrom, DeviceName (e.g. /dev/sr0) is optional
 bool MountCdrom(std::string Path, std::string DeviceName="");
 bool MountCdrom(std::string Path, std::string DeviceName="");
 bool UnmountCdrom(std::string Path);
 bool UnmountCdrom(std::string Path);

+ 4 - 0
apt-pkg/contrib/cmndline.h

@@ -44,6 +44,10 @@
 #ifndef PKGLIB_CMNDLINE_H
 #ifndef PKGLIB_CMNDLINE_H
 #define PKGLIB_CMNDLINE_H
 #define PKGLIB_CMNDLINE_H
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/configuration.h>
+#endif
+
 class Configuration;
 class Configuration;
 
 
 class CommandLine
 class CommandLine

+ 4 - 0
apt-pkg/contrib/configuration.h

@@ -34,6 +34,10 @@
 #include <vector>
 #include <vector>
 #include <iostream>
 #include <iostream>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+#endif
+
 class Configuration
 class Configuration
 {
 {
    public:
    public:

+ 432 - 74
apt-pkg/contrib/fileutl.cc

@@ -24,6 +24,7 @@
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/sptr.h>
 #include <apt-pkg/sptr.h>
+#include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 
 
 #include <cstdlib>
 #include <cstdlib>
@@ -43,6 +44,16 @@
 #include <set>
 #include <set>
 #include <algorithm>
 #include <algorithm>
 
 
+// FIXME: Compressor Fds have some speed disadvantages and are a bit buggy currently,
+// so while the current implementation satisfies the testcases it is not a real option
+// to disable it for now
+#define APT_USE_ZLIB 1
+#if APT_USE_ZLIB
+#include <zlib.h>
+#else
+#pragma message "Usage of zlib is DISABLED!"
+#endif
+
 #ifdef WORDS_BIGENDIAN
 #ifdef WORDS_BIGENDIAN
 #include <inttypes.h>
 #include <inttypes.h>
 #endif
 #endif
@@ -52,6 +63,21 @@
 
 
 using namespace std;
 using namespace std;
 
 
+class FileFdPrivate {
+	public:
+#if APT_USE_ZLIB
+	gzFile gz;
+#else
+	void* gz;
+#endif
+	int compressed_fd;
+	pid_t compressor_pid;
+	bool pipe;
+	APT::Configuration::Compressor compressor;
+	unsigned int openmode;
+	FileFdPrivate() : gz(NULL), compressed_fd(-1), compressor_pid(-1), pipe(false) {};
+};
+
 // RunScripts - Run a set of scripts from a configuration subtree	/*{{{*/
 // RunScripts - Run a set of scripts from a configuration subtree	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -718,84 +744,287 @@ bool ExecWait(pid_t Pid,const char *Name,bool Reap)
 // FileFd::Open - Open a file						/*{{{*/
 // FileFd::Open - Open a file						/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The most commonly used open mode combinations are given with Mode */
 /* The most commonly used open mode combinations are given with Mode */
-bool FileFd::Open(string FileName,OpenMode Mode, unsigned long Perms)
+bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress, unsigned long const Perms)
 {
 {
-   Close();
-   Flags = AutoClose;
-   switch (Mode)
+   if (Mode == ReadOnlyGzip)
+      return Open(FileName, ReadOnly, Gzip, Perms);
+
+   if (Compress == Auto && (Mode & WriteOnly) == WriteOnly)
+      return _error->Error("Autodetection on %s only works in ReadOnly openmode!", FileName.c_str());
+
+   // FIXME: Denote inbuilt compressors somehow - as we don't need to have the binaries for them
+   std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors();
+   std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin();
+   if (Compress == Auto)
    {
    {
-      case ReadOnly:
-      iFd = open(FileName.c_str(),O_RDONLY);
-      break;
-
-      case ReadOnlyGzip:
-      iFd = open(FileName.c_str(),O_RDONLY);
-      if (iFd > 0) {
-	 gz = gzdopen (iFd, "r");
-	 if (gz == NULL) {
-	     close (iFd);
-	     iFd = -1;
-	 }
-      }
-      break;
-      
-      case WriteAtomic:
+      for (; compressor != compressors.end(); ++compressor)
       {
       {
-	 Flags |= Replace;
-	 char *name = strdup((FileName + ".XXXXXX").c_str());
-	 TemporaryFileName = string(mktemp(name));
-	 iFd = open(TemporaryFileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms);
-	 free(name);
+	 std::string file = std::string(FileName).append(compressor->Extension);
+	 if (FileExists(file) == false)
+	    continue;
+	 FileName = file;
 	 break;
 	 break;
       }
       }
-
-      case WriteEmpty:
+   }
+   else if (Compress == Extension)
+   {
+      std::string::size_type const found = FileName.find_last_of('.');
+      std::string ext;
+      if (found != std::string::npos)
       {
       {
-      	 struct stat Buf;
-	 if (lstat(FileName.c_str(),&Buf) == 0 && S_ISLNK(Buf.st_mode))
-	    unlink(FileName.c_str());
-	 iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_TRUNC,Perms);
-	 break;
+	 ext = FileName.substr(found);
+	 if (ext == ".new" || ext == ".bak")
+	 {
+	    std::string::size_type const found2 = FileName.find_last_of('.', found - 1);
+	    if (found2 != std::string::npos)
+	       ext = FileName.substr(found2, found - found2);
+	    else
+	       ext.clear();
+	 }
       }
       }
-      
-      case WriteExists:
-      iFd = open(FileName.c_str(),O_RDWR);
-      break;
+      for (; compressor != compressors.end(); ++compressor)
+	 if (ext == compressor->Extension)
+	    break;
+      // no matching extension - assume uncompressed (imagine files like 'example.org_Packages')
+      if (compressor == compressors.end())
+	 for (compressor = compressors.begin(); compressor != compressors.end(); ++compressor)
+	    if (compressor->Name == ".")
+	       break;
+   }
+   else
+   {
+      std::string name;
+      switch (Compress)
+      {
+      case None: name = "."; break;
+      case Gzip: name = "gzip"; break;
+      case Bzip2: name = "bzip2"; break;
+      case Lzma: name = "lzma"; break;
+      case Xz: name = "xz"; break;
+      case Auto:
+      case Extension:
+	 // Unreachable
+	 return _error->Error("Opening File %s in None, Auto or Extension should be already handled?!?", FileName.c_str());
+      }
+      for (; compressor != compressors.end(); ++compressor)
+	 if (compressor->Name == name)
+	    break;
+      if (compressor == compressors.end())
+	 return _error->Error("Can't find a configured compressor %s for file %s", name.c_str(), FileName.c_str());
+   }
 
 
-      case WriteAny:
-      iFd = open(FileName.c_str(),O_RDWR | O_CREAT,Perms);
-      break;      
+   if (compressor == compressors.end())
+      return _error->Error("Can't find a match for specified compressor mode for file %s", FileName.c_str());
+   return Open(FileName, Mode, *compressor, Perms);
+}
+bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor, unsigned long const Perms)
+{
+   Close();
+   d = new FileFdPrivate;
+   d->openmode = Mode;
+   Flags = AutoClose;
+
+   if ((Mode & WriteOnly) != WriteOnly && (Mode & (Atomic | Create | Empty | Exclusive)) != 0)
+      return _error->Error("ReadOnly mode for %s doesn't accept additional flags!", FileName.c_str());
+   if ((Mode & ReadWrite) == 0)
+      return _error->Error("No openmode provided in FileFd::Open for %s", FileName.c_str());
 
 
-      case WriteTemp:
+   if ((Mode & Atomic) == Atomic)
+   {
+      Flags |= Replace;
+      char *name = strdup((FileName + ".XXXXXX").c_str());
+      TemporaryFileName = string(mktemp(name));
+      free(name);
+   }
+   else if ((Mode & (Exclusive | Create)) == (Exclusive | Create))
+   {
+      // for atomic, this will be done by rename in Close()
       unlink(FileName.c_str());
       unlink(FileName.c_str());
-      iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms);
-      break;
-   }  
+   }
+   if ((Mode & Empty) == Empty)
+   {
+      struct stat Buf;
+      if (lstat(FileName.c_str(),&Buf) == 0 && S_ISLNK(Buf.st_mode))
+	 unlink(FileName.c_str());
+   }
+
+   int fileflags = 0;
+   #define if_FLAGGED_SET(FLAG, MODE) if ((Mode & FLAG) == FLAG) fileflags |= MODE
+   if_FLAGGED_SET(ReadWrite, O_RDWR);
+   else if_FLAGGED_SET(ReadOnly, O_RDONLY);
+   else if_FLAGGED_SET(WriteOnly, O_WRONLY);
+
+   if_FLAGGED_SET(Create, O_CREAT);
+   if_FLAGGED_SET(Empty, O_TRUNC);
+   if_FLAGGED_SET(Exclusive, O_EXCL);
+   else if_FLAGGED_SET(Atomic, O_EXCL);
+   #undef if_FLAGGED_SET
+
+   if (TemporaryFileName.empty() == false)
+      iFd = open(TemporaryFileName.c_str(), fileflags, Perms);
+   else
+      iFd = open(FileName.c_str(), fileflags, Perms);
+
+   if (iFd == -1 || OpenInternDescriptor(Mode, compressor) == false)
+   {
+      if (iFd != -1)
+      {
+	 close (iFd);
+	 iFd = -1;
+      }
+      return _error->Errno("open",_("Could not open file %s"), FileName.c_str());
+   }
 
 
-   if (iFd < 0)
-      return _error->Errno("open",_("Could not open file %s"),FileName.c_str());
-   
    this->FileName = FileName;
    this->FileName = FileName;
    SetCloseExec(iFd,true);
    SetCloseExec(iFd,true);
    return true;
    return true;
 }
 }
+									/*}}}*/
+// FileFd::OpenDescriptor - Open a filedescriptor			/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compress, bool AutoClose)
+{
+   std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors();
+   std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin();
+   std::string name;
+   switch (Compress)
+   {
+   case None: name = "."; break;
+   case Gzip: name = "gzip"; break;
+   case Bzip2: name = "bzip2"; break;
+   case Lzma: name = "lzma"; break;
+   case Xz: name = "xz"; break;
+   case Auto:
+   case Extension:
+      return _error->Error("Opening Fd %d in Auto or Extension compression mode is not supported", Fd);
+   }
+   for (; compressor != compressors.end(); ++compressor)
+      if (compressor->Name == name)
+	 break;
+   if (compressor == compressors.end())
+      return _error->Error("Can't find a configured compressor %s for file %s", name.c_str(), FileName.c_str());
 
 
-bool FileFd::OpenDescriptor(int Fd, OpenMode Mode, bool AutoClose)
+   return OpenDescriptor(Fd, Mode, *compressor, AutoClose);
+}
+bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose)
 {
 {
    Close();
    Close();
+   d = new FileFdPrivate;
+   d->openmode = Mode;
    Flags = (AutoClose) ? FileFd::AutoClose : 0;
    Flags = (AutoClose) ? FileFd::AutoClose : 0;
    iFd = Fd;
    iFd = Fd;
-   if (Mode == ReadOnlyGzip) {
-      gz = gzdopen (iFd, "r");
-      if (gz == NULL) {
-	 if (AutoClose)
-	    close (iFd);
-	 return _error->Errno("gzdopen",_("Could not open file descriptor %d"),
-			      Fd);
-      }
+   if (OpenInternDescriptor(Mode, compressor) == false)
+   {
+      if (AutoClose)
+	 close (iFd);
+      return _error->Errno("gzdopen",_("Could not open file descriptor %d"), Fd);
    }
    }
    this->FileName = "";
    this->FileName = "";
    return true;
    return true;
+}
+bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor)
+{
+   d->compressor = compressor;
+   if (compressor.Name == "." || compressor.Binary.empty() == true)
+      return true;
+#if APT_USE_ZLIB
+   else if (compressor.Name == "gzip")
+   {
+      if ((Mode & ReadWrite) == ReadWrite)
+	 d->gz = gzdopen(iFd, "r+");
+      else if ((Mode & WriteOnly) == WriteOnly)
+	 d->gz = gzdopen(iFd, "w");
+      else
+	 d->gz = gzdopen (iFd, "r");
+      if (d->gz == NULL)
+	 return false;
+      Flags |= Compressed;
+      return true;
+   }
+#endif
+
+   if ((Mode & ReadWrite) == ReadWrite)
+      return _error->Error("ReadWrite mode is not supported for file %s", FileName.c_str());
+
+   bool const Comp = (Mode & WriteOnly) == WriteOnly;
+   // Handle 'decompression' of empty files
+   if (Comp == false)
+   {
+      struct stat Buf;
+      fstat(iFd, &Buf);
+      if (Buf.st_size == 0 && S_ISFIFO(Buf.st_mode) == false)
+	 return true;
+
+      // We don't need the file open - instead let the compressor open it
+      // as he properly knows better how to efficiently read from 'his' file
+      if (FileName.empty() == false)
+	 close(iFd);
+   }
+
+   // Create a data pipe
+   int Pipe[2] = {-1,-1};
+   if (pipe(Pipe) != 0)
+      return _error->Errno("pipe",_("Failed to create subprocess IPC"));
+   for (int J = 0; J != 2; J++)
+      SetCloseExec(Pipe[J],true);
+
+   d->compressed_fd = iFd;
+   d->pipe = true;
+
+   if (Comp == true)
+      iFd = Pipe[1];
+   else
+      iFd = Pipe[0];
+
+   // The child..
+   d->compressor_pid = ExecFork();
+   if (d->compressor_pid == 0)
+   {
+      if (Comp == true)
+      {
+	 dup2(d->compressed_fd,STDOUT_FILENO);
+	 dup2(Pipe[0],STDIN_FILENO);
+      }
+      else
+      {
+	 if (FileName.empty() == true)
+	    dup2(d->compressed_fd,STDIN_FILENO);
+	 dup2(Pipe[1],STDOUT_FILENO);
+      }
+
+      SetCloseExec(STDOUT_FILENO,false);
+      SetCloseExec(STDIN_FILENO,false);
+
+      std::vector<char const*> Args;
+      Args.push_back(compressor.Binary.c_str());
+      std::vector<std::string> const * const addArgs =
+		(Comp == true) ? &(compressor.CompressArgs) : &(compressor.UncompressArgs);
+      for (std::vector<std::string>::const_iterator a = addArgs->begin();
+	   a != addArgs->end(); ++a)
+	 Args.push_back(a->c_str());
+      if (Comp == false && FileName.empty() == false)
+      {
+	 Args.push_back("--stdout");
+	 if (TemporaryFileName.empty() == false)
+	    Args.push_back(TemporaryFileName.c_str());
+	 else
+	    Args.push_back(FileName.c_str());
+      }
+      Args.push_back(NULL);
+
+      execvp(Args[0],(char **)&Args[0]);
+      cerr << _("Failed to exec compressor ") << Args[0] << endl;
+      _exit(100);
+   }
+   if (Comp == true)
+      close(Pipe[0]);
+   else
+      close(Pipe[1]);
+   if (Comp == true || FileName.empty() == true)
+      close(d->compressed_fd);
+
+   return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // FileFd::~File - Closes the file					/*{{{*/
 // FileFd::~File - Closes the file					/*{{{*/
@@ -817,12 +1046,14 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
    errno = 0;
    errno = 0;
    if (Actual != 0)
    if (Actual != 0)
       *Actual = 0;
       *Actual = 0;
-   
+   *((char *)To) = '\0';
    do
    do
    {
    {
-      if (gz != NULL)
-         Res = gzread(gz,To,Size);
+#if APT_USE_ZLIB
+      if (d->gz != NULL)
+         Res = gzread(d->gz,To,Size);
       else
       else
+#endif
          Res = read(iFd,To,Size);
          Res = read(iFd,To,Size);
       if (Res < 0 && errno == EINTR)
       if (Res < 0 && errno == EINTR)
 	 continue;
 	 continue;
@@ -853,6 +1084,31 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
    return _error->Error(_("read, still have %llu to read but none left"), Size);
    return _error->Error(_("read, still have %llu to read but none left"), Size);
 }
 }
 									/*}}}*/
 									/*}}}*/
+// FileFd::ReadLine - Read a complete line from the file		/*{{{*/
+// ---------------------------------------------------------------------
+/* Beware: This method can be quiet slow for big buffers on UNcompressed
+   files because of the naive implementation! */
+char* FileFd::ReadLine(char *To, unsigned long long const Size)
+{
+   *To = '\0';
+#if APT_USE_ZLIB
+   if (d->gz != NULL)
+      return gzgets(d->gz, To, Size);
+#endif
+
+   unsigned long long read = 0;
+   if (Read(To, Size, &read) == false)
+      return NULL;
+   char* c = To;
+   for (; *c != '\n' && *c != '\0' && read != 0; --read, ++c)
+      ; // find the end of the line
+   if (*c != '\0')
+      *c = '\0';
+   if (read != 0)
+      Seek(Tell() - read);
+   return To;
+}
+									/*}}}*/
 // FileFd::Write - Write to the file					/*{{{*/
 // FileFd::Write - Write to the file					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -862,9 +1118,11 @@ bool FileFd::Write(const void *From,unsigned long long Size)
    errno = 0;
    errno = 0;
    do
    do
    {
    {
-      if (gz != NULL)
-         Res = gzwrite(gz,From,Size);
+#if APT_USE_ZLIB
+      if (d->gz != NULL)
+         Res = gzwrite(d->gz,From,Size);
       else
       else
+#endif
          Res = write(iFd,From,Size);
          Res = write(iFd,From,Size);
       if (Res < 0 && errno == EINTR)
       if (Res < 0 && errno == EINTR)
 	 continue;
 	 continue;
@@ -891,10 +1149,38 @@ bool FileFd::Write(const void *From,unsigned long long Size)
 /* */
 /* */
 bool FileFd::Seek(unsigned long long To)
 bool FileFd::Seek(unsigned long long To)
 {
 {
+   if (d->pipe == true)
+   {
+      if ((d->openmode & ReadOnly) != ReadOnly)
+	 return _error->Error("Reopen is only implemented for read-only files!");
+      close(iFd);
+      iFd = 0;
+      if (TemporaryFileName.empty() == false)
+	 iFd = open(TemporaryFileName.c_str(), O_RDONLY);
+      else if (FileName.empty() == false)
+	 iFd = open(FileName.c_str(), O_RDONLY);
+      else
+      {
+	 if (d->compressed_fd > 0)
+	    if (lseek(d->compressed_fd, 0, SEEK_SET) != 0)
+	       iFd = d->compressed_fd;
+	 if (iFd <= 0)
+	    return _error->Error("Reopen is not implemented for pipes opened with FileFd::OpenDescriptor()!");
+      }
+
+      if (OpenInternDescriptor(d->openmode, d->compressor) == false)
+	 return _error->Error("Seek on file %s because it couldn't be reopened", FileName.c_str());
+
+      if (To != 0)
+	 return Skip(To);
+      return true;
+   }
    int res;
    int res;
-   if (gz)
-      res = gzseek(gz,To,SEEK_SET);
+#if APT_USE_ZLIB
+   if (d->gz)
+      res = gzseek(d->gz,To,SEEK_SET);
    else
    else
+#endif
       res = lseek(iFd,To,SEEK_SET);
       res = lseek(iFd,To,SEEK_SET);
    if (res != (signed)To)
    if (res != (signed)To)
    {
    {
@@ -911,9 +1197,11 @@ bool FileFd::Seek(unsigned long long To)
 bool FileFd::Skip(unsigned long long Over)
 bool FileFd::Skip(unsigned long long Over)
 {
 {
    int res;
    int res;
-   if (gz)
-      res = gzseek(gz,Over,SEEK_CUR);
+#if APT_USE_ZLIB
+   if (d->gz != NULL)
+      res = gzseek(d->gz,Over,SEEK_CUR);
    else
    else
+#endif
       res = lseek(iFd,Over,SEEK_CUR);
       res = lseek(iFd,Over,SEEK_CUR);
    if (res < 0)
    if (res < 0)
    {
    {
@@ -929,7 +1217,7 @@ bool FileFd::Skip(unsigned long long Over)
 /* */
 /* */
 bool FileFd::Truncate(unsigned long long To)
 bool FileFd::Truncate(unsigned long long To)
 {
 {
-   if (gz)
+   if (d->gz != NULL)
    {
    {
       Flags |= Fail;
       Flags |= Fail;
       return _error->Error("Truncating gzipped files is not implemented (%s)", FileName.c_str());
       return _error->Error("Truncating gzipped files is not implemented (%s)", FileName.c_str());
@@ -949,9 +1237,11 @@ bool FileFd::Truncate(unsigned long long To)
 unsigned long long FileFd::Tell()
 unsigned long long FileFd::Tell()
 {
 {
    off_t Res;
    off_t Res;
-   if (gz)
-     Res = gztell(gz);
+#if APT_USE_ZLIB
+   if (d->gz != NULL)
+     Res = gztell(d->gz);
    else
    else
+#endif
      Res = lseek(iFd,0,SEEK_CUR);
      Res = lseek(iFd,0,SEEK_CUR);
    if (Res == (off_t)-1)
    if (Res == (off_t)-1)
       _error->Errno("lseek","Failed to determine the current file position");
       _error->Errno("lseek","Failed to determine the current file position");
@@ -964,9 +1254,19 @@ unsigned long long FileFd::Tell()
 unsigned long long FileFd::FileSize()
 unsigned long long FileFd::FileSize()
 {
 {
    struct stat Buf;
    struct stat Buf;
-
-   if (fstat(iFd,&Buf) != 0)
+   if (d->pipe == false && fstat(iFd,&Buf) != 0)
       return _error->Errno("fstat","Unable to determine the file size");
       return _error->Errno("fstat","Unable to determine the file size");
+
+   // for compressor pipes st_size is undefined and at 'best' zero
+   if (d->pipe == true || S_ISFIFO(Buf.st_mode))
+   {
+      // we set it here, too, as we get the info here for free
+      // in theory the Open-methods should take care of it already
+      d->pipe = true;
+      if (stat(FileName.c_str(), &Buf) != 0)
+	 return _error->Errno("stat","Unable to determine the file size");
+   }
+
    return Buf.st_size;
    return Buf.st_size;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -977,10 +1277,25 @@ unsigned long long FileFd::Size()
 {
 {
    unsigned long long size = FileSize();
    unsigned long long size = FileSize();
 
 
+   // for compressor pipes st_size is undefined and at 'best' zero,
+   // so we 'read' the content and 'seek' back - see there
+   if (d->pipe == true)
+   {
+      // FIXME: If we have read first and then FileSize() the report is wrong
+      size = 0;
+      char ignore[1000];
+      unsigned long long read = 0;
+      do {
+	 Read(ignore, sizeof(ignore), &read);
+	 size += read;
+      } while(read != 0);
+      Seek(0);
+   }
+#if APT_USE_ZLIB
    // only check gzsize if we are actually a gzip file, just checking for
    // only check gzsize if we are actually a gzip file, just checking for
-   // "gz" is not sufficient as uncompressed files will be opened with
+   // "gz" is not sufficient as uncompressed files could be opened with
    // gzopen in "direct" mode as well
    // gzopen in "direct" mode as well
-   if (gz && !gzdirect(gz) && size > 0)
+   else if (d->gz && !gzdirect(d->gz) && size > 0)
    {
    {
        /* unfortunately zlib.h doesn't provide a gzsize(), so we have to do
        /* unfortunately zlib.h doesn't provide a gzsize(), so we have to do
 	* this ourselves; the original (uncompressed) file size is the last 32
 	* this ourselves; the original (uncompressed) file size is the last 32
@@ -1004,24 +1319,58 @@ unsigned long long FileFd::Size()
 	   return _error->Errno("lseek","Unable to seek in gzipped file");
 	   return _error->Errno("lseek","Unable to seek in gzipped file");
        return size;
        return size;
    }
    }
+#endif
 
 
    return size;
    return size;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// FileFd::ModificationTime - Return the time of last touch		/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+time_t FileFd::ModificationTime()
+{
+   struct stat Buf;
+   if (d->pipe == false && fstat(iFd,&Buf) != 0)
+   {
+      _error->Errno("fstat","Unable to determine the modification time of file %s", FileName.c_str());
+      return 0;
+   }
+
+   // for compressor pipes st_size is undefined and at 'best' zero
+   if (d->pipe == true || S_ISFIFO(Buf.st_mode))
+   {
+      // we set it here, too, as we get the info here for free
+      // in theory the Open-methods should take care of it already
+      d->pipe = true;
+      if (stat(FileName.c_str(), &Buf) != 0)
+      {
+	 _error->Errno("fstat","Unable to determine the modification time of file %s", FileName.c_str());
+	 return 0;
+      }
+   }
+
+   return Buf.st_mtime;
+}
+									/*}}}*/
 // FileFd::Close - Close the file if the close flag is set		/*{{{*/
 // FileFd::Close - Close the file if the close flag is set		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
 bool FileFd::Close()
 bool FileFd::Close()
 {
 {
+   if (iFd == -1)
+      return true;
+
    bool Res = true;
    bool Res = true;
    if ((Flags & AutoClose) == AutoClose)
    if ((Flags & AutoClose) == AutoClose)
    {
    {
-      if (gz != NULL) {
-	 int const e = gzclose(gz);
+#if APT_USE_ZLIB
+      if (d != NULL && d->gz != NULL) {
+	 int const e = gzclose(d->gz);
 	 // gzdopen() on empty files always fails with "buffer error" here, ignore that
 	 // gzdopen() on empty files always fails with "buffer error" here, ignore that
 	 if (e != 0 && e != Z_BUF_ERROR)
 	 if (e != 0 && e != Z_BUF_ERROR)
 	    Res &= _error->Errno("close",_("Problem closing the gzip file %s"), FileName.c_str());
 	    Res &= _error->Errno("close",_("Problem closing the gzip file %s"), FileName.c_str());
       } else
       } else
+#endif
 	 if (iFd > 0 && close(iFd) != 0)
 	 if (iFd > 0 && close(iFd) != 0)
 	    Res &= _error->Errno("close",_("Problem closing the file %s"), FileName.c_str());
 	    Res &= _error->Errno("close",_("Problem closing the file %s"), FileName.c_str());
    }
    }
@@ -1031,16 +1380,23 @@ bool FileFd::Close()
 	 Res &= _error->Errno("rename",_("Problem renaming the file %s to %s"), TemporaryFileName.c_str(), FileName.c_str());
 	 Res &= _error->Errno("rename",_("Problem renaming the file %s to %s"), TemporaryFileName.c_str(), FileName.c_str());
 
 
       FileName = TemporaryFileName; // for the unlink() below.
       FileName = TemporaryFileName; // for the unlink() below.
+      TemporaryFileName.clear();
    }
    }
 
 
    iFd = -1;
    iFd = -1;
-   gz = NULL;
 
 
    if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail &&
    if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail &&
        FileName.empty() == false)
        FileName.empty() == false)
       if (unlink(FileName.c_str()) != 0)
       if (unlink(FileName.c_str()) != 0)
 	 Res &= _error->WarningE("unlnk",_("Problem unlinking the file %s"), FileName.c_str());
 	 Res &= _error->WarningE("unlnk",_("Problem unlinking the file %s"), FileName.c_str());
 
 
+   if (d != NULL)
+   {
+      if (d->compressor_pid > 0)
+	 ExecWait(d->compressor_pid, "FileFdCompressor", true);
+      delete d;
+      d = NULL;
+   }
 
 
    return Res;
    return Res;
 }
 }
@@ -1057,3 +1413,5 @@ bool FileFd::Sync()
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+gzFile FileFd::gzFd() { return (gzFile) d->gz; }

+ 59 - 12
apt-pkg/contrib/fileutl.h

@@ -22,30 +22,51 @@
 #define PKGLIB_FILEUTL_H
 #define PKGLIB_FILEUTL_H
 
 
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
+#include <apt-pkg/aptconfiguration.h>
 
 
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
 
 
 #include <zlib.h>
 #include <zlib.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+#endif
+
 /* Define this for python-apt */
 /* Define this for python-apt */
 #define APT_HAS_GZIP 1
 #define APT_HAS_GZIP 1
 
 
+class FileFdPrivate;
 class FileFd
 class FileFd
 {
 {
    protected:
    protected:
    int iFd;
    int iFd;
  
  
    enum LocalFlags {AutoClose = (1<<0),Fail = (1<<1),DelOnFail = (1<<2),
    enum LocalFlags {AutoClose = (1<<0),Fail = (1<<1),DelOnFail = (1<<2),
-                    HitEof = (1<<3), Replace = (1<<4) };
+                    HitEof = (1<<3), Replace = (1<<4), Compressed = (1<<5) };
    unsigned long Flags;
    unsigned long Flags;
    std::string FileName;
    std::string FileName;
    std::string TemporaryFileName;
    std::string TemporaryFileName;
-   gzFile gz;
 
 
    public:
    public:
-   enum OpenMode {ReadOnly,WriteEmpty,WriteExists,WriteAny,WriteTemp,ReadOnlyGzip,
-                  WriteAtomic};
+   enum OpenMode {
+	ReadOnly = (1 << 0),
+	WriteOnly = (1 << 1),
+	ReadWrite = ReadOnly | WriteOnly,
+
+	Create = (1 << 2),
+	Exclusive = (1 << 3),
+	Atomic = Exclusive | (1 << 4),
+	Empty = (1 << 5),
+
+	WriteEmpty = ReadWrite | Create | Empty,
+	WriteExists = ReadWrite,
+	WriteAny = ReadWrite | Create,
+	WriteTemp = ReadWrite | Create | Exclusive,
+	ReadOnlyGzip,
+	WriteAtomic = ReadWrite | Create | Atomic
+   };
+   enum CompressMode { Auto = 'A', None = 'N', Extension = 'E', Gzip = 'G', Bzip2 = 'B', Lzma = 'L', Xz = 'X' };
    
    
    inline bool Read(void *To,unsigned long long Size,bool AllowEof)
    inline bool Read(void *To,unsigned long long Size,bool AllowEof)
    {
    {
@@ -55,6 +76,7 @@ class FileFd
       return Read(To,Size);
       return Read(To,Size);
    }   
    }   
    bool Read(void *To,unsigned long long Size,unsigned long long *Actual = 0);
    bool Read(void *To,unsigned long long Size,unsigned long long *Actual = 0);
+   char* ReadLine(char *To, unsigned long long const Size);
    bool Write(const void *From,unsigned long long Size);
    bool Write(const void *From,unsigned long long Size);
    bool Seek(unsigned long long To);
    bool Seek(unsigned long long To);
    bool Skip(unsigned long long To);
    bool Skip(unsigned long long To);
@@ -62,6 +84,7 @@ class FileFd
    unsigned long long Tell();
    unsigned long long Tell();
    unsigned long long Size();
    unsigned long long Size();
    unsigned long long FileSize();
    unsigned long long FileSize();
+   time_t ModificationTime();
 
 
    /* You want to use 'unsigned long long' if you are talking about a file
    /* You want to use 'unsigned long long' if you are talking about a file
       to be able to support large files (>2 or >4 GB) properly.
       to be able to support large files (>2 or >4 GB) properly.
@@ -77,30 +100,54 @@ class FileFd
 	return T;
 	return T;
    }
    }
 
 
-   bool Open(std::string FileName,OpenMode Mode,unsigned long Perms = 0666);
-   bool OpenDescriptor(int Fd, OpenMode Mode, bool AutoClose=false);
+   bool Open(std::string FileName,unsigned int const Mode,CompressMode Compress,unsigned long const Perms = 0666);
+   bool Open(std::string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor,unsigned long const Perms = 0666);
+   inline bool Open(std::string const &FileName,unsigned int const Mode, unsigned long const Perms = 0666) {
+      return Open(FileName, Mode, None, Perms);
+   };
+   bool OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compress, bool AutoClose=false);
+   bool OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose=false);
+   inline bool OpenDescriptor(int Fd, unsigned int const Mode, bool AutoClose=false) {
+      return OpenDescriptor(Fd, Mode, None, AutoClose);
+   };
    bool Close();
    bool Close();
    bool Sync();
    bool Sync();
    
    
    // Simple manipulators
    // Simple manipulators
    inline int Fd() {return iFd;};
    inline int Fd() {return iFd;};
    inline void Fd(int fd) {iFd = fd;};
    inline void Fd(int fd) {iFd = fd;};
-   inline gzFile gzFd() {return gz;};
+   __deprecated gzFile gzFd();
+
    inline bool IsOpen() {return iFd >= 0;};
    inline bool IsOpen() {return iFd >= 0;};
    inline bool Failed() {return (Flags & Fail) == Fail;};
    inline bool Failed() {return (Flags & Fail) == Fail;};
    inline void EraseOnFailure() {Flags |= DelOnFail;};
    inline void EraseOnFailure() {Flags |= DelOnFail;};
    inline void OpFail() {Flags |= Fail;};
    inline void OpFail() {Flags |= Fail;};
    inline bool Eof() {return (Flags & HitEof) == HitEof;};
    inline bool Eof() {return (Flags & HitEof) == HitEof;};
+   inline bool IsCompressed() {return (Flags & Compressed) == Compressed;};
    inline std::string &Name() {return FileName;};
    inline std::string &Name() {return FileName;};
    
    
-   FileFd(std::string FileName,OpenMode Mode,unsigned long Perms = 0666) : iFd(-1), 
-            Flags(0), gz(NULL)
+   FileFd(std::string FileName,unsigned int const Mode,unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL)
    {
    {
-      Open(FileName,Mode,Perms);
+      Open(FileName,Mode, None, Perms);
+   };
+   FileFd(std::string FileName,unsigned int const Mode, CompressMode Compress, unsigned long Perms = 0666) : iFd(-1), Flags(0), d(NULL)
+   {
+      Open(FileName,Mode, Compress, Perms);
+   };
+   FileFd() : iFd(-1), Flags(AutoClose), d(NULL) {};
+   FileFd(int const Fd, unsigned int const Mode = ReadWrite, CompressMode Compress = None) : iFd(-1), Flags(0), d(NULL)
+   {
+      OpenDescriptor(Fd, Mode, Compress);
+   };
+   FileFd(int const Fd, bool const AutoClose) : iFd(-1), Flags(0), d(NULL)
+   {
+      OpenDescriptor(Fd, ReadWrite, None, AutoClose);
    };
    };
-   FileFd(int Fd = -1) : iFd(Fd), Flags(AutoClose), gz(NULL) {};
-   FileFd(int Fd,bool) : iFd(Fd), Flags(0), gz(NULL) {};
    virtual ~FileFd();
    virtual ~FileFd();
+
+   private:
+   FileFdPrivate* d;
+   bool OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor);
 };
 };
 
 
 bool RunScripts(const char *Cnf);
 bool RunScripts(const char *Cnf);

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

@@ -22,6 +22,12 @@
 #include <vector>
 #include <vector>
 #include <cstring>
 #include <cstring>
 
 
+
+#ifndef APT_8_CLEANER_HEADERS
+using std::min;
+using std::vector;
+#endif
+
 // helper class that contains hash function name
 // helper class that contains hash function name
 // and hash
 // and hash
 class HashString
 class HashString

+ 5 - 0
apt-pkg/contrib/hashsum_template.h

@@ -15,6 +15,11 @@
 #include <algorithm>
 #include <algorithm>
 #include <stdint.h>
 #include <stdint.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+using std::min;
+#endif
+
 template<int N>
 template<int N>
 class HashSumValue
 class HashSumValue
 {
 {

+ 5 - 0
apt-pkg/contrib/md5.h

@@ -31,6 +31,11 @@
 
 
 #include "hashsum_template.h"
 #include "hashsum_template.h"
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+using std::min;
+#endif
+
 typedef HashSumValue<128> MD5SumValue;
 typedef HashSumValue<128> MD5SumValue;
 
 
 class MD5Summation : public SummationImplementation
 class MD5Summation : public SummationImplementation

+ 20 - 2
apt-pkg/contrib/mmap.cc

@@ -66,7 +66,7 @@ MMap::~MMap()
 bool MMap::Map(FileFd &Fd)
 bool MMap::Map(FileFd &Fd)
 {
 {
    iSize = Fd.Size();
    iSize = Fd.Size();
-   
+
    // Set the permissions.
    // Set the permissions.
    int Prot = PROT_READ;
    int Prot = PROT_READ;
    int Map = MAP_SHARED;
    int Map = MAP_SHARED;
@@ -77,7 +77,18 @@ bool MMap::Map(FileFd &Fd)
    
    
    if (iSize == 0)
    if (iSize == 0)
       return _error->Error(_("Can't mmap an empty file"));
       return _error->Error(_("Can't mmap an empty file"));
-   
+
+   // We can't mmap compressed fd's directly, so we need to read it completely
+   if (Fd.IsCompressed() == true)
+   {
+      if ((Flags & ReadOnly) != ReadOnly)
+	 return _error->Error("Compressed file %s can only be mapped readonly", Fd.Name().c_str());
+      Base = new unsigned char[iSize];
+      if (Fd.Seek(0L) == false || Fd.Read(Base, iSize) == false)
+	 return false;
+      return true;
+   }
+
    // Map it.
    // Map it.
    Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0);
    Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0);
    if (Base == (void *)-1)
    if (Base == (void *)-1)
@@ -86,6 +97,13 @@ bool MMap::Map(FileFd &Fd)
       {
       {
 	 // The filesystem doesn't support this particular kind of mmap.
 	 // The filesystem doesn't support this particular kind of mmap.
 	 // So we allocate a buffer and read the whole file into it.
 	 // So we allocate a buffer and read the whole file into it.
+	 if ((Flags & ReadOnly) == ReadOnly)
+	 {
+	    // for readonly, we don't need sync, so make it simple
+	    Base = new unsigned char[iSize];
+	    return Fd.Read(Base, iSize);
+	 }
+	 // FIXME: Writing to compressed fd's ?
 	 int const dupped_fd = dup(Fd.Fd());
 	 int const dupped_fd = dup(Fd.Fd());
 	 if (dupped_fd == -1)
 	 if (dupped_fd == -1)
 	    return _error->Errno("mmap", _("Couldn't duplicate file descriptor %i"), Fd.Fd());
 	    return _error->Errno("mmap", _("Couldn't duplicate file descriptor %i"), Fd.Fd());

+ 5 - 0
apt-pkg/contrib/mmap.h

@@ -28,6 +28,11 @@
 
 
 #include <string>
 #include <string>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/fileutl.h>
+using std::string;
+#endif
+
 class FileFd;
 class FileFd;
 
 
 /* This should be a 32 bit type, larger tyes use too much ram and smaller
 /* This should be a 32 bit type, larger tyes use too much ram and smaller

+ 4 - 0
apt-pkg/contrib/netrc.h

@@ -16,6 +16,10 @@
 
 
 #include <string>
 #include <string>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/strutl.h>
+#endif
+
 #define DOT_CHAR "."
 #define DOT_CHAR "."
 #define DIR_CHAR "/"
 #define DIR_CHAR "/"
 
 

+ 4 - 0
apt-pkg/contrib/progress.h

@@ -25,6 +25,10 @@
 #include <string>
 #include <string>
 #include <sys/time.h>
 #include <sys/time.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+#endif
+
 class Configuration;
 class Configuration;
 class OpProgress
 class OpProgress
 {
 {

+ 5 - 0
apt-pkg/contrib/sha1.h

@@ -20,6 +20,11 @@
 
 
 #include "hashsum_template.h"
 #include "hashsum_template.h"
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+using std::min;
+#endif
+
 typedef  HashSumValue<160> SHA1SumValue;
 typedef  HashSumValue<160> SHA1SumValue;
 
 
 class SHA1Summation : public SummationImplementation
 class SHA1Summation : public SummationImplementation

+ 6 - 0
apt-pkg/contrib/strutl.h

@@ -27,6 +27,12 @@
 
 
 #include "macros.h"
 #include "macros.h"
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+using std::vector;
+using std::ostream;
+#endif
+
 bool UTF8ToCodeset(const char *codeset, const std::string &orig, std::string *dest);
 bool UTF8ToCodeset(const char *codeset, const std::string &orig, std::string *dest);
 char *_strstrip(char *String);
 char *_strstrip(char *String);
 char *_strtabexpand(char *String,size_t Len);
 char *_strtabexpand(char *String,size_t Len);

+ 14 - 18
apt-pkg/deb/debindexfile.cc

@@ -26,6 +26,8 @@
 #include <sys/stat.h>
 #include <sys/stat.h>
 									/*}}}*/
 									/*}}}*/
 
 
+using std::string;
+
 // SourcesIndex::debSourcesIndex - Constructor				/*{{{*/
 // SourcesIndex::debSourcesIndex - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -159,7 +161,7 @@ unsigned long debSourcesIndex::Size() const
    /* we need to ignore errors here; if the lists are absent, just return 0 */
    /* we need to ignore errors here; if the lists are absent, just return 0 */
    _error->PushToStack();
    _error->PushToStack();
 
 
-   FileFd f = FileFd (IndexFile("Sources"), FileFd::ReadOnlyGzip);
+   FileFd f = FileFd (IndexFile("Sources"), FileFd::ReadOnly, FileFd::Extension);
    if (!f.Failed())
    if (!f.Failed())
       size = f.Size();
       size = f.Size();
 
 
@@ -288,7 +290,7 @@ unsigned long debPackagesIndex::Size() const
    /* we need to ignore errors here; if the lists are absent, just return 0 */
    /* we need to ignore errors here; if the lists are absent, just return 0 */
    _error->PushToStack();
    _error->PushToStack();
 
 
-   FileFd f = FileFd (IndexFile("Packages"), FileFd::ReadOnlyGzip);
+   FileFd f = FileFd (IndexFile("Packages"), FileFd::ReadOnly, FileFd::Extension);
    if (!f.Failed())
    if (!f.Failed())
       size = f.Size();
       size = f.Size();
 
 
@@ -305,7 +307,7 @@ unsigned long debPackagesIndex::Size() const
 bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 {
 {
    string PackageFile = IndexFile("Packages");
    string PackageFile = IndexFile("Packages");
-   FileFd Pkg(PackageFile,FileFd::ReadOnlyGzip);
+   FileFd Pkg(PackageFile,FileFd::ReadOnly, FileFd::Extension);
    debListParser Parser(&Pkg, Architecture);
    debListParser Parser(&Pkg, Architecture);
 
 
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
@@ -319,11 +321,8 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
    // Store the IMS information
    // Store the IMS information
    pkgCache::PkgFileIterator File = Gen.GetCurFile();
    pkgCache::PkgFileIterator File = Gen.GetCurFile();
    pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(File);
    pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(File);
-   struct stat St;
-   if (fstat(Pkg.Fd(),&St) != 0)
-      return _error->Errno("fstat","Failed to stat");
-   File->Size = St.st_size;
-   File->mtime = St.st_mtime;
+   File->Size = Pkg.FileSize();
+   File->mtime = Pkg.ModificationTime();
    
    
    if (Gen.MergeList(Parser) == false)
    if (Gen.MergeList(Parser) == false)
       return _error->Error("Problem with MergeList %s",PackageFile.c_str());
       return _error->Error("Problem with MergeList %s",PackageFile.c_str());
@@ -489,7 +488,7 @@ unsigned long debTranslationsIndex::Size() const
    /* we need to ignore errors here; if the lists are absent, just return 0 */
    /* we need to ignore errors here; if the lists are absent, just return 0 */
    _error->PushToStack();
    _error->PushToStack();
 
 
-   FileFd f = FileFd (IndexFile(Language), FileFd::ReadOnlyGzip);
+   FileFd f = FileFd (IndexFile(Language), FileFd::ReadOnly, FileFd::Extension);
    if (!f.Failed())
    if (!f.Failed())
       size = f.Size();
       size = f.Size();
 
 
@@ -509,7 +508,7 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
    string TranslationFile = IndexFile(Language);
    string TranslationFile = IndexFile(Language);
    if (FileExists(TranslationFile))
    if (FileExists(TranslationFile))
    {
    {
-     FileFd Trans(TranslationFile,FileFd::ReadOnlyGzip);
+     FileFd Trans(TranslationFile,FileFd::ReadOnly, FileFd::Extension);
      debListParser TransParser(&Trans);
      debListParser TransParser(&Trans);
      if (_error->PendingError() == true)
      if (_error->PendingError() == true)
        return false;
        return false;
@@ -521,11 +520,8 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 
 
      // Store the IMS information
      // Store the IMS information
      pkgCache::PkgFileIterator TransFile = Gen.GetCurFile();
      pkgCache::PkgFileIterator TransFile = Gen.GetCurFile();
-     struct stat TransSt;
-     if (fstat(Trans.Fd(),&TransSt) != 0)
-       return _error->Errno("fstat","Failed to stat");
-     TransFile->Size = TransSt.st_size;
-     TransFile->mtime = TransSt.st_mtime;
+     TransFile->Size = Trans.FileSize();
+     TransFile->mtime = Trans.ModificationTime();
    
    
      if (Gen.MergeList(TransParser) == false)
      if (Gen.MergeList(TransParser) == false)
        return _error->Error("Problem with MergeList %s",TranslationFile.c_str());
        return _error->Error("Problem with MergeList %s",TranslationFile.c_str());
@@ -590,7 +586,7 @@ unsigned long debStatusIndex::Size() const
 /* */
 /* */
 bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 {
 {
-   FileFd Pkg(File,FileFd::ReadOnlyGzip);
+   FileFd Pkg(File,FileFd::ReadOnly, FileFd::Extension);
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return false;
       return false;
    debListParser Parser(&Pkg);
    debListParser Parser(&Pkg);
@@ -607,8 +603,8 @@ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
    struct stat St;
    struct stat St;
    if (fstat(Pkg.Fd(),&St) != 0)
    if (fstat(Pkg.Fd(),&St) != 0)
       return _error->Errno("fstat","Failed to stat");
       return _error->Errno("fstat","Failed to stat");
-   CFile->Size = St.st_size;
-   CFile->mtime = St.st_mtime;
+   CFile->Size = Pkg.FileSize();
+   CFile->mtime = Pkg.ModificationTime();
    CFile->Archive = Gen.WriteUniqString("now");
    CFile->Archive = Gen.WriteUniqString("now");
    
    
    if (Gen.MergeList(Parser) == false)
    if (Gen.MergeList(Parser) == false)

+ 1 - 0
apt-pkg/deb/deblistparser.cc

@@ -773,6 +773,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
    // file. to provide Component pinning we use the section name now
    // file. to provide Component pinning we use the section name now
    FileI->Component = WriteUniqString(component);
    FileI->Component = WriteUniqString(component);
 
 
+   // FIXME: Code depends on the fact that Release files aren't compressed
    FILE* release = fdopen(dup(File.Fd()), "r");
    FILE* release = fdopen(dup(File.Fd()), "r");
    if (release == NULL)
    if (release == NULL)
       return false;
       return false;

+ 4 - 0
apt-pkg/deb/deblistparser.h

@@ -14,6 +14,10 @@
 #include <apt-pkg/pkgcachegen.h>
 #include <apt-pkg/pkgcachegen.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/tagfile.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/indexfile.h>
+#endif
+
 class debListParser : public pkgCacheGenerator::ListParser
 class debListParser : public pkgCacheGenerator::ListParser
 {
 {
    public:
    public:

+ 4 - 0
apt-pkg/deb/debmetaindex.h

@@ -8,6 +8,10 @@
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/sourcelist.h>
+#endif
+
 class debReleaseIndex : public metaIndex {
 class debReleaseIndex : public metaIndex {
    public:
    public:
 
 

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

@@ -25,7 +25,7 @@ using std::string;
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
 debRecordParser::debRecordParser(string FileName,pkgCache &Cache) : 
 debRecordParser::debRecordParser(string FileName,pkgCache &Cache) : 
-                  File(FileName,FileFd::ReadOnlyGzip), 
+                  File(FileName,FileFd::ReadOnly, FileFd::Extension),
                   Tags(&File, std::max(Cache.Head().MaxVerFileSize, 
                   Tags(&File, std::max(Cache.Head().MaxVerFileSize, 
 				       Cache.Head().MaxDescFileSize) + 200)
 				       Cache.Head().MaxDescFileSize) + 200)
 {
 {

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

@@ -18,6 +18,10 @@
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/indexfile.h>
+#endif
+
 class debRecordParser : public pkgRecords::Parser
 class debRecordParser : public pkgRecords::Parser
 {
 {
    /** \brief dpointer placeholder (for later in case we need it) */
    /** \brief dpointer placeholder (for later in case we need it) */

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

@@ -50,7 +50,7 @@ class debSrcRecordParser : public pkgSrcRecords::Parser
    virtual bool Files(std::vector<pkgSrcRecords::File> &F);
    virtual bool Files(std::vector<pkgSrcRecords::File> &F);
 
 
    debSrcRecordParser(std::string const &File,pkgIndexFile const *Index) 
    debSrcRecordParser(std::string const &File,pkgIndexFile const *Index) 
-      : Parser(Index), Fd(File,FileFd::ReadOnlyGzip), Tags(&Fd,102400), 
+      : Parser(Index), Fd(File,FileFd::ReadOnly, FileFd::Extension), Tags(&Fd,102400), 
         Buffer(NULL) {}
         Buffer(NULL) {}
    virtual ~debSrcRecordParser();
    virtual ~debSrcRecordParser();
 };
 };

+ 5 - 0
apt-pkg/deb/dpkgpm.h

@@ -15,6 +15,11 @@
 #include <map>
 #include <map>
 #include <stdio.h>
 #include <stdio.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::vector;
+using std::map;
+#endif
+
 class pkgDPkgPMPrivate;
 class pkgDPkgPMPrivate;
 
 
 class pkgDPkgPM : public pkgPackageManager
 class pkgDPkgPM : public pkgPackageManager

+ 5 - 0
apt-pkg/depcache.h

@@ -46,6 +46,11 @@
 #include <set>
 #include <set>
 #include <list>
 #include <list>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/progress.h>
+#include <apt-pkg/error.h>
+#endif
+
 class OpProgress;
 class OpProgress;
 
 
 class pkgDepCache : protected pkgCache::Namespace
 class pkgDepCache : protected pkgCache::Namespace

+ 5 - 0
apt-pkg/edsp.h

@@ -15,6 +15,11 @@
 #include <list>
 #include <list>
 #include <string>
 #include <string>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/depcache.h>
+#include <apt-pkg/progress.h>
+#endif
+
 class pkgDepCache;
 class pkgDepCache;
 class OpProgress;
 class OpProgress;
 
 

+ 4 - 7
apt-pkg/edsp/edspindexfile.cc

@@ -24,7 +24,7 @@
 // edspIndex::edspIndex - Constructor					/*{{{*/
 // edspIndex::edspIndex - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-edspIndex::edspIndex(string File) : debStatusIndex(File)
+edspIndex::edspIndex(std::string File) : debStatusIndex(File)
 {
 {
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -44,16 +44,13 @@ bool edspIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
 
 
    if (Prog != NULL)
    if (Prog != NULL)
       Prog->SubProgress(0,File);
       Prog->SubProgress(0,File);
-   if (Gen.SelectFile(File,string(),*this) == false)
+   if (Gen.SelectFile(File,std::string(),*this) == false)
       return _error->Error("Problem with SelectFile %s",File.c_str());
       return _error->Error("Problem with SelectFile %s",File.c_str());
 
 
    // Store the IMS information
    // Store the IMS information
    pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
    pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
-   struct stat St;
-   if (fstat(Pkg.Fd(),&St) != 0)
-      return _error->Errno("fstat","Failed to stat");
-   CFile->Size = St.st_size;
-   CFile->mtime = St.st_mtime;
+   CFile->Size = Pkg.FileSize();
+   CFile->mtime = Pkg.ModificationTime();
    CFile->Archive = Gen.WriteUniqString("edsp::scenario");
    CFile->Archive = Gen.WriteUniqString("edsp::scenario");
 
 
    if (Gen.MergeList(Parser) == false)
    if (Gen.MergeList(Parser) == false)

+ 4 - 0
apt-pkg/edsp/edspindexfile.h

@@ -10,6 +10,10 @@
 
 
 #include <apt-pkg/debindexfile.h>
 #include <apt-pkg/debindexfile.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/indexfile.h>
+#endif
+
 class edspIndex : public debStatusIndex
 class edspIndex : public debStatusIndex
 {
 {
    /** \brief dpointer placeholder (for later in case we need it) */
    /** \brief dpointer placeholder (for later in case we need it) */

+ 6 - 0
apt-pkg/edsp/edsplistparser.h

@@ -13,6 +13,12 @@
 
 
 #include <apt-pkg/deblistparser.h>
 #include <apt-pkg/deblistparser.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/pkgcachegen.h>
+#include <apt-pkg/indexfile.h>
+#include <apt-pkg/tagfile.h>
+#endif
+
 class FileFd;
 class FileFd;
 
 
 class edspListParser : public debListParser
 class edspListParser : public debListParser

+ 59 - 116
apt-pkg/indexcopy.cc

@@ -16,6 +16,7 @@
 #include <apt-pkg/progress.h>
 #include <apt-pkg/progress.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
+#include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/indexrecords.h>
 #include <apt-pkg/indexrecords.h>
@@ -37,8 +38,6 @@
 
 
 using namespace std;
 using namespace std;
 
 
-
-
 // IndexCopy::CopyPackages - Copy the package files from the CD		/*{{{*/
 // IndexCopy::CopyPackages - Copy the package files from the CD		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -57,15 +56,25 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
    
    
    // Prepare the progress indicator
    // Prepare the progress indicator
    off_t TotalSize = 0;
    off_t TotalSize = 0;
+   std::vector<APT::Configuration::Compressor> const compressor = APT::Configuration::getCompressors();
    for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    {
    {
       struct stat Buf;
       struct stat Buf;
-      if (stat(string(*I + GetFileName()).c_str(),&Buf) != 0 &&
-	  stat(string(*I + GetFileName() + ".gz").c_str(),&Buf) != 0)
-	 return _error->Errno("stat","Stat failed for %s",
-			      string(*I + GetFileName()).c_str());
+      bool found = false;
+      std::string file = std::string(*I).append(GetFileName());
+      for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
+	   c != compressor.end(); ++c)
+      {
+	 if (stat(std::string(file + c->Extension).c_str(), &Buf) != 0)
+	    continue;
+	 found = true;
+	 break;
+      }
+
+      if (found == false)
+	 return _error->Errno("stat", "Stat failed for %s", file.c_str());
       TotalSize += Buf.st_size;
       TotalSize += Buf.st_size;
-   }	
+   }
 
 
    off_t CurrentSize = 0;
    off_t CurrentSize = 0;
    unsigned int NotFound = 0;
    unsigned int NotFound = 0;
@@ -74,57 +83,11 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
    for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    {      
    {      
       string OrigPath = string(*I,CDROM.length());
       string OrigPath = string(*I,CDROM.length());
-      off_t FileSize = 0;
       
       
       // Open the package file
       // Open the package file
-      FileFd Pkg;
-      if (RealFileExists(*I + GetFileName()) == true)
-      {
-	 Pkg.Open(*I + GetFileName(),FileFd::ReadOnly);
-	 FileSize = Pkg.Size();
-      }      
-      else
-      {
-	 FileFd From(*I + GetFileName() + ".gz",FileFd::ReadOnly);
-	 if (_error->PendingError() == true)
-	    return false;
-	 FileSize = From.Size();
-	 
-	 // Get a temp file
-	 FILE *tmp = tmpfile();
-	 if (tmp == 0)
-	    return _error->Errno("tmpfile","Unable to create a tmp file");
-	 Pkg.Fd(dup(fileno(tmp)));
-	 fclose(tmp);
-	 
-	 // Fork gzip
-	 pid_t Process = fork();
-	 if (Process < 0)
-	    return _error->Errno("fork","Couldn't fork gzip");
-	 
-	 // The child
-	 if (Process == 0)
-	 {	    
-	    dup2(From.Fd(),STDIN_FILENO);
-	    dup2(Pkg.Fd(),STDOUT_FILENO);
-	    SetCloseExec(STDIN_FILENO,false);
-	    SetCloseExec(STDOUT_FILENO,false);
-	    
-	    const char *Args[3];
-	    string Tmp =  _config->Find("Dir::bin::gzip","gzip");
-	    Args[0] = Tmp.c_str();
-	    Args[1] = "-d";
-	    Args[2] = 0;
-	    execvp(Args[0],(char **)Args);
-	    exit(100);
-	 }
-	 
-	 // Wait for gzip to finish
-	 if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false)
-	    return _error->Error("gzip failed, perhaps the disk is full.");
-	 
-	 Pkg.Seek(0);
-      }
+      FileFd Pkg(*I + GetFileName(), FileFd::ReadOnly, FileFd::Extension);
+      off_t const FileSize = Pkg.Size();
+
       pkgTagFile Parser(&Pkg);
       pkgTagFile Parser(&Pkg);
       if (_error->PendingError() == true)
       if (_error->PendingError() == true)
 	 return false;
 	 return false;
@@ -602,13 +565,19 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
 
 
       string const releasegpg = *I+"Release.gpg";
       string const releasegpg = *I+"Release.gpg";
       string const release = *I+"Release";
       string const release = *I+"Release";
+      string const inrelease = *I+"InRelease";
+      bool useInRelease = true;
 
 
       // a Release.gpg without a Release should never happen
       // a Release.gpg without a Release should never happen
-      if(RealFileExists(release) == false)
+      if (RealFileExists(inrelease) == true)
+	 ;
+      else if(RealFileExists(release) == false || RealFileExists(releasegpg) == false)
       {
       {
 	 delete MetaIndex;
 	 delete MetaIndex;
 	 continue;
 	 continue;
       }
       }
+      else
+	 useInRelease = false;
 
 
       pid_t pid = ExecFork();
       pid_t pid = ExecFork();
       if(pid < 0) {
       if(pid < 0) {
@@ -616,11 +585,16 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
 	 return false;
 	 return false;
       }
       }
       if(pid == 0)
       if(pid == 0)
-	 RunGPGV(release, releasegpg);
+      {
+	 if (useInRelease == true)
+	    RunGPGV(inrelease, inrelease);
+	 else
+	    RunGPGV(release, releasegpg);
+      }
 
 
       if(!ExecWait(pid, "gpgv")) {
       if(!ExecWait(pid, "gpgv")) {
 	 _error->Warning("Signature verification failed for: %s",
 	 _error->Warning("Signature verification failed for: %s",
-			 releasegpg.c_str());
+			 (useInRelease ? inrelease.c_str() : releasegpg.c_str()));
 	 // something went wrong, don't copy the Release.gpg
 	 // something went wrong, don't copy the Release.gpg
 	 // FIXME: delete any existing gpg file?
 	 // FIXME: delete any existing gpg file?
 	 continue;
 	 continue;
@@ -650,8 +624,13 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
       delete MetaIndex;
       delete MetaIndex;
    
    
       // everything was fine, copy the Release and Release.gpg file
       // everything was fine, copy the Release and Release.gpg file
-      CopyMetaIndex(CDROM, Name, prefix, "Release");
-      CopyMetaIndex(CDROM, Name, prefix, "Release.gpg");
+      if (useInRelease == true)
+	 CopyMetaIndex(CDROM, Name, prefix, "InRelease");
+      else
+      {
+	 CopyMetaIndex(CDROM, Name, prefix, "Release");
+	 CopyMetaIndex(CDROM, Name, prefix, "Release.gpg");
+      }
    }   
    }   
 
 
    return true;
    return true;
@@ -789,15 +768,25 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,	/*{{{*/
    
    
    // Prepare the progress indicator
    // Prepare the progress indicator
    off_t TotalSize = 0;
    off_t TotalSize = 0;
+   std::vector<APT::Configuration::Compressor> const compressor = APT::Configuration::getCompressors();
    for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    {
    {
       struct stat Buf;
       struct stat Buf;
-      if (stat(string(*I).c_str(),&Buf) != 0 &&
-	  stat(string(*I + ".gz").c_str(),&Buf) != 0)
-	 return _error->Errno("stat","Stat failed for %s",
-			      string(*I).c_str());
+      bool found = false;
+      std::string file = *I;
+      for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
+	   c != compressor.end(); ++c)
+      {
+	 if (stat(std::string(file + c->Extension).c_str(), &Buf) != 0)
+	    continue;
+	 found = true;
+	 break;
+      }
+
+      if (found == false)
+	 return _error->Errno("stat", "Stat failed for %s", file.c_str());
       TotalSize += Buf.st_size;
       TotalSize += Buf.st_size;
-   }	
+   }
 
 
    off_t CurrentSize = 0;
    off_t CurrentSize = 0;
    unsigned int NotFound = 0;
    unsigned int NotFound = 0;
@@ -806,57 +795,11 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,	/*{{{*/
    for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
    {      
    {      
       string OrigPath = string(*I,CDROM.length());
       string OrigPath = string(*I,CDROM.length());
-      off_t FileSize = 0;
-      
+
       // Open the package file
       // Open the package file
-      FileFd Pkg;
-      if (RealFileExists(*I) == true)
-      {
-	 Pkg.Open(*I,FileFd::ReadOnly);
-	 FileSize = Pkg.Size();
-      }      
-      else
-      {
-	 FileFd From(*I + ".gz",FileFd::ReadOnly);
-	 if (_error->PendingError() == true)
-	    return false;
-	 FileSize = From.Size();
-	 
-	 // Get a temp file
-	 FILE *tmp = tmpfile();
-	 if (tmp == 0)
-	    return _error->Errno("tmpfile","Unable to create a tmp file");
-	 Pkg.Fd(dup(fileno(tmp)));
-	 fclose(tmp);
-	 
-	 // Fork gzip
-	 pid_t Process = fork();
-	 if (Process < 0)
-	    return _error->Errno("fork","Couldn't fork gzip");
-	 
-	 // The child
-	 if (Process == 0)
-	 {	    
-	    dup2(From.Fd(),STDIN_FILENO);
-	    dup2(Pkg.Fd(),STDOUT_FILENO);
-	    SetCloseExec(STDIN_FILENO,false);
-	    SetCloseExec(STDOUT_FILENO,false);
-	    
-	    const char *Args[3];
-	    string Tmp =  _config->Find("Dir::bin::gzip","gzip");
-	    Args[0] = Tmp.c_str();
-	    Args[1] = "-d";
-	    Args[2] = 0;
-	    execvp(Args[0],(char **)Args);
-	    exit(100);
-	 }
-	 
-	 // Wait for gzip to finish
-	 if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false)
-	    return _error->Error("gzip failed, perhaps the disk is full.");
-	 
-	 Pkg.Seek(0);
-      }
+      FileFd Pkg(*I, FileFd::ReadOnly, FileFd::Extension);
+      off_t const FileSize = Pkg.Size();
+
       pkgTagFile Parser(&Pkg);
       pkgTagFile Parser(&Pkg);
       if (_error->PendingError() == true)
       if (_error->PendingError() == true)
 	 return false;
 	 return false;

+ 5 - 0
apt-pkg/indexcopy.h

@@ -14,6 +14,11 @@
 #include <string>
 #include <string>
 #include <stdio.h>
 #include <stdio.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+using std::vector;
+#endif
+
 class pkgTagSection;
 class pkgTagSection;
 class FileFd;
 class FileFd;
 class indexRecords;
 class indexRecords;

+ 4 - 0
apt-pkg/indexfile.h

@@ -29,6 +29,10 @@
 #include <apt-pkg/pkgrecords.h>
 #include <apt-pkg/pkgrecords.h>
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+#endif
+
 class pkgAcquire;
 class pkgAcquire;
 class pkgCacheGenerator;
 class pkgCacheGenerator;
 class OpProgress;
 class OpProgress;

+ 4 - 0
apt-pkg/indexrecords.h

@@ -13,6 +13,10 @@
 #include <vector>
 #include <vector>
 #include <ctime>
 #include <ctime>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/fileutl.h>
+#endif
+
 class indexRecords
 class indexRecords
 {
 {
    bool parseSumData(const char *&Start, const char *End, std::string &Name,
    bool parseSumData(const char *&Start, const char *End, std::string &Name,

+ 5 - 0
apt-pkg/init.h

@@ -13,6 +13,11 @@
 #ifndef PKGLIB_INIT_H
 #ifndef PKGLIB_INIT_H
 #define PKGLIB_INIT_H
 #define PKGLIB_INIT_H
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/pkgsystem.h>
+#endif
+
 class pkgSystem;
 class pkgSystem;
 class Configuration;
 class Configuration;
 
 

+ 7 - 0
apt-pkg/metaindex.h

@@ -6,6 +6,13 @@
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/indexfile.h>
 #include <apt-pkg/indexfile.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/vendor.h>
+using std::string;
+#endif
+
 class pkgAcquire;
 class pkgAcquire;
 class pkgCacheGenerator;
 class pkgCacheGenerator;
 class OpProgress;
 class OpProgress;

+ 5 - 0
apt-pkg/packagemanager.h

@@ -29,6 +29,11 @@
 #include <iostream>
 #include <iostream>
 #include <set>
 #include <set>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/depcache.h>
+using std::string;
+#endif
+
 class pkgAcquire;
 class pkgAcquire;
 class pkgDepCache;
 class pkgDepCache;
 class pkgSourceList;
 class pkgSourceList;

+ 4 - 1
apt-pkg/pkgcache.h

@@ -74,11 +74,14 @@
 #ifndef PKGLIB_PKGCACHE_H
 #ifndef PKGLIB_PKGCACHE_H
 #define PKGLIB_PKGCACHE_H
 #define PKGLIB_PKGCACHE_H
 
 
-
 #include <string>
 #include <string>
 #include <time.h>
 #include <time.h>
 #include <apt-pkg/mmap.h>
 #include <apt-pkg/mmap.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+#endif
+
 class pkgVersioningSystem;
 class pkgVersioningSystem;
 class pkgCache								/*{{{*/
 class pkgCache								/*{{{*/
 {
 {

+ 9 - 7
apt-pkg/pkgcachegen.cc

@@ -35,12 +35,14 @@
 
 
 #include <apti18n.h>
 #include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
-typedef vector<pkgIndexFile *>::iterator FileIterator;
+typedef std::vector<pkgIndexFile *>::iterator FileIterator;
 template <typename Iter> std::vector<Iter*> pkgCacheGenerator::Dynamic<Iter>::toReMap;
 template <typename Iter> std::vector<Iter*> pkgCacheGenerator::Dynamic<Iter>::toReMap;
 
 
 bool IsDuplicateDescription(pkgCache::DescIterator Desc,
 bool IsDuplicateDescription(pkgCache::DescIterator Desc,
 			    MD5SumValue const &CurMd5, std::string const &CurLang);
 			    MD5SumValue const &CurMd5, std::string const &CurLang);
 
 
+using std::string;
+
 // CacheGenerator::pkgCacheGenerator - Constructor			/*{{{*/
 // CacheGenerator::pkgCacheGenerator - Constructor			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* We set the dirty flag and make sure that is written to the disk */
 /* We set the dirty flag and make sure that is written to the disk */
@@ -1221,14 +1223,14 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
 			MMap **OutMap,bool AllowMem)
 			MMap **OutMap,bool AllowMem)
 {
 {
    bool const Debug = _config->FindB("Debug::pkgCacheGen", false);
    bool const Debug = _config->FindB("Debug::pkgCacheGen", false);
-   
-   vector<pkgIndexFile *> Files;
-   for (vector<metaIndex *>::const_iterator i = List.begin();
+
+   std::vector<pkgIndexFile *> Files;
+   for (std::vector<metaIndex *>::const_iterator i = List.begin();
         i != List.end();
         i != List.end();
         ++i)
         ++i)
    {
    {
-      vector <pkgIndexFile *> *Indexes = (*i)->GetIndexFiles();
-      for (vector<pkgIndexFile *>::const_iterator j = Indexes->begin();
+      std::vector <pkgIndexFile *> *Indexes = (*i)->GetIndexFiles();
+      for (std::vector<pkgIndexFile *>::const_iterator j = Indexes->begin();
 	   j != Indexes->end();
 	   j != Indexes->end();
 	   ++j)
 	   ++j)
          Files.push_back (*j);
          Files.push_back (*j);
@@ -1418,7 +1420,7 @@ __deprecated bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutM
    { return pkgCacheGenerator::MakeOnlyStatusCache(&Progress, OutMap); }
    { return pkgCacheGenerator::MakeOnlyStatusCache(&Progress, OutMap); }
 bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap)
 bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap)
 {
 {
-   vector<pkgIndexFile *> Files;
+   std::vector<pkgIndexFile *> Files;
    unsigned long EndOfSource = Files.size();
    unsigned long EndOfSource = Files.size();
    if (_system->AddStatusFiles(Files) == false)
    if (_system->AddStatusFiles(Files) == false)
       return false;
       return false;

+ 4 - 0
apt-pkg/pkgsystem.h

@@ -41,6 +41,10 @@
 
 
 #include <vector>
 #include <vector>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/depcache.h>
+#endif
+
 class pkgDepCache;
 class pkgDepCache;
 class pkgPackageManager;
 class pkgPackageManager;
 class pkgVersioningSystem;
 class pkgVersioningSystem;

+ 4 - 0
apt-pkg/policy.h

@@ -38,6 +38,10 @@
 #include <apt-pkg/versionmatch.h>
 #include <apt-pkg/versionmatch.h>
 #include <vector>
 #include <vector>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::vector;
+#endif
+
 class pkgPolicy : public pkgDepCache::Policy
 class pkgPolicy : public pkgDepCache::Policy
 {
 {
    protected:
    protected:

+ 15 - 13
apt-pkg/sourcelist.h

@@ -32,9 +32,11 @@
 #include <map>
 #include <map>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/metaindex.h>
 using std::string;
 using std::string;
 using std::vector;
 using std::vector;
-    
+#endif
 
 
 class pkgAcquire;
 class pkgAcquire;
 class pkgIndexFile;
 class pkgIndexFile;
@@ -57,32 +59,32 @@ class pkgSourceList
       const char *Name;
       const char *Name;
       const char *Label;
       const char *Label;
 
 
-      bool FixupURI(string &URI) const;
-      virtual bool ParseLine(vector<metaIndex *> &List,
+      bool FixupURI(std::string &URI) const;
+      virtual bool ParseLine(std::vector<metaIndex *> &List,
 			     const char *Buffer,
 			     const char *Buffer,
-			     unsigned long const &CurLine,string const &File) const;
-      virtual bool CreateItem(vector<metaIndex *> &List,string const &URI,
-			      string const &Dist,string const &Section,
-			      std::map<string, string> const &Options) const = 0;
+			     unsigned long const &CurLine,std::string const &File) const;
+      virtual bool CreateItem(std::vector<metaIndex *> &List,std::string const &URI,
+			      std::string const &Dist,std::string const &Section,
+			      std::map<std::string, std::string> const &Options) const = 0;
       Type();
       Type();
       virtual ~Type() {};
       virtual ~Type() {};
    };
    };
    
    
-   typedef vector<metaIndex *>::const_iterator const_iterator;
+   typedef std::vector<metaIndex *>::const_iterator const_iterator;
    
    
    protected:
    protected:
 
 
-   vector<metaIndex *> SrcList;
+   std::vector<metaIndex *> SrcList;
    
    
    public:
    public:
 
 
    bool ReadMainList();
    bool ReadMainList();
-   bool Read(string File);
+   bool Read(std::string File);
 
 
    // CNC:2003-03-03
    // CNC:2003-03-03
    void Reset();
    void Reset();
-   bool ReadAppend(string File);
-   bool ReadSourceDir(string Dir);
+   bool ReadAppend(std::string File);
+   bool ReadSourceDir(std::string Dir);
    
    
    // List accessors
    // List accessors
    inline const_iterator begin() const {return SrcList.begin();};
    inline const_iterator begin() const {return SrcList.begin();};
@@ -98,7 +100,7 @@ class pkgSourceList
    time_t GetLastModifiedTime();
    time_t GetLastModifiedTime();
 
 
    pkgSourceList();
    pkgSourceList();
-   pkgSourceList(string File);
+   pkgSourceList(std::string File);
    ~pkgSourceList();      
    ~pkgSourceList();      
 };
 };
 
 

+ 4 - 4
apt-pkg/srcrecords.cc

@@ -29,8 +29,8 @@ pkgSrcRecords::pkgSrcRecords(pkgSourceList &List) : Files(0), Current(0)
 {
 {
    for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); ++I)
    for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); ++I)
    {
    {
-      vector<pkgIndexFile *> *Indexes = (*I)->GetIndexFiles();
-      for (vector<pkgIndexFile *>::const_iterator J = Indexes->begin();
+      std::vector<pkgIndexFile *> *Indexes = (*I)->GetIndexFiles();
+      for (std::vector<pkgIndexFile *>::const_iterator J = Indexes->begin();
 	   J != Indexes->end(); ++J)
 	   J != Indexes->end(); ++J)
       {
       {
          Parser* P = (*J)->CreateSrcParser();
          Parser* P = (*J)->CreateSrcParser();
@@ -58,7 +58,7 @@ pkgSrcRecords::pkgSrcRecords(pkgSourceList &List) : Files(0), Current(0)
 pkgSrcRecords::~pkgSrcRecords()
 pkgSrcRecords::~pkgSrcRecords()
 {
 {
    // Blow away all the parser objects
    // Blow away all the parser objects
-   for(vector<Parser*>::iterator I = Files.begin(); I != Files.end(); ++I)
+   for(std::vector<Parser*>::iterator I = Files.begin(); I != Files.end(); ++I)
       delete *I;
       delete *I;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -68,7 +68,7 @@ pkgSrcRecords::~pkgSrcRecords()
 bool pkgSrcRecords::Restart()
 bool pkgSrcRecords::Restart()
 {
 {
    Current = Files.begin();
    Current = Files.begin();
-   for (vector<Parser*>::iterator I = Files.begin();
+   for (std::vector<Parser*>::iterator I = Files.begin();
         I != Files.end(); ++I)
         I != Files.end(); ++I)
       (*I)->Restart();
       (*I)->Restart();
    
    

+ 5 - 0
apt-pkg/srcrecords.h

@@ -17,6 +17,11 @@
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+using std::vector;
+#endif
+
 class pkgSourceList;
 class pkgSourceList;
 class pkgIndexFile;
 class pkgIndexFile;
 class pkgSrcRecords
 class pkgSrcRecords

+ 4 - 0
apt-pkg/tagfile.h

@@ -24,6 +24,10 @@
 
 
 #include <string>
 #include <string>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/fileutl.h>
+#endif
+
 class FileFd;
 class FileFd;
 
 
 class pkgTagSection
 class pkgTagSection

+ 4 - 0
apt-pkg/vendor.h

@@ -6,6 +6,10 @@
 
 
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+#endif
+
 // A class representing a particular software provider.
 // A class representing a particular software provider.
 class __deprecated Vendor
 class __deprecated Vendor
 {
 {

+ 7 - 0
apt-pkg/vendorlist.h

@@ -17,6 +17,13 @@
 #include <vector>
 #include <vector>
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+#include <apt-pkg/vendor.h>
+#include <apt-pkg/configuration.h>
+using std::string;
+using std::vector;
+#endif
+
 class Vendor;
 class Vendor;
 class Configuration;
 class Configuration;
 
 

+ 4 - 0
apt-pkg/version.h

@@ -23,6 +23,10 @@
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <string>
 #include <string>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+#endif
+
 class pkgVersioningSystem
 class pkgVersioningSystem
 {
 {
    public:
    public:

+ 4 - 0
apt-pkg/versionmatch.h

@@ -39,6 +39,10 @@
 #include <string>
 #include <string>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 
 
+#ifndef APT_8_CLEANER_HEADERS
+using std::string;
+#endif
+
 class pkgVersionMatch
 class pkgVersionMatch
 {   
 {   
    // Version Matching
    // Version Matching

+ 2 - 0
buildlib/config.h.in

@@ -44,3 +44,5 @@
 
 
 /* The package name string */
 /* The package name string */
 #undef PACKAGE
 #undef PACKAGE
+
+#define APT_8_CLEANER_HEADERS

+ 1 - 1
cmdline/apt-cache.cc

@@ -1143,7 +1143,7 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
       return _error->Error(_("Package file %s is out of sync."),I.FileName());
       return _error->Error(_("Package file %s is out of sync."),I.FileName());
 
 
    FileFd PkgF;
    FileFd PkgF;
-   if (PkgF.Open(I.FileName(), FileFd::ReadOnlyGzip) == false)
+   if (PkgF.Open(I.FileName(), FileFd::ReadOnly, FileFd::Extension) == false)
       return false;
       return false;
 
 
    // Read the record
    // Read the record

+ 16 - 0
cmdline/apt-config.cc

@@ -134,6 +134,22 @@ int main(int argc,const char *argv[])					/*{{{*/
    for (std::vector<std::string>::const_iterator a = archs.begin(); a != archs.end(); ++a)
    for (std::vector<std::string>::const_iterator a = archs.begin(); a != archs.end(); ++a)
       _config->Set("APT::Architectures::", *a);
       _config->Set("APT::Architectures::", *a);
 
 
+   std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors();
+   _config->Clear("APT::Compressor");
+   string conf = "APT::Compressor::";
+   for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressors.begin(); c != compressors.end(); ++c)
+   {
+      string comp = conf + c->Name + "::";
+      _config->Set(comp + "Name", c->Name);
+      _config->Set(comp + "Extension", c->Extension);
+      _config->Set(comp + "Binary", c->Binary);
+      _config->Set(std::string(comp + "Cost").c_str(), c->Cost);
+      for (std::vector<std::string>::const_iterator a = c->CompressArgs.begin(); a != c->CompressArgs.end(); ++a)
+	 _config->Set(comp + "CompressArg::", *a);
+      for (std::vector<std::string>::const_iterator a = c->UncompressArgs.begin(); a != c->UncompressArgs.end(); ++a)
+	 _config->Set(comp + "UncompressArg::", *a);
+   }
+
    // Match the operation
    // Match the operation
    CmdL.DispatchArg(Cmds);
    CmdL.DispatchArg(Cmds);
    
    

+ 6 - 4
cmdline/apt-extracttemplates.h

@@ -14,6 +14,8 @@
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/dirstream.h>
 #include <apt-pkg/dirstream.h>
 
 
+#include <string>
+
 class DebFile : public pkgDirStream
 class DebFile : public pkgDirStream
 {
 {
 	FileFd File;
 	FileFd File;
@@ -31,11 +33,11 @@ public:
 	bool Go();
 	bool Go();
 	bool ParseInfo();
 	bool ParseInfo();
 
 
-	static string GetInstalledVer(const string &package);
+	static std::string GetInstalledVer(const std::string &package);
 
 
-	string Package;
-	string Version;
-	string DepVer, PreDepVer;
+	std::string Package;
+	std::string Version;
+	std::string DepVer, PreDepVer;
 	unsigned int DepOp, PreDepOp;
 	unsigned int DepOp, PreDepOp;
 
 
 	char *Config;
 	char *Config;

+ 14 - 12
debian/changelog

@@ -3,14 +3,14 @@ apt (0.8.16~exp9) UNRELEASED; urgency=low
   [ Julian Andres Klode ]
   [ Julian Andres Klode ]
   * apt-pkg/cdrom.cc:
   * apt-pkg/cdrom.cc:
     - Accept .bz2, .xz files in addition to .gz files (Closes: #649451)
     - Accept .bz2, .xz files in addition to .gz files (Closes: #649451)
-  
+
   [ Michael Vogt ]
   [ Michael Vogt ]
   * apt-pkg/cdrom.cc:
   * apt-pkg/cdrom.cc:
     - use aptconfiguration to get the supported compression types
     - use aptconfiguration to get the supported compression types
   * debian/control:
   * debian/control:
     - bump debhelper build-dep to debhelper (>= 8.1.3~)
     - bump debhelper build-dep to debhelper (>= 8.1.3~)
     - set libapt-pkg-dev to multi-arch: same too
     - set libapt-pkg-dev to multi-arch: same too
- 
+
   [ Colin Watson ]
   [ Colin Watson ]
   * Convert libapt-pkg4.12 and libapt-inst1.4 to Multi-Arch: same.
   * Convert libapt-pkg4.12 and libapt-inst1.4 to Multi-Arch: same.
 
 
@@ -27,12 +27,22 @@ apt (0.8.16~exp9) UNRELEASED; urgency=low
   * cmdline/apt-get.cc:
   * cmdline/apt-get.cc:
     - ignore foreign architectures if we check if a provides has only one
     - ignore foreign architectures if we check if a provides has only one
       resolver as it's basically the same for the user, so no need to choose
       resolver as it's basically the same for the user, so no need to choose
-  
- -- Julian Andres Klode <jak@debian.org>  Mon, 21 Nov 2011 18:46:36 +0100
+  * cmdline/apt-config.cc:
+    - dump the APT::Compressor settings correctly and completely
+  * apt-pkg/contrib/fileutl.{h,cc}:
+    - implement a ModificationTime method for FileFd
+    - add a ReadLine method
+    - drop the explicit export of gz-compression handling
+  * apt-pkg/cdrom.cc:
+    - support InRelease files on cdrom
+
+ -- David Kalnischkies <kalnischkies@gmail.com>  Sun, 11 Dec 2011 19:34:58 +0100
 
 
 apt (0.8.16~exp8) experimental; urgency=low
 apt (0.8.16~exp8) experimental; urgency=low
 
 
   [ David Kalnischkies ]
   [ David Kalnischkies ]
+  * algorithms.cc:
+    - show a debug why a package was kept by ResolveByKeep()
   * apt-pkg/packagemanager.cc:
   * apt-pkg/packagemanager.cc:
     - do not fail on unpacked packages in SmartUnPack, just don't
     - do not fail on unpacked packages in SmartUnPack, just don't
       shedule them for unpack, but do all checks and configure them
       shedule them for unpack, but do all checks and configure them
@@ -228,14 +238,6 @@ apt (0.8.16~exp1) experimental; urgency=low
 
 
  -- Michael Vogt <mvo@debian.org>  Wed, 29 Jun 2011 12:40:31 +0200
  -- Michael Vogt <mvo@debian.org>  Wed, 29 Jun 2011 12:40:31 +0200
 
 
-apt (1.8.15.9+nmu1) unstable; urgency=low
-
-  [ David Kalnischkies ]
-  * algorithms.cc:
-    - show a debug why a package was kept by ResolveByKeep()
-
- -- David Kalnischkies <kalnischkies@gmail.com>  Mon, 17 Oct 2011 16:36:22 +0200
-
 apt (0.8.15.9) unstable; urgency=low
 apt (0.8.15.9) unstable; urgency=low
 
 
   [ David Kalnischkies ]
   [ David Kalnischkies ]

+ 13 - 127
ftparchive/multicompress.cc

@@ -16,6 +16,7 @@
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
 #include <config.h>
 #include <config.h>
 
 
+#include <apt-pkg/fileutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/md5.h>
@@ -90,7 +91,7 @@ MultiCompress::MultiCompress(string const &Output,string const &Compress,
    /* Open all the temp files now so we can report any errors. File is 
    /* Open all the temp files now so we can report any errors. File is 
       made unreable to prevent people from touching it during creating. */
       made unreable to prevent people from touching it during creating. */
    for (Files *I = Outputs; I != 0; I = I->Next)
    for (Files *I = Outputs; I != 0; I = I->Next)
-      I->TmpFile.Open(I->Output + ".new",FileFd::WriteEmpty,0600);
+      I->TmpFile.Open(I->Output + ".new", FileFd::WriteOnly | FileFd::Create | FileFd::Empty, FileFd::Extension, 0600);
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return;
       return;
 
 
@@ -182,11 +183,6 @@ bool MultiCompress::Start()
       _exit(0);
       _exit(0);
    };
    };
 
 
-   /* Tidy up the temp files, we open them in the constructor so as to
-      get proper error reporting. Close them now. */
-   for (Files *I = Outputs; I != 0; I = I->Next)
-      I->TmpFile.Close();
-   
    close(Pipe[0]);
    close(Pipe[0]);
    Input = fdopen(Pipe[1],"w");
    Input = fdopen(Pipe[1],"w");
    if (Input == 0)
    if (Input == 0)
@@ -261,77 +257,10 @@ bool MultiCompress::Finalize(unsigned long long &OutSize)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// MultiCompress::OpenCompress - Open the compressor			/*{{{*/
-// ---------------------------------------------------------------------
-/* This opens the compressor, either in compress mode or decompress 
-   mode. FileFd is always the compressor input/output file, 
-   OutFd is the created pipe, Input for Compress, Output for Decompress. */
-bool MultiCompress::OpenCompress(APT::Configuration::Compressor const &Prog,
-				 pid_t &Pid,int const &FileFd,int &OutFd,bool const &Comp)
-{
-   Pid = -1;
-   
-   // No compression
-   if (Prog.Binary.empty() == true)
-   {
-      OutFd = dup(FileFd);
-      return true;
-   }
-      
-   // Create a data pipe
-   int Pipe[2] = {-1,-1};
-   if (pipe(Pipe) != 0)
-      return _error->Errno("pipe",_("Failed to create subprocess IPC"));
-   for (int J = 0; J != 2; J++)
-      SetCloseExec(Pipe[J],true);
-
-   if (Comp == true)
-      OutFd = Pipe[1];
-   else
-      OutFd = Pipe[0];
-   
-   // The child..
-   Pid = ExecFork();
-   if (Pid == 0)
-   {
-      if (Comp == true)
-      {
-	 dup2(FileFd,STDOUT_FILENO);
-	 dup2(Pipe[0],STDIN_FILENO);
-      }   
-      else
-      {
-	 dup2(FileFd,STDIN_FILENO);
-	 dup2(Pipe[1],STDOUT_FILENO);
-      }
-      
-      SetCloseExec(STDOUT_FILENO,false);
-      SetCloseExec(STDIN_FILENO,false);
-
-      std::vector<char const*> Args;
-      Args.push_back(Prog.Binary.c_str());
-      std::vector<std::string> const * const addArgs =
-		(Comp == true) ? &(Prog.CompressArgs) : &(Prog.UncompressArgs);
-      for (std::vector<std::string>::const_iterator a = addArgs->begin();
-	   a != addArgs->end(); ++a)
-	 Args.push_back(a->c_str());
-      Args.push_back(NULL);
-
-      execvp(Args[0],(char **)&Args[0]);
-      cerr << _("Failed to exec compressor ") << Args[0] << endl;
-      _exit(100);
-   };      
-   if (Comp == true)
-      close(Pipe[0]);
-   else
-      close(Pipe[1]);
-   return true;
-}
-									/*}}}*/
 // MultiCompress::OpenOld - Open an old file				/*{{{*/
 // MultiCompress::OpenOld - Open an old file				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This opens one of the original output files, possibly decompressing it. */
 /* This opens one of the original output files, possibly decompressing it. */
-bool MultiCompress::OpenOld(int &Fd,pid_t &Proc)
+bool MultiCompress::OpenOld(FileFd &Fd)
 {
 {
    Files *Best = Outputs;
    Files *Best = Outputs;
    for (Files *I = Outputs; I != 0; I = I->Next)
    for (Files *I = Outputs; I != 0; I = I->Next)
@@ -339,29 +268,9 @@ bool MultiCompress::OpenOld(int &Fd,pid_t &Proc)
 	 Best = I;
 	 Best = I;
 
 
    // Open the file
    // Open the file
-   FileFd F(Best->Output,FileFd::ReadOnly);
-   if (_error->PendingError() == true)
-      return false;
-   
-   // Decompress the file so we can read it
-   if (OpenCompress(Best->CompressProg,Proc,F.Fd(),Fd,false) == false)
-      return false;
-   
-   return true;
+   return Fd.Open(Best->Output, FileFd::ReadOnly, FileFd::Extension);
 }
 }
 									/*}}}*/
 									/*}}}*/
-// MultiCompress::CloseOld - Close the old file				/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool MultiCompress::CloseOld(int Fd,pid_t Proc)
-{
-   close(Fd);
-   if (Proc != -1)
-      if (ExecWait(Proc,_("decompressor"),false) == false)
-	 return false;
-   return true;
-}   
-									/*}}}*/
 // MultiCompress::Child - The writer child				/*{{{*/
 // MultiCompress::Child - The writer child				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The child process forks a bunch of compression children and takes 
 /* The child process forks a bunch of compression children and takes 
@@ -371,14 +280,6 @@ bool MultiCompress::CloseOld(int Fd,pid_t Proc)
    is new then the temp files are renamed, otherwise they are erased. */
    is new then the temp files are renamed, otherwise they are erased. */
 bool MultiCompress::Child(int const &FD)
 bool MultiCompress::Child(int const &FD)
 {
 {
-   // Start the compression children.
-   for (Files *I = Outputs; I != 0; I = I->Next)
-   {
-      if (OpenCompress(I->CompressProg,I->CompressProc,I->TmpFile.Fd(),
-		       I->Fd,true) == false)
-	 return false;      
-   }
-
    /* Okay, now we just feed data from FD to all the other FDs. Also
    /* Okay, now we just feed data from FD to all the other FDs. Also
       stash a hash of the data to use later. */
       stash a hash of the data to use later. */
    SetNonBlock(FD,false);
    SetNonBlock(FD,false);
@@ -398,25 +299,14 @@ bool MultiCompress::Child(int const &FD)
       FileSize += Res;
       FileSize += Res;
       for (Files *I = Outputs; I != 0; I = I->Next)
       for (Files *I = Outputs; I != 0; I = I->Next)
       {
       {
-	 if (write(I->Fd,Buffer,Res) != Res)
+	 if (I->TmpFile.Write(Buffer, Res) == false)
 	 {
 	 {
 	    _error->Errno("write",_("IO to subprocess/file failed"));
 	    _error->Errno("write",_("IO to subprocess/file failed"));
 	    break;
 	    break;
 	 }
 	 }
       }      
       }      
    }   
    }   
-   
-   // Close all the writers
-   for (Files *I = Outputs; I != 0; I = I->Next)
-      close(I->Fd);
-   
-   // Wait for the compressors to exit
-   for (Files *I = Outputs; I != 0; I = I->Next)
-   {
-      if (I->CompressProc != -1)
-	 ExecWait(I->CompressProc, I->CompressProg.Binary.c_str(), false);
-   }
-   
+
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return false;
       return false;
    
    
@@ -435,31 +325,27 @@ bool MultiCompress::Child(int const &FD)
    // Check the MD5 of the lowest cost entity.
    // Check the MD5 of the lowest cost entity.
    while (Missing == false)
    while (Missing == false)
    {
    {
-      int CompFd = -1;
-      pid_t Proc = -1;
-      if (OpenOld(CompFd,Proc) == false)
+      FileFd CompFd;
+      if (OpenOld(CompFd) == false)
       {
       {
 	 _error->Discard();
 	 _error->Discard();
 	 break;
 	 break;
       }
       }
-            
+
       // Compute the hash
       // Compute the hash
       MD5Summation OldMD5;
       MD5Summation OldMD5;
       unsigned long long NewFileSize = 0;
       unsigned long long NewFileSize = 0;
       while (1)
       while (1)
       {
       {
-	 int Res = read(CompFd,Buffer,sizeof(Buffer));
+	 unsigned long long Res = 0;
+	 if (CompFd.Read(Buffer,sizeof(Buffer), &Res) == false)
+	    return _error->Errno("read",_("Failed to read while computing MD5"));
 	 if (Res == 0)
 	 if (Res == 0)
 	    break;
 	    break;
-	 if (Res < 0)
-	    return _error->Errno("read",_("Failed to read while computing MD5"));
 	 NewFileSize += Res;
 	 NewFileSize += Res;
 	 OldMD5.Add(Buffer,Res);
 	 OldMD5.Add(Buffer,Res);
       }
       }
-      
-      // Tidy the compressor
-      if (CloseOld(CompFd,Proc) == false)
-	 return false;
+      CompFd.Close();
 
 
       // Check the hash
       // Check the hash
       if (OldMD5.Result() == MD5.Result() &&
       if (OldMD5.Result() == MD5.Result() &&

+ 1 - 5
ftparchive/multicompress.h

@@ -34,15 +34,12 @@ class MultiCompress
       FileFd TmpFile;
       FileFd TmpFile;
       pid_t CompressProc;
       pid_t CompressProc;
       time_t OldMTime;
       time_t OldMTime;
-      int Fd;
    };
    };
    
    
    Files *Outputs;
    Files *Outputs;
    pid_t Outputter;
    pid_t Outputter;
    mode_t Permissions;
    mode_t Permissions;
 
 
-   bool OpenCompress(APT::Configuration::Compressor const &Prog,
-		     pid_t &Pid,int const &FileFd, int &OutFd,bool const &Comp);
    bool Child(int const &Fd);
    bool Child(int const &Fd);
    bool Start();
    bool Start();
    bool Die();
    bool Die();
@@ -54,8 +51,7 @@ class MultiCompress
    unsigned long UpdateMTime;
    unsigned long UpdateMTime;
    
    
    bool Finalize(unsigned long long &OutSize);
    bool Finalize(unsigned long long &OutSize);
-   bool OpenOld(int &Fd,pid_t &Proc);
-   bool CloseOld(int Fd,pid_t Proc);
+   bool OpenOld(FileFd &Fd);
    static bool GetStat(std::string const &Output,std::string const &Compress,struct stat &St);
    static bool GetStat(std::string const &Output,std::string const &Compress,struct stat &St);
    
    
    MultiCompress(std::string const &Output,std::string const &Compress,
    MultiCompress(std::string const &Output,std::string const &Compress,

+ 8 - 15
ftparchive/writer.cc

@@ -889,22 +889,16 @@ bool ContentsWriter::ReadFromPkgs(string const &PkgFile,string const &PkgCompres
    MultiCompress Pkgs(PkgFile,PkgCompress,0,false);
    MultiCompress Pkgs(PkgFile,PkgCompress,0,false);
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return false;
       return false;
-   
+
    // Open the package file
    // Open the package file
-   int CompFd = -1;
-   pid_t Proc = -1;
-   if (Pkgs.OpenOld(CompFd,Proc) == false)
+   FileFd Fd;
+   if (Pkgs.OpenOld(Fd) == false)
       return false;
       return false;
-   
-   // No auto-close FD
-   FileFd Fd(CompFd,false);   
+
    pkgTagFile Tags(&Fd);
    pkgTagFile Tags(&Fd);
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
-   {
-      Pkgs.CloseOld(CompFd,Proc);
       return false;
       return false;
-   }
-   
+
    // Parse.
    // Parse.
    pkgTagSection Section;
    pkgTagSection Section;
    while (Tags.Step(Section) == true)
    while (Tags.Step(Section) == true)
@@ -926,11 +920,10 @@ bool ContentsWriter::ReadFromPkgs(string const &PkgFile,string const &PkgCompres
 	 _error->DumpErrors();
 	 _error->DumpErrors();
       }
       }
    }
    }
-   
+
    // Tidy the compressor
    // Tidy the compressor
-   if (Pkgs.CloseOld(CompFd,Proc) == false)
-      return false;
-   
+   Fd.Close();
+
    return true;
    return true;
 }
 }
 
 

+ 1 - 1
methods/gzip.cc

@@ -48,7 +48,7 @@ bool GzipMethod::Fetch(FetchItem *Itm)
    URIStart(Res);
    URIStart(Res);
    
    
    // Open the source and destination files
    // Open the source and destination files
-   FileFd From(Path,FileFd::ReadOnlyGzip);
+   FileFd From(Path,FileFd::ReadOnly, FileFd::Gzip);
 
 
    if(From.FileSize() == 0)
    if(From.FileSize() == 0)
       return _error->Error(_("Empty files can't be valid archives"));
       return _error->Error(_("Empty files can't be valid archives"));

+ 15 - 29
methods/rred.cc

@@ -37,13 +37,13 @@ class RredMethod : public pkgAcqMethod {
 	// return values
 	// return values
 	enum State {ED_OK, ED_ORDERING, ED_PARSER, ED_FAILURE, MMAP_FAILED};
 	enum State {ED_OK, ED_ORDERING, ED_PARSER, ED_FAILURE, MMAP_FAILED};
 
 
-	State applyFile(gzFile &ed_cmds, FILE *in_file, FILE *out_file,
+	State applyFile(FileFd &ed_cmds, FILE *in_file, FILE *out_file,
 	             unsigned long &line, char *buffer, Hashes *hash) const;
 	             unsigned long &line, char *buffer, Hashes *hash) const;
 	void ignoreLineInFile(FILE *fin, char *buffer) const;
 	void ignoreLineInFile(FILE *fin, char *buffer) const;
-	void ignoreLineInFile(gzFile &fin, char *buffer) const;
+	void ignoreLineInFile(FileFd &fin, char *buffer) const;
 	void copyLinesFromFileToFile(FILE *fin, FILE *fout, unsigned int lines,
 	void copyLinesFromFileToFile(FILE *fin, FILE *fout, unsigned int lines,
 	                            Hashes *hash, char *buffer) const;
 	                            Hashes *hash, char *buffer) const;
-	void copyLinesFromFileToFile(gzFile &fin, FILE *fout, unsigned int lines,
+	void copyLinesFromFileToFile(FileFd &fin, FILE *fout, unsigned int lines,
 	                            Hashes *hash, char *buffer) const;
 	                            Hashes *hash, char *buffer) const;
 
 
 	State patchFile(FileFd &Patch, FileFd &From, FileFd &out_file, Hashes *hash) const;
 	State patchFile(FileFd &Patch, FileFd &From, FileFd &out_file, Hashes *hash) const;
@@ -72,10 +72,10 @@ public:
  *  \param hash the created file for correctness
  *  \param hash the created file for correctness
  *  \return the success State of the ed command executor
  *  \return the success State of the ed command executor
  */
  */
-RredMethod::State RredMethod::applyFile(gzFile &ed_cmds, FILE *in_file, FILE *out_file,
+RredMethod::State RredMethod::applyFile(FileFd &ed_cmds, FILE *in_file, FILE *out_file,
 			unsigned long &line, char *buffer, Hashes *hash) const {
 			unsigned long &line, char *buffer, Hashes *hash) const {
 	// get the current command and parse it
 	// get the current command and parse it
-	if (gzgets(ed_cmds, buffer, BUF_SIZE) == NULL) {
+	if (ed_cmds.ReadLine(buffer, BUF_SIZE) == NULL) {
 		if (Debug == true)
 		if (Debug == true)
 			std::clog << "rred: encounter end of file - we can start patching now." << std::endl;
 			std::clog << "rred: encounter end of file - we can start patching now." << std::endl;
 		line = 0;
 		line = 0;
@@ -130,7 +130,7 @@ RredMethod::State RredMethod::applyFile(gzFile &ed_cmds, FILE *in_file, FILE *ou
 	unsigned char mode = *idx;
 	unsigned char mode = *idx;
 
 
 	// save the current position
 	// save the current position
-	unsigned const long pos = gztell(ed_cmds);
+	unsigned const long long pos = ed_cmds.Tell();
 
 
 	// if this is add or change then go to the next full stop
 	// if this is add or change then go to the next full stop
 	unsigned int data_length = 0;
 	unsigned int data_length = 0;
@@ -164,7 +164,7 @@ RredMethod::State RredMethod::applyFile(gzFile &ed_cmds, FILE *in_file, FILE *ou
 
 
 	// include data from ed script
 	// include data from ed script
 	if (mode == MODE_CHANGED || mode == MODE_ADDED) {
 	if (mode == MODE_CHANGED || mode == MODE_ADDED) {
-		gzseek(ed_cmds, pos, SEEK_SET);
+		ed_cmds.Seek(pos);
 		copyLinesFromFileToFile(ed_cmds, out_file, data_length, hash, buffer);
 		copyLinesFromFileToFile(ed_cmds, out_file, data_length, hash, buffer);
 	}
 	}
 
 
@@ -190,11 +190,11 @@ void RredMethod::copyLinesFromFileToFile(FILE *fin, FILE *fout, unsigned int lin
 	}
 	}
 }
 }
 										/*}}}*/
 										/*}}}*/
-void RredMethod::copyLinesFromFileToFile(gzFile &fin, FILE *fout, unsigned int lines,/*{{{*/
+void RredMethod::copyLinesFromFileToFile(FileFd &fin, FILE *fout, unsigned int lines,/*{{{*/
 					Hashes *hash, char *buffer) const {
 					Hashes *hash, char *buffer) const {
 	while (0 < lines--) {
 	while (0 < lines--) {
 		do {
 		do {
-			gzgets(fin, buffer, BUF_SIZE);
+			fin.ReadLine(buffer, BUF_SIZE);
 			size_t const written = fwrite(buffer, 1, strlen(buffer), fout);
 			size_t const written = fwrite(buffer, 1, strlen(buffer), fout);
 			hash->Add((unsigned char*)buffer, written);
 			hash->Add((unsigned char*)buffer, written);
 		} while (strlen(buffer) == (BUF_SIZE - 1) &&
 		} while (strlen(buffer) == (BUF_SIZE - 1) &&
@@ -211,11 +211,11 @@ void RredMethod::ignoreLineInFile(FILE *fin, char *buffer) const {		/*{{{*/
 	}
 	}
 }
 }
 										/*}}}*/
 										/*}}}*/
-void RredMethod::ignoreLineInFile(gzFile &fin, char *buffer) const {		/*{{{*/
-	gzgets(fin, buffer, BUF_SIZE);
+void RredMethod::ignoreLineInFile(FileFd &fin, char *buffer) const {		/*{{{*/
+	fin.ReadLine(buffer, BUF_SIZE);
 	while (strlen(buffer) == (BUF_SIZE - 1) &&
 	while (strlen(buffer) == (BUF_SIZE - 1) &&
 	       buffer[BUF_SIZE - 2] != '\n') {
 	       buffer[BUF_SIZE - 2] != '\n') {
-		gzgets(fin, buffer, BUF_SIZE);
+		fin.ReadLine(buffer, BUF_SIZE);
 		buffer[0] = ' ';
 		buffer[0] = ' ';
 	}
 	}
 }
 }
@@ -224,12 +224,11 @@ RredMethod::State RredMethod::patchFile(FileFd &Patch, FileFd &From,		/*{{{*/
 					FileFd &out_file, Hashes *hash) const {
 					FileFd &out_file, Hashes *hash) const {
    char buffer[BUF_SIZE];
    char buffer[BUF_SIZE];
    FILE* fFrom = fdopen(From.Fd(), "r");
    FILE* fFrom = fdopen(From.Fd(), "r");
-   gzFile fPatch = Patch.gzFd();
    FILE* fTo = fdopen(out_file.Fd(), "w");
    FILE* fTo = fdopen(out_file.Fd(), "w");
 
 
    /* we do a tail recursion to read the commands in the right order */
    /* we do a tail recursion to read the commands in the right order */
    unsigned long line = -1; // assign highest possible value
    unsigned long line = -1; // assign highest possible value
-   State const result = applyFile(fPatch, fFrom, fTo, line, buffer, hash);
+   State const result = applyFile(Patch, fFrom, fTo, line, buffer, hash);
    
    
    /* read the rest from infile */
    /* read the rest from infile */
    if (result == ED_OK) {
    if (result == ED_OK) {
@@ -258,20 +257,7 @@ struct EdCommand {
 RredMethod::State RredMethod::patchMMap(FileFd &Patch, FileFd &From,		/*{{{*/
 RredMethod::State RredMethod::patchMMap(FileFd &Patch, FileFd &From,		/*{{{*/
 					FileFd &out_file, Hashes *hash) const {
 					FileFd &out_file, Hashes *hash) const {
 #ifdef _POSIX_MAPPED_FILES
 #ifdef _POSIX_MAPPED_FILES
-	MMap ed_cmds(MMap::ReadOnly);
-	if (Patch.gzFd() != NULL) {
-		unsigned long long mapSize = Patch.Size();
-		DynamicMMap* dyn = new DynamicMMap(0, mapSize, 0);
-		if (dyn->validData() == false) {
-			delete dyn;
-			return MMAP_FAILED;
-		}
-		dyn->AddSize(mapSize);
-		gzread(Patch.gzFd(), dyn->Data(), mapSize);
-		ed_cmds = *dyn;
-	} else
-		ed_cmds = MMap(Patch, MMap::ReadOnly);
-
+	MMap ed_cmds(Patch, MMap::ReadOnly);
 	MMap in_file(From, MMap::ReadOnly);
 	MMap in_file(From, MMap::ReadOnly);
 
 
 	if (ed_cmds.Size() == 0 || in_file.Size() == 0)
 	if (ed_cmds.Size() == 0 || in_file.Size() == 0)
@@ -489,7 +475,7 @@ bool RredMethod::Fetch(FetchItem *Itm)						/*{{{*/
    // Open the source and destination files (the d'tor of FileFd will do 
    // Open the source and destination files (the d'tor of FileFd will do 
    // the cleanup/closing of the fds)
    // the cleanup/closing of the fds)
    FileFd From(Path,FileFd::ReadOnly);
    FileFd From(Path,FileFd::ReadOnly);
-   FileFd Patch(Path+".ed",FileFd::ReadOnlyGzip);
+   FileFd Patch(Path+".ed",FileFd::ReadOnly, FileFd::Gzip);
    FileFd To(Itm->DestFile,FileFd::WriteAtomic);   
    FileFd To(Itm->DestFile,FileFd::WriteAtomic);   
    To.EraseOnFailure();
    To.EraseOnFailure();
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)

+ 1 - 1
test/integration/framework

@@ -102,7 +102,7 @@ aptitude() {
 
 
 addtrap() {
 addtrap() {
 	CURRENTTRAP="$CURRENTTRAP $1"
 	CURRENTTRAP="$CURRENTTRAP $1"
-	trap "$CURRENTTRAP" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
+	trap "$CURRENTTRAP exit;" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
 }
 }
 
 
 setupenvironment() {
 setupenvironment() {

+ 86 - 0
test/libapt/cdromfindpackages_test.cc

@@ -0,0 +1,86 @@
+#include <apt-pkg/cdrom.h>
+#include <apt-pkg/error.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "assert.h"
+
+class Cdrom : public pkgCdrom {
+	public:
+	bool FindPackages(std::string const &CD,
+			  std::vector<std::string> &List,
+			  std::vector<std::string> &SList,
+			  std::vector<std::string> &SigList,
+			  std::vector<std::string> &TransList,
+			  std::string &InfoDir) {
+		bool const result = pkgCdrom::FindPackages(CD, List, SList, SigList, TransList, InfoDir, NULL, 0);
+		std::sort(List.begin(), List.end());
+		std::sort(SList.begin(), SList.end());
+		std::sort(SigList.begin(), SigList.end());
+		std::sort(TransList.begin(), TransList.end());
+		return result;
+	}
+
+	bool DropRepeats(std::vector<std::string> &List, char const *Name) {
+		return pkgCdrom::DropRepeats(List, Name);
+	}
+};
+
+int main(int argc, char const *argv[]) {
+	if (argc != 2) {
+		std::cout << "One parameter expected - given " << argc << std::endl;
+		return 100;
+	}
+
+	Cdrom cd;
+	std::vector<std::string> Packages, Sources, Signatur, Translation;
+	std::string InfoDir;
+	std::string path = argv[1];
+	equals(true, cd.FindPackages(path, Packages, Sources, Signatur, Translation, InfoDir));
+	equals(4, Packages.size());
+	equals(path + "/dists/sid/main/binary-i386/", Packages[0]);
+	equals(path + "/dists/stable/contrib/binary-amd64/", Packages[1]);
+	equals(path + "/dists/stable/main/binary-i386/", Packages[2]);
+	equals(path + "/dists/unstable/main/binary-i386/", Packages[3]);
+	equals(3, Sources.size());
+	equals(path + "/dists/sid/main/source/", Sources[0]);
+	equals(path + "/dists/stable/main/source/", Sources[1]);
+	equals(path + "/dists/unstable/main/source/", Sources[2]);
+	equals(3, Signatur.size());
+	equals(path + "/dists/sid/", Signatur[0]);
+	equals(path + "/dists/stable/", Signatur[1]);
+	equals(path + "/dists/unstable/", Signatur[2]);
+	equals(4, Translation.size());
+	equals(path + "/dists/sid/main/i18n/Translation-de", Translation[0]);
+	equals(path + "/dists/sid/main/i18n/Translation-en", Translation[1]);
+	equals(path + "/dists/unstable/main/i18n/Translation-de", Translation[2]);
+	equals(path + "/dists/unstable/main/i18n/Translation-en", Translation[3]);
+	equals(path + "/.disk/", InfoDir);
+
+	cd.DropRepeats(Packages, "Packages");
+	cd.DropRepeats(Sources, "Sources");
+	_error->PushToStack();
+	cd.DropRepeats(Signatur, "InRelease");
+	cd.DropRepeats(Signatur, "Release.gpg");
+	_error->RevertToStack();
+	_error->DumpErrors();
+	cd.DropRepeats(Translation, "");
+
+	equals(3, Packages.size());
+	equals(path + "/dists/stable/contrib/binary-amd64/", Packages[0]);
+	equals(path + "/dists/stable/main/binary-i386/", Packages[1]);
+	equals(path + "/dists/unstable/main/binary-i386/", Packages[2]);
+	equals(2, Sources.size());
+	equals(path + "/dists/stable/main/source/", Sources[0]);
+	equals(path + "/dists/unstable/main/source/", Sources[1]);
+	equals(2, Signatur.size());
+	equals(path + "/dists/stable/", Signatur[0]);
+	equals(path + "/dists/unstable/", Signatur[1]);
+	equals(2, Translation.size());
+	equals(path + "/dists/unstable/main/i18n/Translation-de", Translation[0]);
+	equals(path + "/dists/unstable/main/i18n/Translation-en", Translation[1]);
+
+	return 0;
+}

+ 6 - 0
test/libapt/makefile

@@ -74,3 +74,9 @@ PROGRAM = Configuration${BASENAME}
 SLIBS = -lapt-pkg
 SLIBS = -lapt-pkg
 SOURCE = configuration_test.cc
 SOURCE = configuration_test.cc
 include $(PROGRAM_H)
 include $(PROGRAM_H)
+
+# test cdroms core FindPackages
+PROGRAM = CdromFindPackages${BASENAME}
+SLIBS = -lapt-pkg
+SOURCE = cdromfindpackages_test.cc
+include $(PROGRAM_H)

+ 29 - 0
test/libapt/run-tests

@@ -75,6 +75,35 @@ do
 		continue
 		continue
 	elif [ $name = "CompareVersion${EXT}" ]; then
 	elif [ $name = "CompareVersion${EXT}" ]; then
 		tmppath="${DIR}/versions.lst"
 		tmppath="${DIR}/versions.lst"
+	elif [ $name = "CdromFindPackages${EXT}" ]; then
+		tmppath=$(mktemp -d)
+		mkdir -p "${tmppath}/.disk" "${tmppath}/pool" \
+			"${tmppath}/dists/stable/main/binary-i386" \
+			"${tmppath}/dists/stable/main/source" \
+			"${tmppath}/dists/stable/contrib/binary-amd64" \
+			"${tmppath}/dists/stable/contrib/binary-all" \
+			"${tmppath}/dists/unstable/main/binary-i386" \
+			"${tmppath}/dists/unstable/main/i18n" \
+			"${tmppath}/dists/unstable/main/source" \
+			"${tmppath}/dists/broken/non-free/source"
+		touch "${tmppath}/dists/broken/.aptignr" \
+			"${tmppath}/dists/stable/main/binary-i386/Packages" \
+			"${tmppath}/dists/stable/main/binary-i386/Packages.bz2" \
+			"${tmppath}/dists/stable/main/source/Sources.xz" \
+			"${tmppath}/dists/stable/contrib/binary-amd64/Packages" \
+			"${tmppath}/dists/stable/contrib/binary-amd64/Packages.gz" \
+			"${tmppath}/dists/stable/contrib/binary-all/Packages" \
+			"${tmppath}/dists/unstable/main/binary-i386/Packages.xz" \
+			"${tmppath}/dists/unstable/main/binary-i386/Packages.lzma" \
+			"${tmppath}/dists/unstable/main/i18n/Translation-en" \
+			"${tmppath}/dists/unstable/main/i18n/Translation-de.bz2" \
+			"${tmppath}/dists/unstable/main/source/Sources.xz" \
+			"${tmppath}/dists/broken/non-free/source/Sources.gz" \
+			"${tmppath}/dists/stable/Release.gpg" \
+			"${tmppath}/dists/stable/Release" \
+			"${tmppath}/dists/unstable/InRelease" \
+			"${tmppath}/dists/broken/Release.gpg"
+		ln -s "${tmppath}/dists/unstable" "${tmppath}/dists/sid"
 	fi
 	fi
 
 
 	echo -n "Testing with ${NAME} "
 	echo -n "Testing with ${NAME} "